为什么Constant Buffer是在Compute Shader中初始化的,而在Pixel Shader中却没有初始化?

问题描述 投票:0回答:1

我正在学习 DirectX11 并尝试制作粒子系统。我有一个 C++ 结构,对应于 .hlsl 中的 cbuffer。在我的计算着色器中,我可以访问 cbuffer 的变量。然而,在图形管道的其他着色器中,例如像素或几何着色器,该值未初始化。

因此,我目前有一个黑色方块漂浮在周围,而它应该是白色的。

这是我的 C++ CBUFFER :

CBUFFER(ParticleSystemCB, CBSLOT_PARTICLESYSTEM)
{
    lu::math::Color startTint;
    lu::math::Color endTint;
    lu::math::Quaternion startRot;
    lu::math::Quaternion endRot;
    float lifeTime;
    float elapsedTime;
    float deltaTime;

    float startSize;
    float endSize;
    float startSpeed;
    float endSpeed;
    
    int elementCount;
};

我的 cbuffer 在 .hlsl 中:

cbuffer ParticleSystem : register(b3)
{
    float4  particleStartTint;
    float4  particleEndTint;
    float4  particleStartRotation;
    float4  particleEndRotation;
    float   particleLifetime;
    float   particleElapsedTime;
    float   particleDeltaTime;
    
    float   particleStartSize;
    float   particleEndSize;
    float   particleStartSpeed;
    float   particleEndSpeed;
    
    uint elementCount;
}

我每帧绑定所有着色器,按照以下顺序 变换常量缓冲区 -> 粒子常量缓冲区 -> 其他着色器。

graphics::StructedBuffer* mParticleBuffer;
graphics::StructedBuffer* mSharedBuffer;
std::shared_ptr<ParticleShader> mParticleShader;

void ParticleSystem::Render()
{
    Owner()->GetComponent<Transform>()->BindConstantBuffer();
    mParticleShader->OnExecute();//binds and dispatches compute shader
    mParticleShader->SetParticles(mParticleBuffer, this);
    mParticleShader->SetSharedBuffer(mSharedBuffer);

    mParticleBuffer->BindSRV(eShaderStage::VS, 14);
    mParticleBuffer->BindSRV(eShaderStage::GS, 14);
    mParticleBuffer->BindSRV(eShaderStage::PS, 14);

    GetMaterial()->Binds();
    GetMesh()->RenderInstanced(1000);

    mParticleBuffer->clear();
}
void ParticleShader::SetParticles(StructedBuffer* particleBuffer, ParticleSystem* ps)
{
    mParticleBuffer = particleBuffer;
    ConstantBuffer* cb = renderer::constantBuffer[(UINT)eCBType::ParticleSystem];

    renderer::ParticleSystemCB data = {};
    data.startTint = ps->mStartTint;
        //and other data Initializations

    cb->SetData(&data);
    cb->Bind(eShaderStage::CS);
}

在我的计算着色器中,我分配了

particleLifetime
,这是正确应用的:

RWStructuredBuffer<Particle> ParticleBuffer : register(u0);
RWStructuredBuffer<ParticleShared> ParticleSharedBuffer : register(u1);

void InitializeParticle(int id)
{
//correctly assigned
    ParticleBuffer[id].lifeTime = particleLifetime;
}

在我的像素着色器中

particleStartTint
应该是白色(1, 1, 1, 1),但颜色是(0, 0, 0, 0),我调整了
w
使其可见。

float4 main(GSOut In) : SV_TARGET
{
    color = particleStartTint;
    color.w = 1;

    return color;
}

这些是我确认的部分:

  • .hlsl 中没有语法错误(ID3DBlob 检查)
  • cbuffer 插槽是正确的(我检查了三次)
  • 结构 CBUFFER 有正确的信息
  • cbuffer 正确绑定后计算着色器检索信息
  • 像素着色器也绑定在cbuffer之后,但是不起作用

目前我希望结果颜色为白色。

感谢您抽出时间。

c++ shader directx-11 fragment-shader compute-shader
1个回答
0
投票
cb->Bind(eShaderStage::CS);

您只需将 cbuffer 绑定到计算阶段,您还需要执行以下操作:

cb->Bind(eShaderStage::PS);

(你需要将它绑定到每个使用cbuffer的阶段,所以如果你在其他图形阶段使用它,你也需要在那里绑定)

© www.soinside.com 2019 - 2024. All rights reserved.