فهرست منبع

Fix Blend Shapes when Octahedral Compression is Used

Blend shapes did not take into account octahedral compressed vertex
attribute layouts and this resulted in incorrect lighting on the
resulting blended mesh

Now make the blend_shapes shader octahedral compression aware!
Omar El Sheikh 3 سال پیش
والد
کامیت
50ed674ec2

+ 2 - 0
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -1268,6 +1268,8 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
 			if (s->blend_shapes.size() && e->instance->blend_values.size()) {
 				//blend shapes, use transform feedback
 				storage->mesh_render_blend_shapes(s, e->instance->blend_values.read().ptr());
+				//disable octahedral compression as the result of blend shapes is always uncompressed cartesian coordinates
+				state.scene_shader.set_conditional(SceneShaderGLES3::ENABLE_OCTAHEDRAL_COMPRESSION, false);
 				//rebind shader
 				state.scene_shader.bind();
 #ifdef DEBUG_ENABLED

+ 1 - 0
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -4300,6 +4300,7 @@ void RasterizerStorageGLES3::mesh_render_blend_shapes(Surface *s, const float *p
 
 	shaders.blend_shapes.set_conditional(BlendShapeShaderGLES3::ENABLE_BLEND, false); //first pass does not blend
 	shaders.blend_shapes.set_conditional(BlendShapeShaderGLES3::USE_2D_VERTEX, s->format & VS::ARRAY_FLAG_USE_2D_VERTICES); //use 2D vertices if needed
+	shaders.blend_shapes.set_conditional(BlendShapeShaderGLES3::ENABLE_OCTAHEDRAL_COMPRESSION, s->format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION); //use octahedral normal compression
 
 	shaders.blend_shapes.bind();
 

+ 35 - 2
drivers/gles3/shaders/blend_shape.glsl

@@ -25,11 +25,19 @@ ARRAY_INDEX=8,
 
 layout(location = 0) in highp VFORMAT vertex_attrib;
 /* clang-format on */
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+layout(location = 2) in vec4 normal_tangent_attrib;
+#else
 layout(location = 1) in vec3 normal_attrib;
+#endif
 
 #ifdef ENABLE_TANGENT
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+// packed into normal_attrib zw component
+#else
 layout(location = 2) in vec4 tangent_attrib;
 #endif
+#endif
 
 #ifdef ENABLE_COLOR
 layout(location = 3) in vec4 color_attrib;
@@ -109,20 +117,37 @@ out vec4 weight_out; //tfb:ENABLE_SKELETON
 
 uniform float blend_amount;
 
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+vec3 oct_to_vec3(vec2 e) {
+	vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
+	float t = max(-v.z, 0.0);
+	v.xy += t * -sign(v.xy);
+	return normalize(v);
+}
+#endif
+
 void main() {
 #ifdef ENABLE_BLEND
 
 	vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount;
 
 #ifdef ENABLE_NORMAL
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+	normal_out = normal_attrib_blend + oct_to_vec3(normal_tangent_attrib.xy) * blend_amount;
+#else
 	normal_out = normal_attrib_blend + normal_attrib * blend_amount;
 #endif
+#endif
 
 #ifdef ENABLE_TANGENT
-
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+	tangent_out.xyz = tangent_attrib_blend.xyz + oct_to_vec3(vec2(normal_tangent_attrib.z, abs(normal_tangent_attrib.w) * 2.0 - 1.0)) * blend_amount;
+	tangent_out.w = sign(tangent_attrib_blend.w);
+#else
 	tangent_out.xyz = tangent_attrib_blend.xyz + tangent_attrib.xyz * blend_amount;
 	tangent_out.w = tangent_attrib_blend.w; //just copy, no point in blending his
 #endif
+#endif
 
 #ifdef ENABLE_COLOR
 
@@ -150,14 +175,22 @@ void main() {
 	vertex_out = vertex_attrib * blend_amount;
 
 #ifdef ENABLE_NORMAL
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+	normal_out = oct_to_vec3(normal_tangent_attrib.xy) * blend_amount;
+#else
 	normal_out = normal_attrib * blend_amount;
 #endif
+#endif
 
 #ifdef ENABLE_TANGENT
-
+#ifdef ENABLE_OCTAHEDRAL_COMPRESSION
+	tangent_out.xyz = oct_to_vec3(vec2(normal_tangent_attrib.z, abs(normal_tangent_attrib.w) * 2.0 - 1.0)) * blend_amount;
+	tangent_out.w = sign(normal_tangent_attrib.w);
+#else
 	tangent_out.xyz = tangent_attrib.xyz * blend_amount;
 	tangent_out.w = tangent_attrib.w; //just copy, no point in blending his
 #endif
+#endif
 
 #ifdef ENABLE_COLOR