Hi all,
I'm trying to access a StructuredBuffer from a Compute Shader targeting Metal on a MacBook Pro, and finding that it is sometimes full of zeros the first time the shader runs...
My shader is really simple and just returns green if the first item in the StructuredBuffer has a non-zero value and red otherwise...
I only ever set the value for an item to 1 so I know it should always be non-zero (green) however it seems to sometimes be zero (red).
Is this a bug?
**Unity Version:** 2020.1.3f1
**Shader Code:**
#pragma kernel CSMain
RWTexture2D Result;
struct SomeObject
{
float value;
};
StructuredBuffer _Objects;
uint _ObjectsCount;
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
if (_ObjectsCount > 0 && !any(_Objects[0].value)) {
SomeObject s = _Objects[0];
// Red
Result[id.xy] = float4(1, 0, 0, 1);
} else {
// Green
Result[id.xy] = float4(0, 1, 0, 1);
}
}
**Script Code (Attached to the Camera)**:
using System.Collections.Generic;
using UnityEngine;
struct SomeObject
{
public float value;
}
public class MyComputeShaderTest : MonoBehaviour
{
public ComputeShader RayTracingShader;
private RenderTexture _target;
private ComputeBuffer _objectBuffer;
private int _renderCount = 0;
private void OnRenderImage(RenderTexture source, RenderTexture destination)
{
if (_renderCount > 0)
{
return;
}
RayTracingShader.SetBuffer(0, "_Objects", _objectBuffer);
RayTracingShader.SetInt("_ObjectsCount", _objectBuffer.count);
// Make sure we have a current render target
InitRenderTexture();
// Set the target and dispatch the compute shader
RayTracingShader.SetTexture(0, "Result", _target);
int threadGroupsX = Mathf.CeilToInt(Screen.width / 8.0f);
int threadGroupsY = Mathf.CeilToInt(Screen.height / 8.0f);
RayTracingShader.Dispatch(0, threadGroupsX, threadGroupsY, 1);
// Blit the result texture to the screen
Graphics.Blit(_target, destination);
_renderCount++;
}
private void InitRenderTexture()
{
if (_target == null || _target.width != Screen.width || _target.height != Screen.height)
{
// Release render texture if we already have one
if (_target != null)
_target.Release();
// Get a render target for Ray Tracing
_target = new RenderTexture(Screen.width, Screen.height, 0,
RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
_target.enableRandomWrite = true;
_target.Create();
}
}
private void OnEnable()
{
List objects = new List();
// Add a number of random objects
for (int i = 0; i < 100; i++)
{
SomeObject o = new SomeObject();
o.value = 1;
objects.Add(o);
}
// Assign to compute buffer
_objectBuffer = new ComputeBuffer(objects.Count, 4);
_objectBuffer.SetData(objects);
}
private void OnDisable()
{
if (_objectBuffer != null)
_objectBuffer.Release();
}
}
↧