Shader
シェーダーとは
シェーダーはもともと3D描画時に、リアルな表現をするために陰影をつける仕組みです。 なので、2Dゲーム専用ライブラリであるHaxeFlixelには関係なさそうな機能ですが、ピクセルシェーダーと呼ばれる2次元のピクセルの並びに対する高速な画像処理(ポストエフェクト)が便利なので、それの使い方をここでは紹介します。
OpenFLでは、GLSL(OpenGL Shading Language)を使ってシェーダーを記述することができます。
注意点
OpenFLのシェーダはデスクトップ環境のみ実行可能です。FlashやiOS、Androidなどのモバイル環境では動作しません
走査線シェーダーを使う
テレビやモニターで発生する水平方向の線をシミュレートしたシェーダーです。
シェーダーのコード
以下のシェーダーのコードを、「scanline.frag」として任意のフォルダに保存します。
#ifdef GL_ES precision mediump float; #endif varying vec2 vTexCoord; uniform vec2 uResolution; uniform sampler2D uImage0; const float scale = 1.0; uniform float intensity; void main() { if (mod(floor(vTexCoord.y * uResolution.y / scale), 2.0) == 0.0) { vec4 scanline_mult = vec4(1.0-intensity, 1.0-intensity, 1.0-intensity, 1.0); gl_FragColor = texture2D(uImage0, vTexCoord) * scanline_mult; } else gl_FragColor = texture2D(uImage0, vTexCoord); }
シェーダーの読み込みと適用
「bg.png」はあらかじめ用意した背景画像です。
package; import flixel.FlxG; import flixel.FlxSprite; import flixel.FlxState; import flixel.effects.postprocess.PostProcess; class MenuState extends FlxState { var _scanlines:PostProcess; override public function create():Void { // 画像読み込み・配置 var spr = new FlxSprite(0, 0, AssetPaths.bg__png); this.add(spr); // シェーダーの読み込みと適用 (モバイルでは動作しない) #if !mobile _scanlines = new PostProcess(AssetPaths.scanline__frag); _scanlines.setUniform("intensity", 0.2); // "intensity"パラメータを設定 FlxG.addPostProcess(_scanlines); #end super.create(); } override public function update(elapsed:Float):Void { super.update(elapsed); if(FlxG.keys.justPressed.ENTER) { // シェーダー解除 #if !mobile FlxG.removePostProcess(_scanlines); #end } } }
実行すると、以下のように表示されます。
エラーの対処法
型があっていない
Shader.hx:55: ERROR: 0:16: '-' does not operate on 'int' and 'float'
OpenFLのシェーダーは、型チェックが厳しいため、上記のエラーの例では、整数値と浮動小数値を演算しようとしてエラーが発生しています。適切にキャストを行って型を合わせる必要があります。