GameMaker:Studio Shader 表示色の反転

 shader   invert   GLSL_ES 

GM:S の Pass-Through Shader を元に、簡単な改造を施したもの

表示色を反転する効果。

GameMaker_Studio_1.4_Shader_-_color_invert_effect_-_sample_Screenshot.png

サンプルとしては簡潔すぎたので、画面サイズの半分だけを対象に色を反転させた( オブジェクト・インスタンスの半分を常に反転色とする処理ではない )

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

    1. Create
    2. Step
    3. Draw

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

イベントもシンプルだったので今回はユーザ定義関数化はしない。

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

キーボードの A と S と D と W キーでインスタンスの位置を変更。

色反転の効果が適用される範囲は、スクリーン座標でちょうど半分だけを対象にしてあります。

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

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

シェーダー名:SH_InvertColour

Vertex Shader

attribute vec3 in_Position;                  // (x,y,z)
attribute vec2 in_TextureCoord;              // (u,v)
// 今回、あえて頂点カラーは無視しています、必要な場合は追加してください
varying float v_vPosition;
varying vec2  v_vTexcoord;

void main()
{
    vec4 pos    = vec4( in_Position.xyz, 1.0);
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * pos;
    v_vPosition = in_Position.x;
    v_vTexcoord = in_TextureCoord;
}
コメントでも記述がありますが、頂点カラーを無視しています。汎用性考えれば無視するべきではなく、必要無いから今回は抜いただけです。 コピペして使う場合は、
attribute vec4 in_Colour;                    // (r,g,b,a)

varying vec4 v_vColour;

上記2つに加えて、スタートアップである main 関数内で varying 変数へ値を渡してください。

v_vColour = in_Colour;

逆に今回あえて付け加えた varying 変数

varying float v_vPosition;

この変数は不要な場合削除できます。

in_Position は座標を得るための attribute で、テクスチャ全面にシェーダ効果を与える場合はあえて varying でフラグメントへ値を提供する手間は不要。

Fragment Shader

varying float v_vPosition;
varying vec2  v_vTexcoord;

const float center = 256.0;// Screen width(512 pixel) / 2.0;

void main()
{
vec4 colour = texture2D( gm_BaseTexture , v_vTexcoord );

    if (v_vPosition < center) {
        colour = vec4( 1.0 - colour.rgb , colour.a );
    }

gl_FragColor = colour;
}

const float center = 256.0;

この定数は画面サイズを半分にした値を代入しています。

今回 room のサイズは横 512 px なので、この半分は 256.0 となります。大した処理ではないためハードコードしました。これが X の中心座標と成ります。

GameMaker Studio 1.4 Room settings screenshot

中心座標を基準に処理を左右分割、画面左半分はインスタンスの色を反転させ、画面右半分は通常の色を表示します。

注意点、インスタンス座標は基準にせず、スクリーンサイズを半分にした値を中心座標としてる点。

オブジェクト・インスタンスの半分を常に反転色とする処理ではない。

オブジェクト・インスタンスのもつスプライト全体を反転処理させたい場合、

    //if (v_vPosition < center) {
        colour = vec4( 1.0 - colour.rgb , colour.a );
    //}
上記のように if 条件を削除して使ってください。

ユーザ定義関数

今回は無し

イベント処理

簡潔なイベントを作成、オブジェクトの外観として設定されたスプライトを描画するだけの処理。

Step イベントも本来は不要。

Create Event

draw_set_font(font0);
var a = SH_InvertColour;

if !shader_is_compiled(a){
     show_message("Ur hardware ain't support shader - SH_InvertColour");
};

Step Event

var a = 3.333;
if keyboard_check(ord("A")) x -= a;
if keyboard_check(ord("D")) x += a;
if keyboard_check(ord("S")) y += a;
if keyboard_check(ord("W")) y -= a;

Draw Event

var a,b
a = c_aqua;
b = "press ASDW keys, can move direrction"
draw_set_colour(a);
draw_text(0,30, b);

shader_set(SH_InvertColour);
draw_self();
shader_reset();

Pass-Through Shader に少し手を加えた程度だが、Shader 無しの場合は GM:S の標準機能から image_blend を使った色反転処理が可能だと思う。

しかし Shader の場合は領域を指定して部分的に色を反転することなどが容易、これだと応用の幅も広くなるし処理速度自体も image_blend より速い( はず )




次へ

前へ