Shader の変更点


[[FrontPage]]

* シェーダーとは [#f5740e33]
シェーダーはもともと3D描画時に、リアルな表現をするために陰影をつける仕組みです。
なので、2Dゲーム専用ライブラリであるHaxeFlixelには関係なさそうな機能ですが、ピクセルシェーダーと呼ばれる2次元のピクセルの並びに対する高速な画像処理(ポストエフェクト)が便利なので、それの使い方をここでは紹介します。

OpenFLでは、GLSL(OpenGL Shading Language)を使ってシェーダーを記述することができます。

** 注意点 [#ob2a269b]
OpenFLのシェーダはデスクトップ環境のみ実行可能です。FlashやiOS、Androidなどのモバイル環境では動作しません

** 走査線シェーダーを使う [#w67be64b]
テレビやモニターで発生する水平方向の線をシミュレートしたシェーダーです。

*** シェーダーのコード [#z4f1974f]
以下のシェーダーのコードを、「scanline.frag」として任意のフォルダに保存します。
#geshi(c){{
#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);
}
}}

*** シェーダーの読み込みと適用 [#f6f46199]
「bg.png」はあらかじめ用意した背景画像です。
#geshi(Actionscript3){{
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);
    _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
    }
  }
}

}}
実行すると、以下のように表示されます。

#ref(bg_after02.png);


** エラーの対処法 [#g6bb66fe]
*** 型があっていない [#s8687c31]
 Shader.hx:55: ERROR: 0:16: '-' does not operate on 'int' and 'float'

OpenFLのシェーダーは、型チェックが厳しいため、上記のエラーの例では、整数値と浮動小数値を演算しようとしてエラーが発生しています。適切にキャストを行って型を合わせる必要があります。