Skip to content

Instantly share code, notes, and snippets.

@zawazawagh
Last active February 20, 2022 04:50
Show Gist options
  • Save zawazawagh/def0da608c3dc869c82b0e00752064d1 to your computer and use it in GitHub Desktop.
Save zawazawagh/def0da608c3dc869c82b0e00752064d1 to your computer and use it in GitHub Desktop.
VertexBufferVisualizer
#pragma kernel CSMain
struct VertexPosition
{
float3 Position;
};
ByteAddressBuffer Verts;
RWStructuredBuffer<VertexPosition> VertexPositionBuffer;;
float4x4 LocalToWorld;
int VertexCount;
[numthreads(1,1,1)]
void CSMain (uint3 id : SV_GroupThreadID)
{
for(int i = 0; i < VertexCount; i++)
{
//float3 Position, float3 Normal, float4 Tangent, float2 TexCoord0
//total 12 floats, 4bytes
//4 * 12 = 48
int vidx = i.x * 48;
uint3 praw = Verts.Load3(vidx);
float3 localPosition = asfloat(praw);
float4 worldPosition = mul(LocalToWorld, float4(localPosition, 1));
VertexPositionBuffer[i].Position = float3(worldPosition.xyz);
}
}
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Rendering;
public class VertexBufferVisualizer : MonoBehaviour
{
[SerializeField]
private GameObject _meshObject;
[SerializeField]
private ComputeShader _computeShader;
private ComputeBuffer _vertexPositionBuffer;
private GraphicsBuffer _vertexBuffer;
private VertexPosition[] _result;
private Mesh _mesh;
private List<GameObject> _vertVisualiser = new List<GameObject>();
public struct VertexPosition
{
public Vector3 Position;
}
void Start()
{
_mesh = _meshObject.GetComponent<MeshFilter>().mesh;
VertexAttributeDescriptor[] attrubtes = _mesh.GetVertexAttributes();
//Position Float32 0 30 0 48
//Normal Float32 0 312 0 48
//Tangent Float32 0 424 0 48
//TexCoord0 Float32 0 240 0 48
for (int i = 0; i < attrubtes.Length; i++)
{
Debug.Log($"{attrubtes[i].attribute} " +
$"{attrubtes[i].format} " +
$"{attrubtes[i].stream} " +
$"{attrubtes[i].dimension}" +
$"{_mesh.GetVertexAttributeOffset(attrubtes[i].attribute)} " +
$"{_mesh.GetVertexAttributeStream(attrubtes[i].attribute)} " +
$"{_mesh.GetVertexBufferStride(attrubtes[i].stream)} ");
}
_vertexPositionBuffer = new ComputeBuffer(_mesh.vertexCount, Marshal.SizeOf<VertexPosition>());
_mesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw;
_vertexBuffer = _mesh.GetVertexBuffer(0);
_computeShader.SetBuffer(0, "Verts", _vertexBuffer);
_computeShader.SetBuffer(0, "VertexPositionBuffer", _vertexPositionBuffer);
_computeShader.SetInt("VertexCount", _mesh.vertexCount);
_result = new VertexPosition[_mesh.vertexCount];
for (int i = 0; i < _mesh.vertexCount; i++)
{
var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.transform.localScale = Vector3.one * 0.1f;
_vertVisualiser.Add(sphere);
}
}
private void OnDestroy()
{
_vertexBuffer.Dispose();
_vertexPositionBuffer.Dispose();
}
void Update()
{
_computeShader.SetMatrix("LocalToWorld", _meshObject.transform.localToWorldMatrix);
_computeShader.Dispatch(0, 1,1,1);
_vertexPositionBuffer.GetData(_result);
for (int i = 0; i < _vertVisualiser.Count; i++)
{
_vertVisualiser[i].transform.position = _result[i].Position;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment