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

标签 c++ directx shader hlsl

我有两个不同的着色器(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)

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

关于c++ - 在不同的着色器中使用相同的常量缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47775466/

相关文章:

c++ - 如何在C++中播放声音?

directx - DirectX Textures是否共享/减少(32位)应用程序的地址空间?

glsl - 为什么这个 Shaderoy 在 glsl 中无法正确显示?

c++ - 关于 64 位环境中 Delphi 和 C++ 中的枚举

c++ - Qt 中的内部类

c++ - 安装VC2008后VC2005变慢了

opengl-es - 如何模拟GL_DEPTH_CLAMP_NV?

directx - DX11 三角形列表根本不渲染

input - 如何从 Xbox 360 Controller 获取输入?

opengl-es - OpenGL 片段着色器如何知道要在纹理中采样哪个像素?