GameMaker:Studio Shader LED電光掲示板

 shader   LED   GLSL_ES 

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

LED ( 電光掲示板 ) 風の画像効果を得る

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

    1. Create
    2. Draw
    3. DrawGUI

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

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

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

参考(YoYoGames MarketPlace):xygthop3’s Shader Resources

キーボードの Q と A と W と S キーで値を変更可能。

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

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

シェーダー名:SH_LED

Vertex Shader

attribute vec3 in_Position;
attribute vec2 in_TextureCoord;

varying vec2   v_texcoord;

void main()
{
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position, 1.0);
    v_texcoord  = in_TextureCoord;
}

Fragment Shader

varying vec2  v_texcoord;

uniform vec2  resolution;
uniform float led_size;
uniform float brightness;  

const float pai = 3.1415;
const float mul = 1.5;

vec4 pixelize(vec2 uv, float sca) {
    float dx   = 1.0 / sca;
    float dy   = 1.0 / sca;
    vec2 coord = vec2(dx * ceil(uv.x / dx), dy * ceil(uv.y / dy));
    return texture2D(gm_BaseTexture, coord);
}

void main()
{
        vec2 uv         = v_texcoord;
        vec2 coor       = uv * led_size;
        coor.x         *= (resolution.x / resolution.y);
        vec4 resColor   = pixelize(uv, led_size) * brightness;
        float mvx       = abs(sin(coor.x * pai)) * mul;
        float mvy       = abs(sin(coor.y * pai)) * mul;
        
            if ( (mvx * mvy) < 1.0) {
               resColor = vec4(0.0, 0.0, 0.0, texture2D(gm_BaseTexture, v_texcoord).a);
            }
            else {
               resColor = resColor * (mvx * mvy);
            }
        gl_FragColor    = resColor; 
}

ユーザ定義関数 Init_Shader_LED

///Init_Shader_LED();

    if (!shader_is_compiled(SH_LED)) {
        show_message("Your hardware doesn't support shader - SH_LED");
    }
    else{
        uni_resolution     = shader_get_uniform(SH_LED, "resolution");
        var_resolution_x   = room_width; //or "view_wview";
        var_resolution_y   = room_height;//or "view_hview";
        
        uni_led_size       = shader_get_uniform(SH_LED, "led_size");
        var_led_size       = 80;
        
        uni_led_brightness = shader_get_uniform(SH_LED, "brightness");
        var_led_brightness = 1.0;
    };

ユーザ定義関数 DrawGUIEv_LED

///DrawGUIEv_LED();
if Shader_Enabled {
    shader_set(SH_LED);
    shader_set_uniform_f(uni_resolution,     var_resolution_x, var_resolution_y);
    shader_set_uniform_f(uni_led_size,       var_led_size);
    shader_set_uniform_f(uni_led_brightness, var_led_brightness);
    draw_surface(application_surface, 0,0);
    shader_reset();
};

ユーザ定義関数 Debug_Keys

///Debug_Keys();
var a,b,c,d,e;
a = var_led_size;
b = var_led_brightness;
c = 1;
d = 0.01;
e = 0.5;

if keyboard_check(ord('Q')) a += c;
if keyboard_check(ord('A')) a -= c;

if keyboard_check(ord('W')) b += d;
if (keyboard_check(ord('S')) and (b > e)) b -= d;

if keyboard_check_pressed(vk_space) Shader_Enabled = !Shader_Enabled;

var_led_size       = a;
var_led_brightness = b;

/* Show Information */
//fake Drop shadow TEXT
draw_set_color(c_black);
draw_text(0,2,  "Real FPS: "+string(fps_real));
draw_text(0,42, "LED size (Q & A to adjust): "+string(var_led_size));
draw_text(0,82, "LED Brightness (W & S to adjust): "+string(var_led_brightness));

draw_text(0,482,"Spacebar to toggle shader");

draw_set_color(c_white);
draw_text(0,0,  "Real FPS: "+string(fps_real));
draw_text(0,40, "LED size (Q & A to adjust): "+string(var_led_size));
draw_text(0,80, "LED Brightness (W & S to adjust): "+string(var_led_brightness));

draw_text(0,480,"Spacebar to toggle shader");

実際のイベント処理

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

Create Event

draw_set_font(font0);
draw_set_colour(c_white);

Init_Shader_LED();

/* Instance Variables for Debug */
Shader_Enabled   = true;

Draw Event

draw_background_stretched(background0,0,0,room_width,room_height);
draw_self();

Draw GUI Event

DrawGUIEv_LED();
Debug_Keys();

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

Draw イベントで描画した画面を DrawGUI へ描画するという手順。シェーダで application_surface 全体を対象にする場合は DrawGUI のタイミングで描画するのが無難。

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




次へ

前へ