"Directx 11에서 3D 게임 프로그래밍 소개"를 진행하십시오. Effects Framework을 사용하지 않도록 샘플을 다시 작성합니다. 지금까지는 모두 훌륭했습니다.Direct11에서 부분 버퍼 업데이트가 부분적으로 발생합니다
그러나 상수 버퍼 중 하나가 부분적으로 만 업데이트된다는 문제가 있습니다.
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