opengl - Faulty geometry shaders to visualise normals -
somehing wrong visualising normals.
as can see in video, normals faulty , seem move. duck , sphere loaded .dea files (with assimp) , hard coded cube myself.
here shaders:
vertex shader:
#version 430 layout(location = 0) in vec3 inpos; layout(location = 1) in vec3 innormal; out vec4 vertex_normal; void main(void) { gl_position = vec4(inpos, 1.0); vertex_normal = vec4(innormal, 1.0f); }
geometry shader:
#version 430 layout(triangles) in; layout(line_strip, max_vertices = 6) out; uniform mat4 projectionmatrix; uniform mat4 viewmatrix; uniform mat4 modelmatrix; uniform mat4 normalmatix; in vec4 vertex_normal[3]; out vec4 outcolor; void main(void) { //the "normalviewprojection" matrix normals mat4 nvp = projectionmatrix * viewmatrix * normalmatix; //the modelviewprojection matrix vertices mat4 mvp = projectionmatrix * viewmatrix * modelmatrix; //normals transformed screen space const vec4 normals[] = { normalize(nvp * vertex_normal[0]), normalize(nvp * vertex_normal[0]), normalize(nvp * vertex_normal[0]), }; const float normallength = 1.2f; //gl_in.length() = 3, since working triangles for(int = 0; < gl_in.length(); i++) { outcolor = normals[i]; const vec4 position = mvp * gl_in[i].gl_position; //first vertex gl_position = position; emitvertex(); //second vertex gl_position = position + normals[i] * normallength; emitvertex(); //send line fragment shader endprimitive(); } }
fragment shader:
#version 430 layout(location = 0) out vec4 fragcolor; in vec4 outcolor; void main(void) { fragcolor = vec4(outcolor.xyz, 1.0f); }
i have tried multiple tutorials. tutorial1 tutorial2 , few more out results.
one has distinguish between 2 different types of vectors here:
- position vectors, describe position in 3d space. example vertices, and
- direction vectors, describe direction, not position. normals example such direction vectors.
projections gives correct results position vectors not direction vectors. , problem in code lies: treating normals (directions) positions.
in opinion, correct code has somehow this:
... for(int = 0; < gl_in.length(); i++) { const vec4 position = mvp * gl_in[i].gl_position; //first vertex gl_position = position; emitvertex(); //second vertex const vec4 position2 = mvp * vec4(gl_in[i].gl_position.xyz + vertex_normal[i].xyz, 1.0); gl_position = position2; emitvertex(); } ...
here position of tip of normal first calculated in model space (gl_in[i].gl_position.xyz + vertex_normal[i].xyz
) , projected.
edit: when using scalings in model matrix , want have normals @ same lenght, might have transform normals , positions world space before adding:
mat4 vp = projectionmatrix * viewmatrix; ... for(int = 0; < gl_in.length(); i++) { const vec4 position_ws = modelmatrix * gl_in[i].gl_position; //first vertex gl_position = vp * position_ws; emitvertex(); //second vertex const vec4 normal_ws = normalize(normalmatrix * vertex_normal[i]); gl_position = vp * vec4(position_ws.xyz + normal_ws.xyz, 1.0); emitvertex(); } ...
Comments
Post a Comment