GameMaker:Studio Shader Transition(円)改善版
配布されていたシェーダサンプルを独自に作り直したもの。
円を描くロジックを見直し、フラグメントでは組み込み関数の distance を使って簡潔に記述。オリジナルの方法だと円にジャギー( 階段状のギザギザ ) が発生するため、これを軽減するためのアンチエイリアス的処理追加。
イベントを一つのオブジェクトへまとめるようにし、
- Create
- Draw
- DrawGUI
上記の三つのイベントへ収まるように作った。そして無駄な変数定義を全て排除。
なるべくユーザ定義関数化し、コードの使い回しが簡単。
参考動作:http://prester.org/html5/13_shader_circle_transition_Rev2/
要 WebGL、Google Chrome/FireFox 等で動作を確認。
HTML5( WebGL ) と Windows PC で微妙に描画結果が異なる場合があります。
HTML5( WebGL ) と Windows PC で微妙に描画結果が異なる場合があります。
シェーダー名:SH_transition_circle_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 vec3 v_MaskParams;// x,y=position, z=radius,
const float offset = 1.0;//強いアンチエイリアスをかける場合は 2.0 以上にする
void main()
{
float dist = distance(v_vPosition.xy , v_MaskParams.xy);
if ( dist > v_MaskParams.z ){
float opt = dist - v_MaskParams.z;
if (opt < offset ){
//opt = v_vColour.a - (opt / offset);//強いアンチエイリアス == Offset値を2.0以上にする
opt = v_vColour.a - opt;//通常はこれで十分綺麗な円に見える
gl_FragColor = vec4(v_vColour.rgb, opt) * texture2D( gm_BaseTexture, v_vTexcoord );
}
else{
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_Rev2)) {
show_message("Your hardware doesn't support shader - SH_transition_circle_Rev2");
}
else{
v_mask = shader_get_uniform(SH_transition_circle_Rev2, "v_MaskParams");
Length = 0.0;
Time = 2.0;
};
ユーザ定義関数 DrawEv_transition_circle
///DrawEv_transition_circle();
draw_self();
var a,b,c,d,e;
a = Length;// Circle
b = mouse_x;//Screen Center position X
c = mouse_y;//Screen Center position Y
d = room_width;
e = room_height;
shader_set(SH_transition_circle_Rev2);
shader_set_uniform_f(v_mask, b, c, a);
draw_background_stretched(background0, 0, 0, d, e);
draw_set_colour(c_red);
draw_text(40,140,"Hello Hello Hello World!");
shader_reset();
if ( a < 0 or a > d ) Time *= -1;
Length += Time;
ユーザ定義関数 DrawGUI_Show_Status
///DrawGUI_Show_Status();
draw_set_colour(c_green);
draw_text(10,10,"Shader SH_transition_circle_Rev2");
draw_set_colour(c_blue);
draw_text(10,room_width-100,"length = "+string_format(Length,1,5));
実際のイベント処理
シェーダと4つのユーザ定義関数を使って簡潔なイベントを作成。
Create Event
draw_set_font(font0);
Init_Shader_transition_circle_Rev2();
Draw Event
DrawEv_transition_circle();
Draw GUI Event
DrawGUI_Show_Status();
application_surface を対象としてシェーダでエフェクトをかけます。
ユーザ定義関数である DrawEv_transition_circle(); でシェーダ処理を行っている。
次へ
前へ