From c8cf71753c4f971c25924addbfe79356e7d2ec4e Mon Sep 17 00:00:00 2001 From: JFonS Date: Thu, 21 Jun 2018 00:12:12 +0200 Subject: [PATCH] Add render mode to ensure correct normals when using non-uniform scaling --- drivers/gles3/shader_compiler_gles3.cpp | 1 + drivers/gles3/shaders/scene.glsl | 12 ++++++++++++ scene/resources/material.cpp | 5 +++++ scene/resources/material.h | 3 ++- servers/visual/shader_types.cpp | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index eb8d6c485b3..9ad16ac2a21 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -898,6 +898,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index f5481c597cf..132e988a5a6 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -322,7 +322,13 @@ void main() { #if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) vertex = world_matrix * vertex; + +#if defined(ENSURE_CORRECT_NORMALS) + mat3 normal_matrix = mat3(transpose(inverse(world_matrix))); + normal = normal_matrix * normal; +#else normal = normalize((world_matrix * vec4(normal,0.0)).xyz); +#endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) @@ -394,7 +400,13 @@ VERTEX_SHADER_CODE #if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED) vertex = modelview * vertex; + +#if defined(ENSURE_CORRECT_NORMALS) + mat3 normal_matrix = mat3(transpose(inverse(modelview))); + normal = normal_matrix * normal; +#else normal = normalize((modelview * vec4(normal,0.0)).xyz); +#endif #if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY) diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 5e7569586af..654d7b884e9 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -393,6 +393,9 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_DONT_RECEIVE_SHADOWS]) { code += ",shadows_disabled"; } + if (flags[FLAG_ENSURE_CORRECT_NORMALS]) { + code += ",ensure_correct_normals"; + } code += ";\n"; code += "uniform vec4 albedo : hint_color;\n"; @@ -1852,6 +1855,7 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_do_not_receive_shadows"), "set_flag", "get_flag", FLAG_DONT_RECEIVE_SHADOWS); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_ensure_correct_normals"), "set_flag", "get_flag", FLAG_ENSURE_CORRECT_NORMALS); ADD_GROUP("Vertex Color", "vertex_color"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR); @@ -2042,6 +2046,7 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD); BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB); BIND_ENUM_CONSTANT(FLAG_DONT_RECEIVE_SHADOWS); + BIND_ENUM_CONSTANT(FLAG_ENSURE_CORRECT_NORMALS); BIND_ENUM_CONSTANT(FLAG_MAX); BIND_ENUM_CONSTANT(DIFFUSE_BURLEY); diff --git a/scene/resources/material.h b/scene/resources/material.h index ce733bfb8d9..87594213bcf 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -189,6 +189,7 @@ public: FLAG_USE_ALPHA_SCISSOR, FLAG_ALBEDO_TEXTURE_FORCE_SRGB, FLAG_DONT_RECEIVE_SHADOWS, + FLAG_ENSURE_CORRECT_NORMALS, FLAG_MAX }; @@ -237,7 +238,7 @@ private: uint64_t blend_mode : 2; uint64_t depth_draw_mode : 2; uint64_t cull_mode : 2; - uint64_t flags : 15; + uint64_t flags : 16; uint64_t detail_blend_mode : 2; uint64_t diffuse_mode : 3; uint64_t specular_mode : 2; diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index 95193f7a8f2..a92e1b06d26 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -172,6 +172,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_vertex_transform"); shader_modes[VS::SHADER_SPATIAL].modes.insert("world_vertex_coords"); + shader_modes[VS::SHADER_SPATIAL].modes.insert("ensure_correct_normals"); shader_modes[VS::SHADER_SPATIAL].modes.insert("shadows_disabled");