0

我正在使用一个常量缓冲区在每一帧将数据传递给我的着色器,并且我遇到了一个问题,即缓冲区的某些成员的值指向同一内存。

当我使用 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 );
}
4

1 回答 1

0

它看起来像这个问题中的填充问题:问题

所有常量缓冲区的大小都应该被 sizeof(四分量向量) ( doc )整除

于 2013-02-18T09:31:28.767 回答