summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclayjohn <claynjohn@gmail.com>2023-10-11 21:34:52 -0600
committerclayjohn <claynjohn@gmail.com>2023-10-13 08:54:49 -0600
commite3d31837ebcc136f7b532e8ecfbbb8ee6eb665cc (patch)
tree7a8a664a1027242db37e6c661a4aa566b0e7ebbc
parentb1371806ad3907c009458ea939bd4b810f9deb21 (diff)
downloadredot-engine-e3d31837ebcc136f7b532e8ecfbbb8ee6eb665cc.tar.gz
Sanitize tangents when creating mesh surfaces to avoid triggering the compressed mesh path in the shader
-rw-r--r--scene/3d/sprite_3d.cpp5
-rw-r--r--scene/resources/immediate_mesh.cpp5
-rw-r--r--scene/resources/mesh.cpp10
-rw-r--r--servers/rendering_server.cpp12
4 files changed, 32 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;
}
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index c5adb6cdf6..0ecfb6afb7 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -612,6 +612,12 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint
(uint16_t)CLAMP(res.y * 65535, 0, 65535),
};
+ if (vector[0] == 0 && vector[1] == 65535) {
+ // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection.
+ // So we sanitize here.
+ vector[0] = 65535;
+ }
+
memcpy(&vw[p_offsets[ai] + i * p_normal_stride], vector, 4);
}
} else { // PACKED_FLOAT64_ARRAY
@@ -627,6 +633,12 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint
(uint16_t)CLAMP(res.y * 65535, 0, 65535),
};
+ if (vector[0] == 0 && vector[1] == 65535) {
+ // (1, 1) and (0, 1) decode to the same value, but (0, 1) messes with our compression detection.
+ // So we sanitize here.
+ vector[0] = 65535;
+ }
+
memcpy(&vw[p_offsets[ai] + i * p_normal_stride], vector, 4);
}
}