Browse Source

Octahedral Normal Support for Sprite and Soft Body

Properly encode the normal and tangent vectors with octahedral
compression
Omar El Sheikh 3 years ago
parent
commit
2425d798cd
2 changed files with 16 additions and 21 deletions
  1. 3 3
      scene/3d/soft_dynamic_body_3d.cpp
  2. 13 18
      scene/3d/sprite_3d.cpp

+ 3 - 3
scene/3d/soft_dynamic_body_3d.cpp

@@ -88,10 +88,10 @@ void SoftDynamicBodyRenderingServerHandler::set_normal(int p_vertex_id, const vo
 	memcpy(&n, p_vector3, sizeof(Vector3));
 	n *= Vector3(0.5, 0.5, 0.5);
 	n += Vector3(0.5, 0.5, 0.5);
+	Vector2 res = n.octahedron_encode();
 	uint32_t value = 0;
-	value |= CLAMP(int(n.x * 1023.0), 0, 1023);
-	value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
-	value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
+	value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+	value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
 	memcpy(&write_buffer[p_vertex_id * stride + offset_normal], &value, sizeof(uint32_t));
 }
 

+ 13 - 18
scene/3d/sprite_3d.cpp

@@ -562,23 +562,21 @@ void Sprite3D::_draw() {
 	{
 		Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
 
+		Vector2 res = n.octahedron_encode();
 		uint32_t value = 0;
-		value |= CLAMP(int(n.x * 1023.0), 0, 1023);
-		value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
-		value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
+		value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+		value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
 
 		v_normal = value;
 	}
 	uint32_t v_tangent;
 	{
 		Plane t = tangent;
+		Vector2 res = t.normal.octahedron_tangent_encode(t.d);
 		uint32_t value = 0;
-		value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023);
-		value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
-		value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
-		if (t.d > 0) {
-			value |= 3UL << 30;
-		}
+		value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+		value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
+
 		v_tangent = value;
 	}
 
@@ -929,23 +927,20 @@ void AnimatedSprite3D::_draw() {
 	{
 		Vector3 n = normal * Vector3(0.5, 0.5, 0.5) + Vector3(0.5, 0.5, 0.5);
 
+		Vector2 res = n.octahedron_encode();
 		uint32_t value = 0;
-		value |= CLAMP(int(n.x * 1023.0), 0, 1023);
-		value |= CLAMP(int(n.y * 1023.0), 0, 1023) << 10;
-		value |= CLAMP(int(n.z * 1023.0), 0, 1023) << 20;
+		value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+		value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
 
 		v_normal = value;
 	}
 	uint32_t v_tangent;
 	{
 		Plane t = tangent;
+		Vector2 res = t.normal.octahedron_tangent_encode(t.d);
 		uint32_t value = 0;
-		value |= CLAMP(int((t.normal.x * 0.5 + 0.5) * 1023.0), 0, 1023);
-		value |= CLAMP(int((t.normal.y * 0.5 + 0.5) * 1023.0), 0, 1023) << 10;
-		value |= CLAMP(int((t.normal.z * 0.5 + 0.5) * 1023.0), 0, 1023) << 20;
-		if (t.d > 0) {
-			value |= 3UL << 30;
-		}
+		value |= (uint16_t)CLAMP(res.x * 65535, 0, 65535);
+		value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
 		v_tangent = value;
 	}