在不同的着色器中使用相同的常量缓冲区
Use the same constant buffer in distinct shaders
我有两个不同的着色器(PS 和 VS 作为单独的文件)并且在它们中我需要使用完全相同的常量缓冲区。
他们共享这个常量缓冲区还是代码要加倍?
我没有使用 Effects,所以如果我想在构建时而不是运行时编译着色器,我必须使用 Visual Studio 在不同的文件中分别编译 PS 和 VS 着色器(所以 CompileFromFile 是对我来说不是这样。
这是我现在的方法,这显然会导致渲染错误:
顶点着色器:
cbuffer cbPerObject : register(b0)
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
Material gMaterial;
};
像素着色器:
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 }
因此,我渲染了一些非常巨大的东西,而不是我的立方体(比例不是问题,所以相机也是因为我再次对同一个立方体使用相同的比例和相机进行颜色混合,照明公式取自预订,不能出错)。
成功了:我只是忘了考虑 hlsl 和 c++ 之间的打包差异。
如果有人对解决方案感兴趣,我必须将这个预处理器命令添加到我的 hlsl 代码中:
#pragma pack_matrix(row_major)
(或将转置矩阵发送到常量缓冲区)
我有两个不同的着色器(PS 和 VS 作为单独的文件)并且在它们中我需要使用完全相同的常量缓冲区。 他们共享这个常量缓冲区还是代码要加倍?
我没有使用 Effects,所以如果我想在构建时而不是运行时编译着色器,我必须使用 Visual Studio 在不同的文件中分别编译 PS 和 VS 着色器(所以 CompileFromFile 是对我来说不是这样。
这是我现在的方法,这显然会导致渲染错误:
顶点着色器:
cbuffer cbPerObject : register(b0)
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
Material gMaterial;
};
像素着色器:
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 }
因此,我渲染了一些非常巨大的东西,而不是我的立方体(比例不是问题,所以相机也是因为我再次对同一个立方体使用相同的比例和相机进行颜色混合,照明公式取自预订,不能出错)。
成功了:我只是忘了考虑 hlsl 和 c++ 之间的打包差异。 如果有人对解决方案感兴趣,我必须将这个预处理器命令添加到我的 hlsl 代码中:
#pragma pack_matrix(row_major)
(或将转置矩阵发送到常量缓冲区)