Transition Circle(円)rev.2

 transition   circle   distance   discard   safari 

{{< twitter >}}

配布されていたシェーダサンプルを独自に作り直したもの

円を描くロジックを見直し、フラグメントで GLSL ES 組み込み関数の distance を使ってコード記述を簡潔化。円の見た目に発生するジャギー( 階段状のギザギザ ) を軽減するため、アンチエイリアス的処理を追加。

左:滑らかなカーブ、右:ジャギーが見える

イベントを一つのオブジェクトへまとめ、

上記三つのイベントへ収まるように作った。無駄な変数定義を排除、処理をユーザ定義関数化しコードの使い回し簡単。

    参考( prester.org ) Shader_transition_circle

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

    YoYoGames Simple Shader Samples

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

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

シェーダー名:SH_transition_circle_Rev2

参考動作:Shade Transition Circle rev.2

OpenGL-ES_50px_May16 WebGL_50px_June16

( MacBook Pro OS X El Capitan + Safari 11601.7.7 で正常に動作せず )

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;
    v_vColour   = in_Colour;
    v_vTexcoord = in_TextureCoord;
}
 

Fragment Shader

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

uniform vec3 u_Param;    // x,y = position, z = radius
const float offset = 1.0;// 強いアンチエイリアスをかける場合は値 2.0 以上

void main()
{
    float dist  = distance(v_vPosition.xy , u_Param.xy);
        if ( dist > u_Param.z ){
           float opt = dist - u_Param.z;
                if (opt < offset ){
                    //opt        = v_vColour.a - (opt / offset);//strong anti-aliasing → set 'offset' over 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();
draw_set_font(font0);
var a,b;
a = SH_transition_circle_Rev2;
    if !shader_is_compiled(a) {
        b = "ur hardware ain't support shader - SH_transition_circle_Rev2";
        show_message( b );
    }
    else{
        b         = "u_Param"; 
        Uni_param = shader_get_uniform( a , b );
        Length    = 0.0;
        Time      = 2.0;
    };
 

ユーザ定義関数 Draw_transition_circle

///Draw_transition_circle();
draw_self();

var a,b,c;
a = Length;    // Circle size
b = mouse_x;   // Screen Center position X
c = mouse_y;   // Screen Center position Y

shader_set(SH_transition_circle_Rev2);
shader_set_uniform_f(Uni_param, b, c, a);
draw_background(background0, 0, 0);
draw_set_colour(c_red);
draw_text(40,140, "Hello Hello Hello World!");
shader_reset();

    if ( a < 0 or a > room_width ) 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) );
 

イベント処理

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

Create Event

///Init
Init_Shader_transition_circle_Rev2();

Draw Event

///Draw
Draw_transition_circle();

Draw GUI Event

///DrawGUI
DrawGUI_Show_Status();

application_surface を対象としてシェーダでエフェクトをかけます。

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




次へ

前へ