Hey people,
I'm getting some strange errors setting up a constant buffer to send in to my pixel shader (used for rendering directional lights in a deferred renderer).
So this is the buffer, C++ followed by HLSL :
struct LightingConstants
{
DirectX::XMFLOAT3 myLightDirection;
DirectX::XMFLOAT3 myLightColour;
DirectX::XMFLOAT3 myCameraPosition;
DirectX::XMFLOAT2 myHalfPixel;
DirectX::XMMATRIX myInverseViewProjection;
float myPadding;
};
...
cbuffer LightingBuffer
{
float3 myLightDirection;
float3 myLightColour;
float3 myCameraPosition;
float2 myHalfPixel;
float4x4 myInverseViewProjection;
float myPadding;
};
Which should be 112 bytes.
The trouble is when it gets to the pixel shader, some of the values I'm getting are messed up. Setting a light colour of (1.0f, 1.0f, 1.0f) will result in (1.0f, 1.0f, 0.0f) when trying to read from the the buffer, and setting the padding to 0.0f results in a reading of 10.0f (looking at the pix capture).
The really odd thing is that when I calculate the size of the buffer code-side (sizeof(LightingConstants)) I get a value of 128, not 112.
Stranger still, when I enter the buffer layout in to PIX and take a look at the light colour value - it looks correct, but reading it still gives me (1.0f, 1.0f, 0.0f).
Any ideas what I'm doing wrong here? This is how I'm setting up the constant buffer for the pixel shader (I do use a constant buffer for the vertex shader as well, but didn't think that the two would interfere with each other) :
Building the buffer :
HRESULT result;
D3D11_BUFFER_DESC bufferDescription;
VEDirectXInterface* renderInterface = VoxelEngine::GetInstance()->GetRenderInterface();
assert( renderInterface != NULL );
// Set up the buffer with a byte width of three matrices
bufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bufferDescription.ByteWidth = sizeof(LightingConstants);
bufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDescription.MiscFlags = 0;
bufferDescription.StructureByteStride = 0;
bufferDescription.Usage = D3D11_USAGE_DYNAMIC;
// Create the buffer
result = renderInterface->GetDevice()->CreateBuffer(
&bufferDescription,
NULL,
&myPixelConstantBuffer);
if( FAILED(result) )
{
return false;
}
return true;
Populating the buffer :
// Grab the lighting constant buffer
result = deviceContext->Map( myPixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource );
if( FAILED(result) )
{
return false;
}
// Fill in the lighting buffer
lightingBuffer = (LightingConstants*)mappedResource.pData;
lightingBuffer->myCameraPosition = aCamera->GetPosition();
lightingBuffer->myHalfPixel = renderManager->GetHalfPixel();
lightingBuffer->myLightColour = directionalLight->GetColour();
lightingBuffer->myLightDirection = directionalLight->GetDirection();
lightingBuffer->myPadding = 0.0f;
// Calculate the inverse view-projection matrix
XMMATRIX viewProj = XMMatrixMultiply( XMLoadFloat4x4(&aCamera->GetView()), XMLoadFloat4x4(&aCamera->GetProjection()) );
XMMATRIX inverseViewProj = XMMatrixInverse( NULL, viewProj );
lightingBuffer->myInverseViewProjection = XMMatrixTranspose(inverseViewProj);
// Release the buffer
deviceContext->Unmap( myPixelConstantBuffer, 0 );
// Set the constant buffer for the pixel shader
deviceContext->PSSetConstantBuffers( 0, 1, &myPixelConstantBuffer );
Thanks for the help!