diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index ae55ff068378..2693fb9c44f0 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/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 diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 586eb7f39697..98d021d9398a 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/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(); diff --git a/drivers/gles3/shaders/blend_shape.glsl b/drivers/gles3/shaders/blend_shape.glsl index da6dec167687..2a0aa6a06d20 100644 --- a/drivers/gles3/shaders/blend_shape.glsl +++ b/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