java - How to generate normals in GLSL -


i have created randomly generated terrain using simplex noise. code looks this:

      float [ ] vertices = new float [ size * size * 3 ];        short [ ] indices = new short [ ( size - 1 ) * ( size - 1 ) * 2 * 3 ];        ( int x = 0 , index = 0 ; x < size ; x ++ )       {          ( int z = 0 ; z < size ; z ++ )          {             vertices [ index ++ ] = x;             vertices [ index ++ ] = ( float ) simplexnoise.noise ( x , z );             vertices [ index ++ ] = z;          }       }        ( int = 0 , index = 0 ; < ( size - 1 ) ; ++ )       {          int offset = * size;           ( int j = 0 ; j < ( size - 1 ) ; j ++ )          {             indices [ index ++ ] = ( short ) ( j + offset );             indices [ index ++ ] = ( short ) ( j + offset + 1 );             indices [ index ++ ] = ( short ) ( j + offset + 1 + size );             indices [ index ++ ] = ( short ) ( j + offset + 1 + size );             indices [ index ++ ] = ( short ) ( j + offset + size );             indices [ index ++ ] = ( short ) ( j + offset );          }       } 

that gives me indices , vertices unless use gl_lines looks mob of color. can't continue progress on terrain until know looking @ way know how use normals load them in model , send them off shader. have no clue how generate them. have searched around , read lot getting normals of surrounding faces , normalizing them , other stuff didn't understand of , best of knowledge have access single vertex in vertex shader @ time not sure how process entire triangle. can see appreciated.

edit:

i have did research , have calculated normals of triangles:

      float [ ] trinormals = new float [ indices.length ];        ( int = 0 , index = 0 ; < indices.length ;  )       {          float x , y , z;           x = vertices [ ( 3 * indices [ ] ) ];          y = vertices [ ( 3 * indices [ ] ) + 1 ];          z = vertices [ ( 3 * indices [ ++ ] ) + 2 ];           vector3f p1 = new vector3f ( x , y , z );           x = vertices [ ( 3 * indices [ ] ) ];          y = vertices [ ( 3 * indices [ ] ) + 1 ];          z = vertices [ ( 3 * indices [ ++ ] ) + 2 ];           vector3f p2 = new vector3f ( x , y , z );           x = vertices [ ( 3 * indices [ ] ) ];          y = vertices [ ( 3 * indices [ ] ) + 1 ];          z = vertices [ ( 3 * indices [ ++ ] ) + 2 ];           vector3f p3 = new vector3f ( x , y , z );           vector3f u = vector3f.subtract ( p2 , p1 );          vector3f v = vector3f.subtract ( p3 , p1 );           vector3f normal = vector3f.crossproduct ( u , v );           trinormals [ index ++ ] = normal.x;          trinormals [ index ++ ] = normal.y;          trinormals [ index ++ ] = normal.z;       } 

now need know how calculate normals of vertices using normals of surrounding triangles.

generating per-triangle or face normals, flat , have sharp edges done normalizing cross product of 2 edges. @neuo says, done in geometry shader, sounds you're after "smooth" normals.

enter image description here

smooth normals not implicit vertex geometry, decent guess based off adjacent triangles (the average or weighted average of). unless have adjacency information (as in tessellation shaders (?)), isn't possible in glsl render. need done in separate pass (maybe using transform feedback) , easy process on cpu.

in gl, there 1 normal every vertex*. start new zeroed array equal vertices (or space between vertices if interleave). every triangle formed indices array (a, b, c), find triangle normal using cross product (b - a) × (c - a) , normalize it. add triangle normal per vertex normals of vertices of each triangle (i.e. a, b , c). run through every normal , normalize. done.

depending on mesh, simple method can work pretty well. in cases triangles small or skinny, equal weighting can cause strange results:

enter image description hereenter image description here

one approach fixing scale normal contribution each triangle area. this, don't normalize cross product result before add each normal.

for (int t = 0; t < numindices / 3; ++t) {     unsigned int t1 = dataindices[t*3+0];     unsigned int t2 = dataindices[t*3+1];     unsigned int t3 = dataindices[t*3+2];     const vec3f& = verts[t1];     const vec3f& b = verts[t2];     const vec3f& c = verts[t3];     vec3f u = b - a;     vec3f v = c - a;     vec3f n = u.cross(v);     //if (n.size() > 0.0) n.normalize(); //removes weighting based on triangle area     norms[t1] += n;     norms[t2] += n;     norms[t3] += n; } (int v = 0; v < numvertices; ++v)     norms[v].normalize(); 

src

* face normals you'd have duplicate vertices, why image drawn 2 red normals each vertex position. use keyword flat on in/out variables flat.


Comments

Popular posts from this blog

java - Static nested class instance -

c# - Bluetooth LE CanUpdate Characteristic property -

JavaScript - Replace variable from string in all occurrences -