「Directx 11での3Dゲームプログラミング入門」で作業しています。エフェクトフレームワークを使用しないようにサンプルを修正しています。定数バッファが部分的にDirect11で更新されるのはなぜですか?
しかし、定数バッファの1つが部分的にしか更新されないという問題がありました。
CPU側CB構造体:私は前の任意の図面にCBを更新
struct CBPerFrame
{
DirectionalLight DirLight[3];
DirectX::XMFLOAT3 EyePositionW;
DirectX::XMFLOAT4 FogColour;
float FogStart;
float FogRange;
int LightNumber;
double Padding;
};
。
CBPerFrame cbPerFrame { };
cbPerFrame.DirLight[ 0 ] = mDirectionalLights[ 0 ];
cbPerFrame.DirLight[ 1 ] = mDirectionalLights[ 1 ];
cbPerFrame.DirLight[ 2 ] = mDirectionalLights[ 2 ];
cbPerFrame.EyePositionW = mEyePosW;
cbPerFrame.FogColour = XMFLOAT4(Colors::Black);
cbPerFrame.FogRange = 1.0F;
cbPerFrame.FogStart = 0.0F;
cbPerFrame.LightNumber = mLightCount;
cbPerFrame.Padding = 0.0;
mD3DImmediateContext->UpdateSubresource(mCBPerFrame.Get(), 0, nullptr, &cbPerFrame, 0, 0);
ピクセルシェーダ:
cbuffer CBPerFrame : register(b0)
{
DirectionalLight gDirectionalLights[ 3 ];
float3 gEyePosW;
float4 gFogColor;
float gFogStart;
float gFogRange;
int gLightCount;
double gPadding;
}
cbuffer CBPerObject : register(b1)
{
matrix gWorld;
matrix gWorldInverseTranspose;
matrix gWorldViewProjection;
float4x4 gTextureTransform;
Material gMaterial;
}
float4 main(VertexOut input) : SV_TARGET
{
// Interpolating normal can unnormalize it, so normalize it.
input.NormalW = normalize(input.NormalW);
// The toEye vector is used in lighting.
float3 toEye = normalize(gEyePosW - input.PositionW);
// Cache the distance to the eye from this surface point.
float distToEye = length(toEye);
// Normalize.
toEye /= distToEye;
//
// Lighting.
//
// Start with a sum of zero.
float4 ambient = float4(0.0F, 0.0F, 0.0F, 0.0F);
float4 diffuse = float4(0.0F, 0.0F, 0.0F, 0.0F);
float4 spec = float4(0.0F, 0.0F, 0.0F, 0.0F);
// Sum the light contribution from each light source.
/* [unroll]*/
for (int i = 0; i < gLightCount; i++)
{
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirectionalLights[ i ], input.NormalW, toEye, A, D, S);
ambient += A;
diffuse += D;
spec += S;
}
float4 litColour = ambient + diffuse + spec;
// Common to take alpha from diffuse material.
litColour.a = gMaterial.Diffuse.a;
return litColour;
}
はgLightCountは常にそれがアプリケーションの開始時に2に設定する必要があっても、0に設定されています。ループの条件をハードコードされた1/2/3に変更すると、シェイダーは正常に機能します。
私は、CBに余分な変数があることを認識していますが、サンプルコードにこれがあり、さらなる例で使用されていると思います。
私は、CBPerFrame構造体がどのように埋め込まれているかに問題があると思うので、GPUに正しくコピーされていません。何かご意見は?
ありがとうございました。
ありがとうございましたCB構造体は16バイトの倍数でなければならないが、16バイト境界で整列する必要があることは知らなかった。 – Compton