GameMaker:Studio Shader Transition(円)

 shader   transition   GLSL_ES 

配布されていたシェーダのサンプルを整理したもの。

トランジション効果をシェーダで実現したもの。サンプルではオブジェクトの外観として設定されたスプライトと、背景としてリソースツリーに追加された背景用リソース「background0」、二つの画像を自動で切り替えする処理が実装されている。

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

    1. Create
    2. Draw
    3. DrawGUI

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

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

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

( 参考:Demosタブ → YoYo Demos → Advanced → Simple_Shader_Examples )

Simple Shader Samples

値表示のみ

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

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

シェーダー名:SH_transition_circle

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 vec3 v_MaskParams;// x,y=position, z=radius, 

void main()
{
    vec2  v     = v_MaskParams.xy - v_vPosition.xy;
    float size  = 0.8;// 0.0 ~ x.x
    float dist  = ((v.x * v.x) + (v.y * v.y)) * size;
    float RadSq = (v_MaskParams.z * v_MaskParams.z);
        if ( dist > RadSq ){
            discard;  // throw pixel away if it's out of range
        }
        else{
            gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
        }
}

ユーザ定義関数 Init_Shader_transition_circle

///Init_Shader_transition_circle();

    if (!shader_is_compiled(SH_transition_circle)) {
        show_message("Your hardware doesn't support shader - SH_transition_circle");
    }
    else{
        v_mask = shader_get_uniform(SH_transition_circle, "v_MaskParams");
        Angle  = 270;
    };

ユーザ定義関数 Show_Status

///Show_Status();
draw_set_colour(c_green);
draw_text(10,10,"Shader SH_transition_circle");

ユーザ定義関数 DrawEv_transition_circle

///DrawEv_transition_circle();
draw_self();

var a,b,c,d;
a = Angle;
b = ((sin(degtorad(a))+1.0)/2.0);;
c = room_width;
d = room_height;

shader_set(SH_transition_circle);
shader_set_uniform_f(v_mask, c>>1, d>>1, (c/1.5) * b );
draw_background_stretched(background0, 0, 0, c, d);
draw_set_colour(c_red);
draw_text(40,140,"Hello Hello Hello World!");
shader_reset();

a += 2;
    if( a > 360 ) Angle -=360;
    else Angle = a;

実際のイベント処理

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

Create Event

draw_set_font(font0);

Init_Shader_transition_circle();

Draw Event

Show_Status();

DrawEv_transition_circle();

Draw GUI Event

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

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

ユーザ定義関数である DrawEv_transition_circle でシェーダ処理を行っている。アクションの実行されるタイミングなどを色々変えて描画結果の違いを試すと良い。




次へ

前へ