Unityの新MeshAPIでMeshColliderをリアルタイム変形させる
Unity 21.2 Mesh API Compute Shader Access
Last active
February 20, 2022 04:50
-
-
Save zawazawagh/def0da608c3dc869c82b0e00752064d1 to your computer and use it in GitHub Desktop.
VertexBufferVisualizer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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