忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

[XNA] SpriteBatch + Effect

SpriteBatchEffectを組み合わせる方法に手こずったのでメモしておきますね。

SpriteBatchはXNAの2D機能(といってもテクスチャの描画くらいしかできませんが)をカプセル化したクラスで、それに対してEffectは頂点データをピクセルの色に変換する方法を表すクラスで、どちらかというと3Dです。
もしこの2つを組み合わせることができるのなら(実際できるのですが)、テクスチャにピクセルシェーダーを簡単に適用することができます(たとえば、水面がゆらゆらと揺れている様子がかんたんに表現できるでしょう)

しかし困ったことに、SpriteBatchにはEffectを使うメンバが見当たりませんでした。
ではこの2つは一緒に使うことができないのかというと、そうではありません。
きちんと一緒に使うことができます。
で、ぐだぐだ説明を続けてもいいですが、ここはコードを見たほうが早いでしょう。とくに難しいところはありませんからね。


MyGame.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

public class MyGame : Game
{
    GraphicsDeviceManager graphics;

    SpriteBatch spriteBatch;
    Texture2D texture;
    Effect effect;

    public MyGame()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void LoadContent()
    {
        texture = Content.Load("henohenomoheji");
        effect = Content.Load("2DEffect");

        spriteBatch = new SpriteBatch(GraphicsDevice);
    }

    protected override void UnloadContent()
    {
        spriteBatch.Dispose();
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);


        spriteBatch.Begin(
            SpriteBlendMode.None,
            SpriteSortMode.Immediate,
            SaveStateMode.None
            );

            effect.Begin();
            effect.CurrentTechnique.Passes[0].Begin();

                spriteBatch.Draw(texture, new Vector2(), Color.White);

            effect.CurrentTechnique.Passes[0].End();
            effect.End();

        spriteBatch.End();
    }


    static void Main()
    {
        using (MyGame game = new MyGame())
        {
            game.Run();
        }
    }
}


2DEffect.fx
sampler TextureSampler : register(s0);

float4 PixelShaderFunction(float2 textureCoordinate : TEXCOORD) : COLOR0
{
    float2 texOffset = {sin(textureCoordinate.x * 30) / 20 , 0};
    
    return tex2D(
        TextureSampler,
        textureCoordinate + texOffset
        );
}

technique Technique1
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}



spriteBatchWithPixelShader.jpg

なんだかよくわからないものが左上に表示されていますが、これは「へのへのもへじ」をピクセルシェーダーで変形したものです。

henohenomoheji.jpghenohenomoheji.jpg


ピクセルシェーダー内で、適当にテクスチャ座標をいじってやると、水面が揺らいでいるようにみえなくもないというわけです。









拍手[0回]

PR