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
Show file tree
Hide file tree
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
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions core/math/vector3.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
22 changes: 15 additions & 7 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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

Expand Down
17 changes: 8 additions & 9 deletions drivers/gles3/storage/mesh_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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: {
Expand Down
6 changes: 3 additions & 3 deletions scene/3d/soft_dynamic_body_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
clayjohn marked this conversation as resolved.
Show resolved Hide resolved
value |= (uint16_t)CLAMP(res.y * 65535, 0, 65535) << 16;
memcpy(&write_buffer[p_vertex_id * stride + offset_normal], &value, sizeof(uint32_t));
}

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

Expand Down Expand Up @@ -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;
}

Expand Down
Loading