'Compute Shader Buffer output is incomplete when Appending from another AppendStructuredBuffer
I am working on a placement system where I, from specific parameters find locations in a compute shader and then append these to an AppendStructuredBuffer. This works as expected. The issues stems from using the resulting buffer in another shader, which also tries to Append to a new AppendStructuredBuffer. The output from that buffer is much less than what came in.
Eventually the result is copied to a final buffer for rendering with DrawMeshInstancedIndirect.
Here is the compute shader, it just places objects on a plane.
AppendStructuredBuffer<VegetationData> _OutVegetationData;
[numthreads(32,32,1)]
void VegetationPlacement (uint3 id : SV_DispatchThreadID)
{
VegetationData data;
float2 remappedVal;
Remap_float(float2(id.x, id.y), float2(0,512), float2(-256, 256), remappedVal);
data.position = half4(float4(objPos, 0) + float4(float3(remappedVal.x, 0, remappedVal.y), 1));
data.normals = half3(0,1,0);
data.scale = 1;
_OutVegetationData.Append(data);
return;
And the dispatch - which is run in Update, the shader has been instanced in a start function.
void Update()
{
foreach (var vegetation in terrain.VegetationsOnTerrain)
{
if (vegetation.vegetationDataBuffer == null)
{
vegetation.vegetationDataBuffer = new ComputeBuffer(512*512, 16 + 28, ComputeBufferType.Append);
vegetation.vegetationComputeShaderInstance.SetBuffer(vegetation.vegetationKernel, "_OutVegetationData", vegetation.vegetationDataBuffer);
vegetation.vegetationComputeShaderInstance.SetVector("objPos", terrain.transform.position);
vegetation.vegetationDataBuffer?.SetCounterValue(0);
vegetation.vegetationComputeShaderInstance.Dispatch(vegetation.vegetationKernel,
(int)512/32,
(int) 512 / 32,
(int) 1);
}
}
I then have another compute shader which uses that buffer as a StructuredBuffer to read from, and then fills another AppendStrucuredBuffer which will eventually have some culling happening here. This is the second compute shader:
StructuredBuffer<VegetationData> _InVerticeData;
AppendStructuredBuffer<VegetationData> _OutVegetationData;
[numthreads(32,32,1)]
void LevelOfDetail (uint3 id : SV_DispatchThreadID)
{
_OutVegetationData.Append(_InVegetationData[id.x*id.y]);
return;
}
Here is how I invoke the second computeshader. It is run just after the first shader's dispatch.
The AppendStrcturedBuffer from the first shader is set in the second compute shader as a StructuredBuffer "_InVegetationData".
foreach (var vegetation in terrain.VegetationsOnTerrain)
{
if (vegetation.vegetationLodDataBuffer == null)
{
vegetation.lodComputeShaderInstance.SetBuffer(vegetation.vegetationLodKernel, "_InVegetationData", vegetation.vegetationDataBuffer);
vegetation.vegetationLodDataBuffer = new ComputeBuffer(512 * 512, 16 + 28, ComputeBufferType.Append);
vegetation.lodComputeShaderInstance.SetBuffer(vegetation.vegetationLodKernel, "_OutVegetationData", vegetation.vegetationLodDataBuffer);
vegetation.materialInstance.SetBuffer("vegetationDataBuffer", vegetation.vegetationLodDataBuffer);
}
vegetation.vegetationLodDataBuffer?.SetCounterValue(0);
vegetation.lodComputeShaderInstance.Dispatch(vegetation.vegetationLodKernel,
(int)512/32,
(int)512/32,
(int) 1 / 1);
ComputeBuffer.CopyCount(vegetation.vegetationLodDataBuffer, vegetation.argsBuffer, 4);
}
How it looks after using the second compute shader: notice the thinning.
The hope for a result, would be that the output of the first computeshader/buffer, but if I do not append them in the second compute shader, they will just not appear. I am thinking this is probably/definitely a matter of the GPU not finishing or something like that, but I am not quite sure. Any help will be much appreciated!
Thanks.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
