I'm learning DirectX11 and trying to make a Particle System. I have a structure in C++ that corresponds to the cbuffer in .hlsl. In my compute shader I can access cbuffer's variable. However in other shaders of the graphics pipeline, such as pixel or geometry shader, the value is not initialized.
Therefore I currently have a black square floating around, when it should be white.
This is my CBUFFER in C++ :
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;
};
And my cbuffer in .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;
}
I am binding all my shaders every frame, in the order of transform constant buffer -> particle constant buffer-> other shaders.
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);
}
In my compute shader I am assigning particleLifetime
, which is correctly applied:
RWStructuredBuffer<Particle> ParticleBuffer : register(u0);
RWStructuredBuffer<ParticleShared> ParticleSharedBuffer : register(u1);
void InitializeParticle(int id)
{
//correctly assigned
ParticleBuffer[id].lifeTime = particleLifetime;
}
And in my pixel shader particleStartTint
should be white(1, 1, 1, 1), but color was (0, 0, 0, 0), I tweaked w
to make it visible.
float4 main(GSOut In) : SV_TARGET
{
color = particleStartTint;
color.w = 1;
return color;
}
These are the parts I confirmed:
Currently I want the resulting color to be white.
Thank you for taking your time.
cb->Bind(eShaderStage::CS);
You only bind your cbuffer to the compute stage, you also need to do :
cb->Bind(eShaderStage::PS);
(You need to bind it to every stage where you use the cbuffer also, so if you use it on other graphics stages, you need to bind there too)