diff options
| author | clayjohn <claynjohn@gmail.com> | 2023-10-11 21:34:52 -0600 |
|---|---|---|
| committer | clayjohn <claynjohn@gmail.com> | 2023-10-13 08:54:49 -0600 |
| commit | e3d31837ebcc136f7b532e8ecfbbb8ee6eb665cc (patch) | |
| tree | 7a8a664a1027242db37e6c661a4aa566b0e7ebbc /scene | |
| parent | b1371806ad3907c009458ea939bd4b810f9deb21 (diff) | |
| download | redot-engine-e3d31837ebcc136f7b532e8ecfbbb8ee6eb665cc.tar.gz | |
Sanitize tangents when creating mesh surfaces to avoid triggering the compressed mesh path in the shader
Diffstat (limited to 'scene')
| -rw-r--r-- | scene/3d/sprite_3d.cpp | 5 | ||||
| -rw-r--r-- | scene/resources/immediate_mesh.cpp | 5 | ||||
| -rw-r--r-- | scene/resources/mesh.cpp | 10 |
3 files changed, 20 insertions, 0 deletions
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index e6404b5721..befabfe7b9 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -206,6 +206,11 @@ void SpriteBase3D::draw_texture_rect(Ref<Texture2D> p_texture, Rect2 p_dst_rect, uint32_t value = 0; value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535); value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16; + if (value == 4294901760) { + // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection. + // So we sanitize here. + value = 4294967295; + } v_tangent = value; } diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp index 0112ffd452..3507df8bd8 100644 --- a/scene/resources/immediate_mesh.cpp +++ b/scene/resources/immediate_mesh.cpp @@ -208,6 +208,11 @@ void ImmediateMesh::surface_end() { uint32_t value = 0; value |= (uint16_t)CLAMP(t.x * 65535, 0, 65535); value |= (uint16_t)CLAMP(t.y * 65535, 0, 65535) << 16; + if (value == 4294901760) { + // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection. + // So we sanitize here. + value = 4294967295; + } *tangent = value; } diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 971ec0e597..3aeec7ea87 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1156,6 +1156,11 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint64_t p_old_forma uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_normal_tangent_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); + if (dst[0] == 0 && dst[1] == 65535) { + // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection. + // So we sanitize here. + dst[0] = 65535; + } } src_offset += sizeof(uint8_t) * 4; } else { @@ -1167,6 +1172,11 @@ void _fix_array_compatibility(const Vector<uint8_t> &p_src, uint64_t p_old_forma uint16_t *dst = (uint16_t *)&dst_vertex_ptr[i * dst_normal_tangent_stride + dst_offsets[Mesh::ARRAY_NORMAL]]; dst[0] = (uint16_t)CLAMP(res.x * 65535, 0, 65535); dst[1] = (uint16_t)CLAMP(res.y * 65535, 0, 65535); + if (dst[0] == 0 && dst[1] == 65535) { + // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection. + // So we sanitize here. + dst[0] = 65535; + } } src_offset += sizeof(float) * 4; } |
