- Home /
How do I texture a Procedural Mesh based on its angle?
I have created a procedural terrain generator that can create height maps and make a mesh and apply that height map. The mesh is also textured based on the height. But what I want to do is kind of combine those, so really tall things will still be snowy, but steep ledges would have a cliff/stone texture. How could I find the angle and texture it based on that?
If you are wondering, I followed Sebastian Lague's procedural generation tutorial series.
Answer by Bunny83 · Dec 06, 2019 at 01:41 AM
Well when you talk about creating a mesh from a heightmap we probably talk about creating a subdivided quad mesh with a fix grid and you just adjust the height (y-value) of each vertex based on the heightmap value. So what we know is the given distance between two neighboring vertices in worldspace / localspace. The angle of an "edge" between two vertices is just
float angle = Mathf.ATan2(dy, dx) * Mathf.Rad2Deg;
note that "dy" is the absolute "delta" / difference in height between the two vertices (so simply Abs(y0 - y1)) and dx is the horizontal distance on your grid between two neighboring vertices.
This just calculate the angle of an "edge". Unfortunately it's kinda difficult to get a unique angle for the "surface" between 4 vertices. First of all it is relevant how the quad is actually triangulated. Just imagine a single quad (consisting of 2 triangles) which is completely flat. Now we just raise only one vertex. If the vertex is not part of the diagonal line through the quad we get one triangle sill being flat and one triangle with a raised corner. However if the raised vertex is one of the two vertices that are shared between the two triangles, both triangles will get raised. the first case creates a concave splitting edge, the second one a convex edge.
If you just need a rough approximation you could simply use calculate the average between all 4 edges that meet at a vertex to get a value per vertex or the average of the 4 edges that surround the quad to get a value for the quad. Instead of the average you can also use the max value (which might give a better / more stable result)