我正在使用常量缓冲区在每一帧将数据传递给我的着色器,而我遇到的问题是缓冲区某些成员的值指向同一个内存。
当我使用Visual Studio 2012调试工具时,看起来数据正在或多或少正确地设置在缓冲区中:
0 [0x00000000-0x00000003] | +0
1 [0x00000004-0x00000007] | +1
2 [0x00000008-0x0000000b] | +1
3 [0x0000000c-0x0000000f] | +1
4 [0x00000010-0x00000013] | +0.78539819
5 [0x00000014-0x00000017] | +1.1760513
6 [0x00000018-0x0000001b] | +0
7 [0x0000001c-0x0000001f] | +1
问题在于,当我调试着色器时,sunAngle和phaseFunction都具有相同的值 - 特别是0.78539819
,它应该只是sunAngle的值。如果我交换两个浮点数的顺序,它确实会变为1.1760513
,但两者仍然是相同的。我以为我已经将所有内容正确地打包在一起,但是我不知道如何准确定义缓冲区各部分的常量?
这是我正在使用的C ++结构:
struct SunData {
DirectX::XMFLOAT4 sunPosition;
float sunAngle;
float phaseFunctionResult;
};
着色器缓冲区如下所示:
// updated as the sun moves through the sky
cbuffer sunDependent : register( b1 )
{
float4 sunPosition;
float sunAngle; // theta
float phaseFunctionResult; // F( theta, g )
}
这是我用来初始化缓冲区的代码:
XMVECTOR pos = XMVectorSet( 0, 1, 1, 1 );
XMStoreFloat3( &_sunPosition, pos );
XMStoreFloat4( &_sun.sunPosition, pos );
_sun.sunAngle = XMVectorGetX(
XMVector3AngleBetweenVectors( pos, XMVectorSet( 0, 1, 0, 0 ) )
);
_sun.phaseFunctionResult = _planet.phaseFunction( _sun.sunAngle );
// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc;
cbDesc.ByteWidth = sizeof( SunData ) + 8;
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;
// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &_sun;
data.SysMemPitch = 0;
data.SysMemSlicePitch = 0;
// Create the buffer.
ID3D11Buffer *constantBuffer = nullptr;
HRESULT hr = _d3dDevice->CreateBuffer(
&cbDesc,
&data,
&constantBuffer
);
assert( SUCCEEDED( hr ) );
// Set the buffer.
_d3dDeviceContext->VSSetConstantBuffers( 1, 1, &constantBuffer );
_d3dDeviceContext->PSSetConstantBuffers( 1, 1, &constantBuffer );
Release( constantBuffer );
这是使用值的像素着色器:
float4 main( in ATMOS_PS_INPUT input ) : SV_TARGET
{
float R = sunAngle * sunPosition.x * sunIntensity.x
* attenuationCoefficient.x
* phaseFunctionResult;
return float4( R, 1, 1, 1 );
}