忍者ブログ

Memeplexes

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

かんたんXNA HLSL編 その2 構造体

このページは古いです
最新版はこちら

前回表示したポリゴンに色はついていませんでした。
使った頂点データには色がついていたにもかかわらず、
実際に描画された三角形のすべてのピクセルの色が白だったのです。

これは前回のエフェクトファイルが色を扱っていないことが原因です。
頂点シェーダでは、位置情報だけではなく色の情報も扱わなければなりませんし、
ピクセルシェーダだって引数として色をとらなければなりません。

位置だけでなく色の情報も扱うためには、その二つをまとめるための
構造体を作る必要があります。
(複数の戻り値を返すことはできませんからね)

構造体のつくり方はC/C++のものとほとんど同じです。
もっともセマンティクス(用途)をつける必要はありますが・・・。

struct 構造体名
{
        型 変数名1 : セマンティクス;
        型 変数名2 : セマンティクス;
...
};


具体的に書くとしたらこんな感じでしょうか。

struct VertexPositionColor
{
        float4 Position : POSITION;
        float4 Color : COLOR;
};

C#やJavaになれているひとは最後のセミコロン(;)を忘れないでください。
また、デフォルトでpublicのようにアクセスできることも意外かもしれません。


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

VertexPositionColor MyVertexShader(VertexPositionColor input)
{
	return input;
}

float4 MyPixelShader(float4 color : COLOR) : COLOR
{
	return color;
}

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

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


public class MyGame : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    ContentManager content;

    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);
        content = new ContentManager(Services);
    }

    protected override void LoadGraphicsContent(bool loadAllContent)
    {
        if (loadAllContent)
        {
            effect = content.Load<Effect>("MyEffect");

            graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(
                graphics.GraphicsDevice,
                VertexPositionColor.VertexElements
                );
        }
    }

    protected override void UnloadGraphicsContent(bool unloadAllContent)
    {
        if (unloadAllContent) { content.Unload(); }
    }

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

        effect.Begin();

        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Begin();

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

            pass.End();
        }

        effect.End();
    }
}


 customEffectColor.jpg

今度は色がついています!

頂点シェーダで色を返すようになったので、
ピクセルシェーダの引数として色をとり、
それを描画に反映できるようになったのです。

でもまぁ、こんなんじゃBasicEffectだってできますし、
HLSLだなんてわけのわからないものを使うくらいなら
BasicEffectを使ったほうがずっとましだといえるでしょう。
しかし、HLSLをつかうと、いろいろとおもしろいことができるのです。
次回はそのことについて書くことにします。



拍手[0回]

PR