この短いチュートリアルに従って、基本的なハードウェア モデルのインスタンス化方法を XNA コードに実装しました 。 -テクスチャ/
必要なシェーダーを作成しました (ただし、テクスチャ アトラスはなく、単一のテクスチャのみ)。この方法を使用して、3DS Max 2013 を使用して生成し、FBX 形式でエクスポートした単純なツリーを描画しようとしています。
私が見ている結果は、何が起こっているのか手がかりがありませんでした。
インスタンス化メソッドを使用せず、メッシュで Draw を呼び出すだけだったとき (レベルのすべてのツリーに対して)、ツリー全体が表示されました。
モデルにMesh が 1 つしか含まれておらず、 Mesh に MeshPart が 1 つしか含まれていないことを確認しました。
モデルの頂点とインデックス バッファーの "GetData<>()" メソッドを使用して頂点抽出メソッドを使用し、正しい数の頂点とインデックスを使用しているため、正しい数のプリミティブがレンダリングされます。レンダリングされている木の部分からわかるように、正しいテクスチャ座標と照明の法線も抽出されます。
また、木の部分も正しい場所にあります。
何の理由もなく、単に 1000 個程度のポリゴンが欠落しているだけです。頂点抽出とシェーダーのパラメーター生成のすべてのステップでブレークポイントを設定しましたが、何が間違っているのか一生わかりません。
私のシェーダーの頂点変換関数:
VertexShaderOutput VertexShaderFunction2(VertexShaderInput IN, float4x4 instanceTransform : TEXCOORD1)
{
VertexShaderOutput output;
float4 worldPosition = mul(IN.Position, transpose(instanceTransform));
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.texCoord = IN.texCoord;
output.Normal = IN.Normal;
return output;
}
頂点バインディングとインデックス バッファーの生成:
instanceBuffer = new VertexBuffer(Game1.graphics.GraphicsDevice, Core.VertexData.InstanceVertex.vertexDeclaration, counter, BufferUsage.WriteOnly);
instanceVertices = new Core.VertexData.InstanceVertex[counter];
for (int i = 0; i < counter; i++)
{
instanceVertices[i] = new Core.VertexData.InstanceVertex(locations[i]);
}
instanceBuffer.SetData(instanceVertices);
bufferBinding[0] = new VertexBufferBinding(vBuffer, 0, 0);
bufferBinding[1] = new VertexBufferBinding(instanceBuffer, 0, 1);
すべての頂点情報を取得するために使用される頂点抽出方法 (この部分は、さまざまなシェーダーをテストし、それらを使用してそれらの周りにバウンディング ボックスを構築するために、ボックス、球体などのレベルにテスト用の幾何学的形状をロードするために以前に使用したので、正しく動作するはずです)頂点データを抽出し、すべて正しい):
public void getVertexData(ModelMeshPart part)
{
modelVertices = new VertexPositionNormalTexture[part.NumVertices];
rawData = new Vector3[modelVertices.Length];
modelIndices32 = new uint[rawData.Length];
modelIndices16 = new ushort[rawData.Length];
int stride = part.VertexBuffer.VertexDeclaration.VertexStride;
VertexPositionNormalTexture[] vertexData = new VertexPositionNormalTexture[part.NumVertices];
part.VertexBuffer.GetData(part.VertexOffset * stride, vertexData, 0, part.NumVertices, stride);
if (part.IndexBuffer.IndexElementSize == IndexElementSize.ThirtyTwoBits)
part.IndexBuffer.GetData<uint>(modelIndices32);
if (part.IndexBuffer.IndexElementSize == IndexElementSize.SixteenBits)
part.IndexBuffer.GetData<ushort>(modelIndices16);
for (int i = 0; i < modelVertices.Length; i++)
{
rawData[i] = vertexData[i].Position;
modelVertices[i].Position = rawData[i];
modelVertices[i].TextureCoordinate = vertexData[i].TextureCoordinate;
modelVertices[i].Normal = vertexData[i].Normal;
counter++;
}
}
これは、オブジェクト バッチ (この特定のケースではツリー) のレンダリング コードです。
public void RenderHW()
{
Game1.graphics.GraphicsDevice.RasterizerState = rState;
treeBatchShader.CurrentTechnique.Passes[0].Apply();
Game1.graphics.GraphicsDevice.SetVertexBuffers(bufferBinding);
Game1.graphics.GraphicsDevice.Indices = iBuffer;
Game1.graphics.GraphicsDevice.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, treeMesh.Length, 0, primitive , counter);
Game1.graphics.GraphicsDevice.RasterizerState = rState2;
}
何が起こっているのか完全に困惑しているので、誰かがどこからエラーを探し始めるか考えている場合は、頭に浮かぶすべてのアイデアを投稿してください。
これは、シェーダー コードまたは頂点生成で何かを台無しにして、画面上で絶対的な混乱が発生するという私の以前のすべての経験に逆らうことさえあります。 (0,0,0)、黒いテクスチャ、不適切な配置 (多くの場合、スカイボックスの外側または地形の下)、不適切なスケーリング...
これは、あたかも機能しているかのように、何かが異なります。表示されているツリーの部分は、一部が欠けていることを除いて、すべての側面 (位置、回転、スケール、テクスチャ、シェーディング) で正しいです。私にとって奇妙なのは、欠落している部分が論理的にセグメント化されているように見えることです。木の幹のプリミティブと、木の最も低い枝から離れたいくつかの葉だけが欠落しており、他のすべてのプリミティブはアーティファクトなしで正しくレンダリングされたままです。基本的に、それらは...正しく欠落しています。