uniform int enable_normals; uniform int enable_tangents; uniform int enable_bitangents; uniform int enable_wireframe; uniform int enable_triangle_normals; layout(triangles) in; layout(line_strip, max_vertices = 24) out; in vec3 o_normal[]; in vec3 o_tangent[]; in vec3 o_bitangent[]; flat out vec4 o_color; void main() { if (enable_normals == 0 && enable_tangents == 0 && enable_bitangents == 0 && enable_wireframe == 0 && enable_triangle_normals == 0) { return; } // colors for different type of new lines vec4 edge_color = vec4(0.2, 0.1, 0.1, 1.0); vec4 face_normal_color = vec4(0.5, 0.7, 0.2, 1.0); vec4 normal_color = vec4(0.0, 1.0, 0.2, 1.0); vec4 tangent_color = vec4(1.0, 0.3, 0.2, 1.0); vec4 bitangent_color = vec4(0.0, 0.1, 1.0, 1.0); // form two vectors from triangle vec3 V0 = gl_in[0].gl_Position.xyz - gl_in[1].gl_Position.xyz; vec3 V1 = gl_in[2].gl_Position.xyz - gl_in[1].gl_Position.xyz; // calculate normal as perpendicular to two vectors of the triangle vec3 V0_V1_crossed = cross(V1, V0); float normal_scale = min(length(V0_V1_crossed) * 10.0, 0.25); vec3 N = normalize(V0_V1_crossed); // normals of each vertex of the triangle vec3 nor[3]; nor[0] = o_normal[0].xyz; nor[1] = o_normal[1].xyz; nor[2] = o_normal[2].xyz; // positions of each vertex of the triangle // shifted a bit along normal // so there won't be Z fighting when rendered over the mesh vec4 pos[3]; pos[0] = u_projection_view_matrix * vec4(gl_in[0].gl_Position.xyz + nor[0] * 0.01, 1.0); pos[1] = u_projection_view_matrix * vec4(gl_in[1].gl_Position.xyz + nor[1] * 0.01, 1.0); pos[2] = u_projection_view_matrix * vec4(gl_in[2].gl_Position.xyz + nor[2] * 0.01, 1.0); // output normals, tangents and bitangents for each vertex of the triangle for (int i=0; i < gl_in.length(); i++) { // get position of the vertex vec3 P = gl_in[i].gl_Position.xyz; if (enable_normals > 0) { // create normal for vertex o_color = normal_color; gl_Position = pos[i]; EmitVertex(); gl_Position = u_projection_view_matrix * vec4(P + o_normal[i].xyz * normal_scale, 1.0); EmitVertex(); EndPrimitive(); } if (enable_tangents > 0) { // create tangent for vertex o_color = tangent_color; gl_Position = pos[i]; EmitVertex(); gl_Position = u_projection_view_matrix * vec4(P + o_tangent[i].xyz * normal_scale, 1.0); EmitVertex(); EndPrimitive(); } if (enable_bitangents > 0) { // create bitangent for vertex o_color = bitangent_color; gl_Position = pos[i]; EmitVertex(); gl_Position = u_projection_view_matrix * vec4(P + o_bitangent[i].xyz * normal_scale, 1.0); EmitVertex(); EndPrimitive(); } } if (enable_wireframe > 0) { // create edges for triangle o_color = edge_color; gl_Position = pos[0]; EmitVertex(); gl_Position = pos[1]; EmitVertex(); gl_Position = pos[2]; EmitVertex(); gl_Position = pos[0]; EmitVertex(); // end line strip after four added vertices, so we will get three lines EndPrimitive(); } if (enable_triangle_normals > 0) { // create normal for triangle o_color = face_normal_color; // position as arithmetic average vec3 P = (gl_in[0].gl_Position.xyz + gl_in[1].gl_Position.xyz + gl_in[2].gl_Position.xyz) / 3.0; gl_Position = u_projection_view_matrix * vec4(P, 1.0); EmitVertex(); gl_Position = u_projection_view_matrix * vec4(P + N * normal_scale, 1.0); EmitVertex(); EndPrimitive(); } }