波紋状モザイク(Waving Mosaic)

 transition   effect   wave   mosaic   safari 

{{< twitter >}}

画面切り替え用エフェクト、波紋状モザイク

Waving Mosaic ScreenShot

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

    1. ( 暗黙の Draw として利用 )

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

モザイク処理から派生して作られたシェーダ効果

値変更不可。

スペースキー押しでシェーダの利用を停止/開始、切り替え

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

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

シェーダー名:SH_Transition_WavingMosaic

参考動作:Shader-Transition-Waving Mosaic

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)
// 今回、頂点カラーは無視しています、必要な場合は追加
varying vec2 FragCoord;

void main()
{
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position, 1.0);
    FragCoord   = in_Position.xy;
}
 

Fragment Shader

 
precision mediump float;

varying vec2  FragCoord;

/* Uniform variables */
uniform float resolution_x;
uniform float resolution_y;
uniform float pixel_amount;

float aspect = resolution_x / resolution_y;

/* User-Defined Function */
vec2 Effect(vec2 EA , float EB){
    vec2 EC = sin(EA/EB);
    return (EA + mix( EC.x , EC.y , EB)) / resolution_x;
}

/* MAIN */
void main(){
    vec2  fc     = vec2(FragCoord.x, FragCoord.y * aspect);
    gl_FragColor = texture2D(gm_BaseTexture, Effect(fc, pixel_amount));
}
 

ユーザ定義関数 Init_Shader_WavingMosaic

///Init_Shader_WavingMosaic();
draw_set_font(font0);
var a, b,c,d;
a = SH_Transion_WavingMosaic;
    if !shader_is_compiled(a) {
        b = "ur hardware ain't support shader - SH_Transion_WavingMosaic";
        show_message(b);
    }
    else{
        /* Instance variables for Uniform  */
        b = "resolution_x";
        c = "resolution_y";
        d = "pixel_amount";
        U_ResX        = shader_get_uniform(a, b);
        V_ResX        = display_get_gui_width() *1.0;
        U_ResY        = shader_get_uniform(a, c);
        V_ResY        = display_get_gui_height()*1.0;
        U_PixelAmount = shader_get_uniform(a, d);
        V_PixelAmount = 10.0;
        MaxAmount     = V_PixelAmount;
        AddValue      = 0.1;

        /* Instance Variable for draw_sprite */
        Robot_ImageIndex = 0;
        
        /* For Debug */
        Debug = false;
    };
 

ユーザ定義関数 DrawGUI_WavingMosaic

///DrawGUI_WavingMosaic();
if !Debug 
{
    var a,b,c,d;
    a = SH_Transion_WavingMosaic;
    b = V_PixelAmount;
    c = AddValue;
    d = abs(c);
    /* calculation for the turn */
    b += c;
        if (b > MaxAmount) {
            AddValue = -d;
            b        = MaxAmount;
        }
        else if (b < d) {
            AddValue =  d;
            b        =  d;
        };
    /* shader draw */
    shader_set(a);
    {
    shader_set_uniform_f(U_ResX,        V_ResX);
    shader_set_uniform_f(U_ResY,        V_ResY);
    shader_set_uniform_f(U_PixelAmount, b);
    draw_surface(application_surface, 0,0); 
    };
    shader_reset();
    /* value finalize */
    V_PixelAmount = b;
};

DrawGUI_WalkingRobo();
Debug_ShowStatus();
 

ユーザ定義関数 DrawGUI_WalkingRobo

///DrawGUI_WalkingRobo();
var a,b,c,d;
a = sprite_get_number(rb);
b = Robot_ImageIndex;
b++;
   if (b > a) b = 0;
c = room_width  >> 1;
d = room_height >> 1;
draw_sprite(rb,b,c,d);
/* finalize */
Robot_ImageIndex = b;
 

ユーザ定義関数 Debug_ShowStatus

///Debug_ShowStatus();
if keyboard_check_pressed(ord("R")) room_restart();
if keyboard_check_pressed(vk_space) Debug = !Debug;

var a,b;
a = 0;
b = string(fps_real);

draw_set_colour(c_red);
draw_text(a,0,"Real FPS: " + b);
 

イベント処理

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

Create Event

///Init
Init_Shader_WavingMosaic();

DrawGUI Event

///DrawGUI
DrawGUI_WavingMosaic();

効果としては wave と似ているが、作り方がだいぶ異なる。




次へ

前へ