Klemen Brajkovič

d3cr1pt0r

About Me

Connect

LOCATION
Not Specified
WEBSITE

Houdini Skills

Availability

Not Specified

Recent Forum Posts

VAT baking with C# Nov. 7, 2023, 11:04 a.m.

I am currently working on a project where we rely on animating meshes using tha VAT technique (vertex animation textures). Since this is a mobile project, we need to take into consideration the performance, so in order to optimise this, we would like to bake the animation at the specific frame on specific meshes that need to be in a specific state.

The way I approached this was to "reverse engineer" the shader graph shader and extracted all the logic to C# for just the code that handles/manipulates vertex positions. I mostly succeeded in the task, except that the results seem to be off only at specific vertices. Notice on the edges, the vertices get that jagget shape and I also noticed some triangles just floating in empty space, detached from the mesh.

Here is the code I am using to bake the VAT position texture in C#
private void GenerateMesh() { var mesh = new Mesh(); var vertices = _mesh.vertices; var uv1 = _mesh.uv2; var textureWidth = _positions.width; var textureHeight = _positions.height; var tMin = _vatData.BoundsMin * 10.0f; var tMax = _vatData.BoundsMax * -10.0f; var pixelRatioX = 1.0f - (Mathf.Ceil(tMin.z) - tMin.z); var pixelRatioY = 1.0f - (tMax.x - Mathf.Floor(tMax.x)); var a = (Mathf.Floor(_vatData.DisplayFrame) - 1f) % _vatData.FrameCount; var b = a * (1.0f / _vatData.FrameCount) * pixelRatioY; for (var i = 0; i < vertices.Length; i++) { var uv = uv1[i]; var c = b + (1.0f - uv.y) * pixelRatioY; var sampleX = Mathf.FloorToInt(uv.x * pixelRatioX * textureWidth); var sampleY = Mathf.CeilToInt(c * textureHeight); var pixel = _positions.GetPixel(sampleX, sampleY); var offset = new Vector3(pixel.r, pixel.g, pixel.b); if (uv.y <= 0.1f) offset = new Vector3(0, 0, 0); vertices[i] += offset; } mesh.vertices = vertices; mesh.triangles = _mesh.triangles; mesh.tangents = _mesh.tangents; mesh.uv = _mesh.uv; mesh.uv2 = _mesh.uv2; mesh.RecalculateNormals(); mesh.RecalculateTangents(); _meshFilter.sharedMesh = mesh; }
Attached in the post is the image of how the results look like. On the left is the VAT shader from Houdini, on the right is the C# bake.