GameMaker:Studio Shader Transition Straight Wipe 改

 shader   transition   GLSL_ES 

自作した初歩的なトランジション用のシェーダの改良版

二つの画像をワイプで交互に切り替えする。直線的な動き。画像の切り替える領域ににフェード効果を適用した。視覚的にはスムーズに切り替えが行われているように見える。

イベントを一つのオブジェクトへまとめるようにし、

    1. Create
    2. Draw
    3. DrawGUI

上記の三つのイベントへ収まるように作った。そして無駄な変数定義を全て排除。

なるべくユーザ定義関数化し、コードの使い回しが簡単。

参考動作:http://prester.org/html5/gms_shader_Tr_StraightWipe_LR_Rev2/

Wipe 時のチラツキについて

Windows PC では GGS (グローバルゲームセッティング) から Wipe 時の画面チラツキを抑える設定が可能

HTML5 では GGS 設定に頼ることができないためチラツキを抑えることが現状ではできない

要 WebGL、Google Chrome/FireFox 等で動作を確認。

HTML5( WebGL ) と Windows PC で微妙に描画結果が異なる場合があります

Global Game Settings for Window PC

シェーダー名:SH_Tr_StraightWipe_LR_Rev2

Vertex Shader

attribute vec3 in_Position;       // (x,y,z)
attribute vec4 in_Colour;         // (r,g,b,a)
attribute vec2 in_TextureCoord;   // (u,v)

varying vec2 v_vPosition;
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

void main()
{
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position, 1.0);
    
    v_vPosition = in_Position.xy;// x,y is a screen space coordinate.
    v_vColour   = in_Colour;
    v_vTexcoord = in_TextureCoord;
}

Fragment Shader

varying vec2 v_vPosition;
varying vec2 v_vTexcoord;
varying vec4 v_vColour;

uniform float v_MaskParams;
const float  offset = 50.0;

void main()
{
        if ( v_vPosition.x > v_MaskParams ){
            discard;// throw pixel away if it's out of range
        }
        else{
            vec4 ok      = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
            float nposx  = min(abs(v_MaskParams - v_vPosition.x), offset);
            float alp    = clamp(ok.a-(ok.a - (nposx / offset)), 0.0, ok.a);
            gl_FragColor = vec4(ok.rgb, alp);
        }
}

ユーザ定義関数 Init_Shader_Tr_StraightWipe_LR

///Init_Shader_transition_circle();
/*
Wipe 時のチラツキについて

Windows では GGS の設定を行えば Wipe 時の画面のチラツキを抑えることができる

HTML5 では GGS 設定に頼ることができないためチラツキを抑えることが現状ではできない
*/
    if (!shader_is_compiled(SH_Tr_StraightWipe_LR_Rev2)) {
        show_message("Your hardware doesn't support shader - SH_Tr_StraightWipe_LR_Rev2");
    }
    else{
        v_mask  = shader_get_uniform(SH_Tr_StraightWipe_LR_Rev2, "v_MaskParams");
        SSize   = 0.0;
        WipeDir = true;
    };

ユーザ定義関数 Show_Status

///Show_Status();
draw_set_colour(c_green);
draw_text(10,10,"SH_Tr_StraightWipe_LR_Rev2");

if keyboard_check_pressed(ord("R")) room_restart();

ユーザ定義関数 DrawEv_Tr_StraightWipe_LR

///DrawEv_transition_square();
draw_self();

var a,b,c,d;
a = SSize;
c = room_width;
d = room_height;

shader_set(SH_Tr_StraightWipe_LR_Rev2);
shader_set_uniform_f(v_mask, a );
draw_background_stretched(background0, 0, 0, c, d);
draw_set_colour(c_red);
draw_text(40,140,"Hello Hello Hello World!");
shader_reset();

b = 10.0;
    if (a < 0 or a > c) WipeDir = !WipeDir;
 
    switch (WipeDir){
        case false: a += b; break;
        default:    a -= b;
    };

SSize = a;

実際のイベント処理

シェーダと3つのユーザ定義関数を使って簡潔なイベントを作成。

Create Event

draw_set_font(font0);

Init_Shader_Tr_StraightWipe_LR();

Draw Event

Show_Status();

DrawEv_Tr_StraightWipe_LR();

Draw GUI Event

draw_set_colour(c_blue);
draw_text(10,room_width-100,"SSize =  "+string_format(SSize,1,5));

Object Instance の Draw イベントでシェーダを使ってエフェクトをかけます。

application_surface 上で描画された内容を、リソースツリー上へ登録された「背景( 一枚絵 ) 」と交互に切り替えて表示します。

ユーザ定義関数である DrawEv_Tr_StraightWipe_LR でシェーダ処理を行っている。

この処理では左右にしかワイプしないが、値を少し変えれば上下へのワイプへ簡単に改造可能。




次へ

前へ