From 891b05335801cc101d6c5ec5bad4af93f85a9ac8 Mon Sep 17 00:00:00 2001 From: Benau Date: Wed, 27 Dec 2017 01:33:21 +0800 Subject: [PATCH] Add more functions to normal visualizer --- data/shaders/glow_object.frag | 8 -- data/shaders/sp_normal_visualizer.frag | 8 ++ data/shaders/sp_normal_visualizer.geom | 100 ++++++++++++++++++++++--- data/shaders/sp_normal_visualizer.vert | 32 +++++--- src/graphics/sp/sp_base.cpp | 11 +-- 5 files changed, 127 insertions(+), 32 deletions(-) delete mode 100644 data/shaders/glow_object.frag create mode 100644 data/shaders/sp_normal_visualizer.frag diff --git a/data/shaders/glow_object.frag b/data/shaders/glow_object.frag deleted file mode 100644 index 5f8222e95..000000000 --- a/data/shaders/glow_object.frag +++ /dev/null @@ -1,8 +0,0 @@ -flat in vec4 glowColor; - -out vec4 FragColor; - -void main() -{ - FragColor = vec4(glowColor.bgr, 1.0); -} diff --git a/data/shaders/sp_normal_visualizer.frag b/data/shaders/sp_normal_visualizer.frag new file mode 100644 index 000000000..42be5b003 --- /dev/null +++ b/data/shaders/sp_normal_visualizer.frag @@ -0,0 +1,8 @@ +in vec4 o_color; + +out vec4 o_frag_color; + +void main() +{ + o_frag_color = o_color; +} diff --git a/data/shaders/sp_normal_visualizer.geom b/data/shaders/sp_normal_visualizer.geom index 23e11ba21..21f6b32ec 100644 --- a/data/shaders/sp_normal_visualizer.geom +++ b/data/shaders/sp_normal_visualizer.geom @@ -1,22 +1,102 @@ layout(triangles) in; -layout(line_strip, max_vertices = 6) out; +layout(line_strip, max_vertices = 24) out; -in vec3 normal[]; +in vec3 o_normal[]; +in vec3 o_tangent[]; +in vec3 o_bitangent[]; + +flat out vec4 o_color; void main() { - for (int i = 0; i < gl_in.length(); i++) + // 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 = clamp(length(V0_V1_crossed) * 10.0, 0.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++) { - vec4 pos = gl_in[i].gl_Position; - gl_Position = pos; - EmitVertex(); + // get position of the vertex + vec3 P = gl_in[i].gl_Position.xyz; - pos = inverse(u_projection_matrix) * pos; - pos /= pos.w; - gl_Position = u_projection_matrix * - (pos + 0.2 * vec4(normalize(normal[i]), 0.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(); + // 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(); + + // 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(); } + + // 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(); + + // 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(); } diff --git a/data/shaders/sp_normal_visualizer.vert b/data/shaders/sp_normal_visualizer.vert index 6300e8138..e3dc2a278 100644 --- a/data/shaders/sp_normal_visualizer.vert +++ b/data/shaders/sp_normal_visualizer.vert @@ -8,6 +8,12 @@ layout(location = 1) in int i_normal_pked; layout(location = 1) in vec4 i_normal; #endif +#if defined(Converts_10bit_Vector) +layout(location = 5) in int i_tangent_pked; +#else +layout(location = 5) in vec4 i_tangent; +#endif + layout(location = 6) in ivec4 i_joint; layout(location = 7) in vec4 i_weight; layout(location = 8) in vec3 i_origin; @@ -23,21 +29,25 @@ layout(location = 12) in ivec2 i_misc_data_two; #stk_include "utils/get_world_location.vert" -out vec2 uv; -out vec3 normal; +out vec3 o_tangent; +out vec3 o_bitangent; +out vec3 o_normal; void main() { #if defined(Converts_10bit_Vector) vec4 i_normal = convert10BitVector(i_normal_pked); + vec4 i_tangent = convert10BitVector(i_tangent_pked); vec4 i_rotation = convert10BitVector(i_rotation_pked); #endif vec4 idle_position = vec4(i_position, 1.0); vec4 idle_normal = vec4(i_normal.xyz, 0.0); + vec4 idle_tangent = vec4(i_tangent.xyz, 0.0); vec4 skinned_position = vec4(0.0); vec4 skinned_normal = vec4(0.0); + vec4 skinned_tangent = vec4(0.0); int skinning_offset = i_misc_data_two.x; for (int i = 0; i < 4; i++) @@ -53,15 +63,19 @@ void main() clamp(i_joint[i] + skinning_offset, 0, MAX_BONES) * 4 + 3)); skinned_position += i_weight[i] * joint_matrix * idle_position; skinned_normal += i_weight[i] * joint_matrix * idle_normal; + skinned_tangent += i_weight[i] * joint_matrix * idle_tangent; } - float step_mix = step(float(skinning_offset), -32769.0); - skinned_position = mix(idle_position, skinned_position, step_mix); - skinned_normal = mix(idle_normal, skinned_normal, step_mix); + float step_mix = step(float(skinning_offset), 0.0); + skinned_position = mix(skinned_position, idle_position, step_mix); + skinned_normal = mix(skinned_normal, idle_normal, step_mix); + skinned_tangent = mix(skinned_tangent, idle_tangent, step_mix); + vec4 quaternion = normalize(vec4(i_rotation.xyz, i_scale.w)); - vec4 world_position = getWorldPosition(i_origin, i_rotation, i_scale.xyz, + gl_Position = getWorldPosition(i_origin, quaternion, i_scale.xyz, skinned_position.xyz); - vec3 world_normal = rotateVector(i_rotation, skinned_normal.xyz); - normal = (u_view_matrix * vec4(world_normal, 0.0)).xyz; - gl_Position = u_projection_view_matrix * world_position; + o_normal = normalize(rotateVector(quaternion, skinned_normal.xyz)); + o_tangent = normalize(rotateVector(quaternion, skinned_tangent.xyz)); + o_bitangent = cross(o_normal, o_tangent) * i_tangent.w; + } diff --git a/src/graphics/sp/sp_base.cpp b/src/graphics/sp/sp_base.cpp index ec26eaa33..702821e40 100644 --- a/src/graphics/sp/sp_base.cpp +++ b/src/graphics/sp/sp_base.cpp @@ -784,12 +784,12 @@ void loadShaders() RP_1ST); shader->addShaderFile("sp_normal_visualizer.geom", GL_GEOMETRY_SHADER, RP_1ST); - shader->addShaderFile("colorize.frag", GL_FRAGMENT_SHADER, RP_1ST); + shader->addShaderFile("sp_normal_visualizer.frag", GL_FRAGMENT_SHADER, + RP_1ST); shader->linkShaderFiles(RP_1ST); shader->use(RP_1ST); shader->addBasicUniforms(RP_1ST); shader->addAllTextures(RP_1ST); - shader->addUniform("col", typeid(irr::video::SColorf), RP_1ST); addShader(shader); } #endif @@ -1505,11 +1505,12 @@ void drawNormal() { #ifndef SERVER_ONLY SPShader* nv = getSPShader("sp_normal_visualizer"); + if (nv == NULL) + { + return; + } nv->use(); nv->bindPrefilledTextures(); - SPUniformAssigner* normal_color_assigner = nv->getUniformAssigner("col"); - assert(normal_color_assigner != NULL); - normal_color_assigner->setValue(video::SColorf(0.2f, 0.7f, 0.0f)); for (unsigned i = 0; i < g_final_draw_calls[0].size(); i++) { auto& p = g_final_draw_calls[0][i];