Color Lerp(線形補間)/マスク
YoYoGames 公式で配布されていたシェーダデモのサンプルを改造したもの( rev.2 )
色の合成効果。キャラクタを明滅させる、イベントに応じた色変化など
スプライトに対して利用した場合、キャラクタの形状で切り抜かれたように「指定された色」で領域が塗りつぶされる。透過率の変化に応じてスプライトが点滅して見える仕組み。
イベントを二つのオブジェクトへまとめ、
上記二つのイベントへ収まるように作った。無駄な変数定義を排除、処理をユーザ定義関数化しコードの使い回し簡単。
( 参考:Demosタブ → YoYo Demos → Advanced → Simple_Shader_Examples )
キーボードの Q と A キーで値変更可。
スペースキーでシェーダ切り替え ON・OFF
スライダー調整で描画色の変更が可能
LerpTime の値は 0.0 〜 180.0 までの範囲で制限。
要 WebGL、Google Chrome/FireFox 等で動作を確認。
HTML5( WebGL ) と Windows PC で描画結果が異なる場合があります。
今回のサンプルではオブジェクトを二つ使っています。一つはスライダーで RGB 色を調整するためのもの。シェーダー名:SH_LerpColor
Vertex Shader
attribute vec3 in_Position; // (x,y,z)
attribute vec2 in_TextureCoord; // (u,v)
// 今回、頂点カラーは無視しています、必要な場合は追加
varying vec2 v_vTexcoord;
void main()
{
gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * vec4(in_Position, 1.0);
v_vTexcoord = in_TextureCoord;
}
Fragment Shader
varying vec2 v_vTexcoord;
uniform vec4 u_Colour; // u_Colour.rgba
const float tone = 255.0;
void main()
{
vec4 col = texture2D(gm_BaseTexture, v_vTexcoord);
gl_FragColor = vec4(mix(col.rgb, u_Colour.rgb / tone, u_Colour.a), col.a);
}
ユーザ定義関数 Init_Shader_LerpColor
///Init_Shader_LerpColor();
draw_set_font(font0);
draw_set_colour(c_white);
var a,b;
a = SH_LerpColor;
if !shader_is_compiled(a) {
b = "ur hardware ain't support shader - SH_LerpColor";
show_message(b);
}
else{
b = "u_Colour";
/* instance variabels for Uniform */
U_Colour = shader_get_uniform(a, b);
LerpTime = .0;
Uni_R = .0; // color tone levels for "ReD"
Uni_G = .0; // color tone levels for "GreeN"
Uni_B = .0; // color tone levels for "BluE"
/* Instance Variables for Debug */
VMax = 180.0;// maximum ( degree value )
LerpAmount = 20.0;// 0 == slow : 20 == fast
VMin = .0;// minimum
Shader = true;
Slider = false;
SliderID = noone;
};
ユーザ定義関数 Draw_LerpColor
///Draw_LerpColor();
var a,b,c,d,e, f;
a = SH_LerpColor;
b = LerpTime;
c = LerpAmount;
d = VMax;// 180.
e = VMin;// .0
var R,G,B;// 3 Primary colors tone levels vec3(255,255,255)
R = Uni_R;
G = Uni_G;
B = Uni_B;
if Shader {
b += c;
if (b > d) b = e;
/* Shader draw start */
shader_set(a);
// NOTE: SIN() will give 1 o -1. The -1 will make the image seem "darker"
f = sin( degtorad(b) );
shader_set_uniform_f(U_Colour, R,G,B, f);// lerp to WHITE (1,1,1)
draw_sprite(rb, image_index, x, y);
shader_reset();
/* Finalize */
LerpTime = b;
}
else{
draw_sprite(rb, image_index, x, y);
};
ユーザ定義関数 Draw_ShowStatus
///Draw_ShowStatus();
var a,b,c,d,e,f;
a = LerpAmount;
b = 1.0;
c = Shader;
d = LerpTime;
e = fps_real;
f = room_height;
/* Check Keys */
if keyboard_check(ord("R")) room_restart();
if keyboard_check(ord("Q")) a += b;
if keyboard_check(ord("A")) a -= b;
if keyboard_check_pressed(vk_space) c = !c;
a = clamp(VMin , a , VMax);
/* Debug Status */
draw_text(0, 0, "SH_LerpColor");
draw_text(0, 40, "Real FPS = " + string(e) );
draw_text(0, 80, "LerpTime = " + string(d) );
draw_text(0, 120, "LerpAmount = " + string(a) );
draw_text(0,f-80, "Press Q & A Keys : Value UP || Down");
draw_text(0,f-40, "Press Spacekey, toggle Shader");
/* Finalize */
LerpAmount = a;
Shader = c;
ユーザ定義関数 Init_ColourButtons
///Init_ColourButtons();
var a,b,c,d, e;
a = 10;
b = ( (room_height >> 1) - 50 );
c = 40;
d = 3;
/* Create 3 instances */
for (var i=0; i<d; i++)
{
e = ( b + (c*i) );
with ( instance_create(a,e, button) )
{
image_index = i;// use spread value
image_speed = 0;// stop the Animation
switch (i)
{ // Create an instance Variable
case 2: Colour = "BluE"; break;
case 1: Colour = "GreeN"; break;
default: Colour = "ReD";
};
};
};
ユーザ定義関数 Draw_Slider_Function
///Draw_Slider_Function();
var a,b,c,d,e,f, g;
a = mb_any;
b = button; // Clickable Object Name
c = mouse_x;
d = mouse_y;
e = Slider; // instance varibale with robo.
f = SliderID; // instance varibale with robo.
/* Check mouse Events */
if ( e & mouse_check_button_released(a) ) { e = false; f = noone; };
if ( !e & mouse_check_button_pressed(a) ) { e = true; f = collision_point(c,d,b,-1,1); };
if e {
if f {
f.x = c;
g = f.xstart + 255;
if c < f.xstart f.x = f.xstart;
else if c > g f.x = g;
}
else e = false;
};
/* Draw Status */
var h,j,l,m,n,o,p;
with (button)
{
h = xstart;
j = floor(x - h);
l = y + 16;
m = h + 255;
n = c_gray;
o = room_width - 100;
draw_line_colour(x,l,m,l,n,n);
draw_text(o, y, string(j) );
draw_self();
p = Colour;
switch (p)
{
case "BluE": robo.Uni_B = j; break;
case "GreeN": robo.Uni_G = j; break;
default: robo.Uni_R = j;
};
};
/* finalize */
Slider = e;
SliderID = f;
イベント処理
シェーダと5つのユーザ定義関数を使って簡潔なイベントを作成。
Create Event
///Init
Init_Shader_LerpColor();
Init_ColourButtons();
Draw Event
///Draw
Draw_Slider_Function();
Draw_LerpColor();
Draw_ShowStatus();
スライダーで色を動的に変えることができる。
Draw_Slider_Function ユーザ定義関数はデバッグなど汎用的利用が可能。
今回のシェーダ効果は当たり判定と組み合わせて、衝突した際にキャラクタースプライトを点滅させたり、特定インスタンスを塗りつぶしたり。
シェーダ使わない GM:Studio 標準機能で同じことができるかは不明だが、シェーダなら悩まず簡単に実装できる。
次へ
前へ