かんたんXNA4.0 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; 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 ); } } }
今度は色がついています!
頂点シェーダで色を返すようになったので、
ピクセルシェーダの引数として色をとり、
それを描画に反映できるようになったのです。
でもまぁ、こんなんじゃBasicEffectだってできますし、
HLSLだなんてわけのわからないものを使うくらいなら
BasicEffectを使ったほうがずっとましだといえるでしょう。
しかし、HLSLをつかうと、いろいろとおもしろいことができるのです。
次回はそのことについて書くことにします。
PR