在不同的着色器中使用相同的常量缓冲区

时间:2017-12-12 14:52:02

标签: c++ directx shader hlsl

我有两个不同的着色器(PS和VS作为单独的文件),在这两个着色器中我需要使用完全相同的常量缓冲区。 他们共享这个常量缓冲区还是要加倍代码?

我没有使用Effects,所以我必须使用Visual Studio在不同的文件中分别编译PS和VS着色器,如果我想在构建时而不是运行时编译着色器(因此CompileFromFile不是我的情况)。

这是我现在的做法,这显然让我犯了错误:

VertexShader:

cbuffer cbPerObject : register(b0)
{
    float4x4 gWorld;
    float4x4 gWorldInvTranspose;
    float4x4 gWorldViewProj;
    Material gMaterial;
};

PixelShader:

cbuffer cbPerObject : register(b0)
{
    float4x4 gWorld;
    float4x4 gWorldInvTranspose;
    float4x4 gWorldViewProj;
    Material gMaterial;
};

cbuffer cbPerFrame : register(b1)
{
    DirectionalLight gDirLight;
    PointLight gPointLight;
    SpotLight gSpotLight;
    float3 gEyePosW;
};

我在Render()方法中设置常量缓冲区的方式(我现在只有一个对象,所以perObj和perFrame缓冲区以相同的方式设置):

m_d3dContext->VSSetConstantBuffers(0, 1, m_cBuffer_perObject.GetAddressOf());
m_d3dContext->PSSetConstantBuffers(0, 1, m_cBuffer_perObject.GetAddressOf());
m_d3dContext->PSSetConstantBuffers(1, 1, m_cBuffer_perFrame.GetAddressOf());

那么什么不起作用?我有一个简单的立方体网格。我成功为vertexPos + vertexColour输入布局渲染了立方体,这次我尝试添加一些光照公式,所以我使用vertexPos + vertexNormal

进行新的输入布局
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }

结果而不是我的立方体我有一些非常巨大的渲染(尺度不是问题所以相机,因为再次,我使用相同的比例和相机的相同立方体的颜色混合和照明公式取自书和不会导致错误。

1 个答案:

答案 0 :(得分:0)

搞定了:我只是忘了考虑在hlsl和c ++之间打包差异。 如果有人对解决方案感兴趣,我必须将这个单一的预处理器命令添加到我的hlsl代码中:

#pragma pack_matrix(row_major)

(或将转置矩阵发送到常量缓冲区)