忍者ブログ

Memeplexes

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

かんたんXNA4.0 HLSL編 その4 フロー制御文


HLSLにも他の多くのC言語ベースの言語と同じように、
フロー制御文があります。

つまりifやfor, while, doとかのことです。

まず、msdnを見ると、
if, for, while, switch, do, break, continueと、
一通りそろっているようです。(以下msdnより)

[Attribute] if ( Conditional )
{
    Statement Block
}

[Attribute] for ( Initializer; Conditional; Iterator )
{
    Statement Block;
}

[Attribute] while ( Conditional )
{
    Statement Block;
}

[Attribute] switch ( Selector
{
    case 0 :
        { Statement Block; }
    break;
    case 1 :
        { Statement Block; }
    break;
    case n :
        { Statement Block; }
    break;
    default :
        { Statement Block; }
    break;
}

do 
{
    Statement Block;
} while( Conditional )

break;

continue;


おなじみの文です。
・・・・・・と思ったら[Attribute]とかいう変なのがありますね・・・。
どうやらこれはコンパイルの方法を指定する、C#の一部の属性のようなものらしいです。
でも省略可能なので普通のC言語系のフロー制御と同じように使うことができます。


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

class MyGame : Game
{
    GraphicsDeviceManager graphics;

    Effect effect;
    VertexPositionColor[] vertices = {
            new VertexPositionColor(new Vector3(0, 1, 0), Color.White),
            new VertexPositionColor(new Vector3(1, 0, 0), Color.Blue),
            new VertexPositionColor(new Vector3(-1, 0, 0), Color.Red)
        };


    public MyGame()
    {
        graphics = new GraphicsDeviceManager(this);
    }

    protected override void LoadContent()
    {
        effect = Content.Load<Effect>("Content/MyEffect");
    }

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

        foreach (var pass in effect.CurrentTechnique.Passes)
        {
            pass.Apply();

            GraphicsDevice.DrawUserPrimitives<VertexPositionColor>
            (
                PrimitiveType.TriangleList,
                vertices,
                0,
                vertices.Length / 3
            );
        }
    }
}

MyEffect.fx
struct VertexPositionColor
{
	float4 Position : POSITION;
	float4 Color : COLOR;
};

VertexPositionColor MyVertexShader(VertexPositionColor input)
{
	return input;
}

float4 MyPixelShader(float4 color : COLOR) : COLOR
{
	if(color.r % 0.1f < 0.05f)
		return float4(1,1,1,1);
	else
		return color;
}

technique MyTechnique
{
	pass MyPass
	{
		VertexShader = compile vs_2_0 MyVertexShader();
		PixelShader = compile ps_2_0 MyPixelShader();
	}
}


stripeTriangle.jpg
ほどよくしましまになっているのがわかると思います。
ピクセルシェーダに与えられる色の赤いチャンネルをもとにして
条件分岐を行ったのです。
こんなことをしても実際には何の役にも立たないかもしれませんが、
HLSLの威力がよくわかる例ではないでしょうか。
少なくともこれはBasicEffectでは出来ませんからね。







拍手[1回]

PR