Hi, I’ve encountered a predicament related to the vertex buffer provided by Unity and AMD graphics cards. Specifically, I can’t get a simple compute shader to modify the vertex data of a mesh on these graphics cards. It only manages to change the first vertexData element, whereas on other GPUs, it works as expected, modifying all vertices.
Here is the simple test code:
Compute Shader:
#pragma kernel TestKernel
struct MeshData
{
float3 pos;
float3 normal;
float4 tangent;
};
uint expectedNumberOfThreads; //Each thread represents a vertex
[numthreads(64, 1, 1)]
void TestKernel(uint3 id : SV_DispatchThreadID, RWStructuredBuffer<MeshData> meshData)
{
const uint threadId = id.x;
if (threadId >= expectedNumberOfThreads) return;
meshData[threadId].pos = float3(1.0, 2.0, 3.0);
meshData[threadId].normal = float3(1.0, 2.0, 3.0);
meshData[threadId].tangent = float4(1.0, 2.0, 3.0, 4.0);
}
C#:
public class IT_VertexBufferTest : MonoBehaviour
{
[SerializeField] private ComputeShader _computeShader;
public struct MeshData
{
public Vector3 position;
public Vector3 normal;
public Vector4 tangent;
}
[SerializeField] private Mesh _targetMesh;
[ContextMenu("TestMeshComputeShader")]
private void TestMeshComputeShader()
{
_targetMesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
var vertexAttributeStream = _targetMesh.GetVertexAttributeStream(VertexAttribute.Position);
var targetMeshVertexBuffer = _targetMesh.GetVertexBuffer(vertexAttributeStream);
_computeShader.SetInt("expectedNumberOfThreads", _targetMesh.vertexCount);
_computeShader.SetBuffer(0, "meshData", targetMeshVertexBuffer);
var numberOfThreadGroups = Mathf.CeilToInt(_targetMesh.vertexCount / 64f);
_computeShader.Dispatch(0, numberOfThreadGroups, 1, 1);
// Read back the data
var data = new MeshData[_targetMesh.vertexCount];
targetMeshVertexBuffer.GetData(data);
}
}
I’ve tested in both, Unity 2021.3.13f1 and 2023.2.20f1