- Home /
Deform shared vertices only on a planee
This is my first post here, i just moved from NeoAxis. i've been searching and trying for hours and im stuck. i have a cube-sphere made from 6 planes. i am deforming the planes using this code -
C# code aPlane.transform.aPoint(vertices[i]).normalized * this.radius + (randomFloat));
this gives me rather large gaps where my planes join. my question is, how can i separate between shared and non-shared vertices, adding the randomfloat to shared/non-edge vertices.
psedo code would be
C# code
Vector3[] vertices = mesh.vertices; //maybe add int[] tris = mesh.triangles? if (vertice is shared) add randomfloat; else deform without randomfloat;
im quite certain i need to create an array and add triangle vertices and check if the vertices belong to one triangle or two/more triangles.
Everything is generated from code and this is for a hobby project. i already have planet generators from the Asset store but if i use those i might as well just slap together Asset store content and put my name on it.
Answer by Eno-Khaon · Apr 11, 2016 at 09:17 AM
For reference, Unity's mesh optimization works by separating out numerous fields: vertices, normals, colors, tangents and uvs are all contained in arrays of equal size; there's one of each of those per vertex. Then, triangles are stored in an integer array in groups of three, with those integers acting as a guide for a corresponding vertex.
In the case of a cube shape, you'll likely have 12 triangles (2 per face, 6 faces). Beyond that, you have a choice to make with a model...
Because vertices and normals are shared 1:1, you can either have fewer vertices with rounded corners from interpolation between the normals or you can have more vertices with hard edges. Therefore, a 6-sided cube with rounded normals (to loosely resemble a sphere) would have as few as 8 vertices, a typical 24 vertices, or a maximum of 36 vertices, by having no duplicate vertices, individual faces in groups of 4, or individual triangles with 6 per face respectively.
That said, no matter the vertex count, you'll always have a 36-size array for triangles for a cube, in order to accommodate all 12 triangles.
With all of that in mind, it should be reasonably easy enough to determine which vertices share a location, but the triangle array can't help you here. Because you'll always have 36 triangle array entries on a cube, you can't tell the difference between any two variants of a cube. But if it looks like a cube and has hard edges, you can likely assume that two or more vertices share the same position.
Therefore, in order to manipulate their positions, you'll need to run through the array and find which vertices do share a position (i.e. v[x] == v[y]). Caching the results would likely involve an array of arrays (or a class/struct containing said array, etc.), due to the possibility of a variable array size per reused vertex position.
Once you've found matches, give them a collective normal by adding their normals together, then dividing by the number of vertices sharing the position (and normalize the result). Now, you have your new displacement normal to apply to each of those vertices shared at that position (which could also be applied to the same class/struct containing the array of vertices sharing a position).
By association, going back to another detail, this also means that any vertex in the mesh which doesn't share a position with another vertex is unique (barring extreme circumstances where the mesh has extraneous vertices with no connections). If a vertex is determined to have not shared a position with any other vertex, then you can generally assume that displacement of that vertex will not leave any holes (again, unless the mesh had construction problems in the first place).
I'm sorry about the poor formatting, I posted from a mobile phone.
I managed to get as far as using a class to store each vertex position, normals and uv data by creating a new instance of my custom class object. Beefore i got to comparing vertex values I got a suggestion from elsewhere to use a Noise function and get rid of my random float and the results were not so bad. To quote D$$anonymous$$Gregory from StackExchange, " Seed the noise lookup with the original position of your vertex. Since shared vertices have the same position, they'll get the same displacement, keeping them tightly joined."
For educational purposes, I am going to complete your suggested solution and report back my results.
That's certainly an option for an approach, as well. Using a structured pseudo-randomization (i.e. noise) will return reliable values based on input, so you would definitely see identical results for each vertex in matching positions.
Relying on that alone, however, would not account for the original objective of ai$$anonymous$$g for a combined set of normals for a reliable position offset. Unless you're strictly working from a basis of pushing vertices away from a defined center (basically, supporting only spherical shapes), it may be very challenging to find a scheme which can reliably simulate the same effect you would get from modifying vertex positions based on their normals.
Either way, a noise function would provide a very reliable and reproducible displacement with greater consistency and smoothness than pure randomization would offer, so that's certainly handy to make use of.