3

我有一个像素着色器缓冲区

cbuffer InputBuffer {
   float fTextureWidth;
   float fTextureHeight;
   float fTimeStep;
   float padding;   //padding to align to 16 bytes
};

这对应于我的着色器类中的一个结构:

struct InputBuffer {
    float fTextureWidth;
    float fTextureHeight;
    float fTimeStep;
    float padding;
};

看起来一切都很好,因为它是 16 字节对齐的。但是当我渲染我得到这个警告:

像素着色器单元的插槽 0 处的常量缓冲区的大小太小(提供 16 个字节,预计至少 32 个字节)。这没关系,因为越界读取被定义为返回 0。开发人员也可能知道无论如何都不会使用丢失的数据。如果开发人员实际上打算为着色器所期望的绑定足够大的常量缓冲区,这只是一个问题。[执行警告#351:DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL]

为什么缓冲区需要 32 个字节?我认为 16 是最低要求,而我的显然是?

编辑 1:我添加了 D3DReflect 的输出和我的着色器代码。在像素着色器上运行 D3DReflect 并检索指向常量缓冲区的 ID3D11ShaderReflectionConstantBuffer 指针后,我在缓冲区上运行 GetDesc 方法并得到了我的预期:类型:D3D_CT_BUFFER(0) 变量:4 大小:16 标志:0

根据要求,这是像素着色器代码:

/////////////
// GLOBALS //
/////////////
Texture2D shaderTextures[2];    // 0 is the velocity field texture and 1 is the field that is to be advected
SamplerState SampleType;

/////////////
// BUFFERS //
/////////////
cbuffer InputBuffer {
    float fTextureWidth;
    float fTextureHeight;
    float fTimeStep;
    float fDissipation;
};


//////////////
// TYPEDEFS //
//////////////
struct PixelInputType {
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
};

// Pixel Shader
float4 AdvectionPixelShader(PixelInputType input) : SV_TARGET {
    float2 u = shaderTextures[0].Sample(SampleType, input.tex).xy;  // velocity

    float2 rdFactors = float2(1.0f/fTextureWidth,1.0f/fTextureHeight);

    float2 prevPos = float2(input.tex.x - (fTimeStep*rdFactors.x*u.x),input.tex.y - (fTimeStep*rdFactors.y*u.y) );

    float2 final = shaderTextures[1].Sample(SampleType,prevPos).xy;

    return float4(final,0.0f,1.0f)*fDissipation;
}
4

0 回答 0