Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Octahedral Normal/Tangent Compression #60309

Merged
merged 4 commits into from
Aug 22, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions core/math/vector3.cpp
Original file line number Diff line number Diff line change
@@ -117,6 +117,22 @@ Vector3 Vector3::octahedron_decode(const Vector2 &p_oct) {
return n.normalized();
}

Vector2 Vector3::octahedron_tangent_encode(const float sign) const {
Vector2 res = this->octahedron_encode();
res.y = res.y * 0.5f + 0.5f;
res.y = sign >= 0.0f ? res.y : 1 - res.y;
return res;
}

Vector3 Vector3::octahedron_tangent_decode(const Vector2 &p_oct, float *sign) {
Vector2 oct_compressed = p_oct;
oct_compressed.y = oct_compressed.y * 2 - 1;
*sign = oct_compressed.y >= 0.0f ? 1.0f : -1.0f;
oct_compressed.y = Math::abs(oct_compressed.y);
Vector3 res = Vector3::octahedron_decode(oct_compressed);
return res;
}

Basis Vector3::outer(const Vector3 &p_with) const {
Vector3 row0(x * p_with.x, x * p_with.y, x * p_with.z);
Vector3 row1(y * p_with.x, y * p_with.y, y * p_with.z);
2 changes: 2 additions & 0 deletions core/math/vector3.h
Original file line number Diff line number Diff line change
@@ -111,6 +111,8 @@ struct _NO_DISCARD_ Vector3 {

Vector2 octahedron_encode() const;
static Vector3 octahedron_decode(const Vector2 &p_oct);
Vector2 octahedron_tangent_encode(const float sign) const;
static Vector3 octahedron_tangent_decode(const Vector2 &p_oct, float *sign);

_FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const;
_FORCE_INLINE_ real_t dot(const Vector3 &p_with) const;
22 changes: 15 additions & 7 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
@@ -35,8 +35,8 @@ USE_RADIANCE_MAP = true
/*
from RenderingServer:
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_NORMAL = 1, // RG16 octahedral compression
ARRAY_TANGENT = 2, // RG16 octahedral compression, sign stored in sign of G
ARRAY_COLOR = 3, // RGBA8
ARRAY_TEX_UV = 4, // RG32F
ARRAY_TEX_UV2 = 5, // RG32F
@@ -54,11 +54,11 @@ layout(location = 0) in highp vec3 vertex_attrib;
/* clang-format on */

#ifdef NORMAL_USED
layout(location = 1) in vec3 normal_attrib;
layout(location = 1) in vec2 normal_attrib;
#endif

#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 2) in vec4 tangent_attrib;
layout(location = 2) in vec2 tangent_attrib;
#endif

#if defined(COLOR_USED)
@@ -97,6 +97,13 @@ layout(location = 10) in uvec4 bone_attrib;
layout(location = 11) in vec4 weight_attrib;
#endif

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 v;
}

#ifdef USE_INSTANCING
layout(location = 12) in highp vec4 instance_xform0;
layout(location = 13) in highp vec4 instance_xform1;
@@ -209,13 +216,14 @@ void main() {
#endif

#ifdef NORMAL_USED
vec3 normal = normal_attrib * 2.0 - 1.0;
vec3 normal = oct_to_vec3(normal_attrib * 2.0 - 1.0);
#endif
highp mat3 model_normal_matrix = mat3(model_matrix);

#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
vec3 tangent = tangent_attrib.xyz * 2.0 - 1.0;
float binormalf = tangent_attrib.a * 2.0 - 1.0;
vec2 signed_tangent_attrib = tangent_attrib * 2.0 - 1.0;
vec3 tangent = oct_to_vec3(vec2(signed_tangent_attrib.x, abs(signed_tangent_attrib.y) * 2.0 - 1.0));
float binormalf = sign(signed_tangent_attrib.y);
vec3 binormal = normalize(cross(normal, tangent) * binormalf);
#endif

17 changes: 8 additions & 9 deletions drivers/gles3/storage/mesh_storage.cpp
Original file line number Diff line number Diff line change
@@ -124,11 +124,11 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)

} break;
case RS::ARRAY_NORMAL: {
stride += sizeof(int32_t);
stride += sizeof(uint16_t) * 2;

} break;
case RS::ARRAY_TANGENT: {
stride += sizeof(int32_t);
stride += sizeof(uint16_t) * 2;

} break;
case RS::ARRAY_COLOR: {
@@ -595,17 +595,16 @@ void MeshStorage::_mesh_surface_generate_version_for_input_mask(Mesh::Surface::V
} break;
case RS::ARRAY_NORMAL: {
attribs[i].offset = vertex_stride;
// Will need to change to accommodate octahedral compression
attribs[i].size = 4;
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
vertex_stride += sizeof(float);
attribs[i].size = 2;
attribs[i].type = GL_UNSIGNED_SHORT;
vertex_stride += sizeof(uint16_t) * 2;
attribs[i].normalized = GL_TRUE;
} break;
case RS::ARRAY_TANGENT: {
attribs[i].offset = vertex_stride;
attribs[i].size = 4;
attribs[i].type = GL_UNSIGNED_INT_2_10_10_10_REV;
vertex_stride += sizeof(float);
attribs[i].size = 2;
attribs[i].type = GL_UNSIGNED_SHORT;
vertex_stride += sizeof(uint16_t) * 2;
attribs[i].normalized = GL_TRUE;
} break;
case RS::ARRAY_COLOR: {
6 changes: 3 additions & 3 deletions scene/3d/soft_dynamic_body_3d.cpp
Original file line number Diff line number Diff line change
@@ -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));
}

31 changes: 13 additions & 18 deletions scene/3d/sprite_3d.cpp
Original file line number Diff line number Diff line change
@@ -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;
}

Loading