Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you think of each pixel as a vertex rather than a face, you can generate a simple triangular mesh.</p> <pre><code>+--+--+ |\ |\ | | \| \| +--+--+ |\ |\ | | \| \| +--+--+ </code></pre> <p>Each vertex has an x and y coordinate corresponding to the x and y of the pixel in the map. The z coordinate is based on the value in the map at that location. Triangles can be generated explicitly or implicitly by their position in the grid.</p> <p>What you need is the normal <em>at each vertex</em>.</p> <p>A <em>vertex</em> normal can be computed by taking an area-weighted average of the <em>surface</em> normals for each of the triangles that meet at that point.</p> <p>If you have a triangle with vertices <code>v0</code>, <code>v1</code>, <code>v2</code>, then you can use a vector cross product (of two vectors that lie on two of the sides of the triangle) to compute a vector in the direction of the normal and scaled proportionally to the area of the triangle.</p> <pre><code>Vector3 contribution = Cross(v1 - v0, v2 - v1); </code></pre> <p>Each of your vertices that aren't on the edge will be shared by six triangles. You can loop through those triangles, summing up the <code>contribution</code>s, and then normalize the vector sum.</p> <p><strong>Note:</strong> You have to compute the cross products in a consistent way to make sure the normals are all pointing in the same direction. Always pick two sides in the same order (clockwise or counterclockwise). If you mix some of them up, those contributions will be pointing in the opposite direction.</p> <p>For vertices on the edge, you end up with a shorter loop and a lot of special cases. It's probably easier to create a border around your grid of fake vertices and then compute the normals for the interior ones and discard the fake borders.</p> <pre><code>for each interior vertex V { Vector3 sum(0.0, 0.0, 0.0); for each of the six triangles T that share V { const Vector3 side1 = T.v1 - T.v0; const Vector3 side2 = T.v2 - T.v1; const Vector3 contribution = Cross(side1, side2); sum += contribution; } sum.Normalize(); V.normal = sum; } </code></pre> <p>If you need the normal at a particular point on a triangle (other than one of the vertices), you can interpolate by weighing the normals of the three vertices by the barycentric coordinates of your point. This is how graphics rasterizers treat the normal for shading. It allows a triangle mesh to appear like smooth, curved surface rather than a bunch of adjacent flat triangles.</p> <p><strong>Tip:</strong> For your first test, use a perfectly flat grid and make sure all of the computed normals are pointing straight up.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload