Merge pull request #58838 from The-O-King/gles2_blend_shapes_oct

GLES2 Compression on Blend Shapes Fix
This commit is contained in:
Rémi Verschelde 2022-03-06 22:35:08 +01:00 committed by GitHub
commit d93a4a8885
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 124 additions and 34 deletions

View File

@ -1480,7 +1480,21 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
if (!s->blend_shape_data.empty() && i != VS::ARRAY_BONES && s->blend_shape_buffer_size > 0) {
glBindBuffer(GL_ARRAY_BUFFER, s->blend_shape_buffer_id);
glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, GL_FLOAT, GL_FALSE, 8 * 4 * sizeof(float), CAST_INT_TO_UCHAR_PTR(i * 4 * sizeof(float)));
// When using octahedral compression (2 component normal/tangent)
// decompression changes the component count to 3/4
int size;
switch (i) {
case VS::ARRAY_NORMAL: {
size = 3;
} break;
case VS::ARRAY_TANGENT: {
size = 4;
} break;
default:
size = s->attribs[i].size;
}
glVertexAttribPointer(s->attribs[i].index, size, GL_FLOAT, GL_FALSE, 8 * 4 * sizeof(float), CAST_INT_TO_UCHAR_PTR(i * 4 * sizeof(float)));
} else {
glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id);
@ -2508,7 +2522,9 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_conditional(SceneShaderGLES2::USE_PHYSICAL_LIGHT_ATTENUATION, storage->config.use_physical_light_attenuation);
bool octahedral_compression = e->instance->base_type != VS::INSTANCE_IMMEDIATE && ((RasterizerStorageGLES2::Surface *)e->geometry)->format & VisualServer::ArrayFormat::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION;
bool octahedral_compression = e->instance->base_type != VS::INSTANCE_IMMEDIATE &&
((RasterizerStorageGLES2::Surface *)e->geometry)->format & VisualServer::ArrayFormat::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION &&
(((RasterizerStorageGLES2::Surface *)e->geometry)->blend_shape_data.empty() || ((RasterizerStorageGLES2::Surface *)e->geometry)->blend_shape_buffer_size == 0);
if (octahedral_compression != prev_octahedral_compression) {
state.scene_shader.set_conditional(SceneShaderGLES2::ENABLE_OCTAHEDRAL_COMPRESSION, octahedral_compression);
rebind = true;

View File

@ -3797,6 +3797,7 @@ void RasterizerStorageGLES2::update_dirty_blend_shapes() {
wr[0] = Math::halfptr_to_float(&((uint16_t *)rd)[0]) * base_weight;
wr[1] = Math::halfptr_to_float(&((uint16_t *)rd)[1]) * base_weight;
wr[2] = Math::halfptr_to_float(&((uint16_t *)rd)[2]) * base_weight;
wr[3] = 1.0f;
} else {
float a[3] = { 0 };
a[0] = wr[0] = rd[0] * base_weight;
@ -3806,27 +3807,63 @@ void RasterizerStorageGLES2::update_dirty_blend_shapes() {
}
} break;
case VS::ARRAY_NORMAL: {
if (s->format & VS::ARRAY_COMPRESS_NORMAL) {
wr[0] = (((int8_t *)rd)[0] / 127.0) * base_weight;
wr[1] = (((int8_t *)rd)[1] / 127.0) * base_weight;
wr[2] = (((int8_t *)rd)[2] / 127.0) * base_weight;
if (s->format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (s->format & VS::ARRAY_COMPRESS_NORMAL && s->format & VS::ARRAY_FORMAT_TANGENT && s->format & VS::ARRAY_COMPRESS_TANGENT) {
Vector2 oct(((int8_t *)rd)[0] / 127.0, ((int8_t *)rd)[1] / 127.0);
Vector3 vec = VS::oct_to_norm(oct);
wr[0] = vec.x * base_weight;
wr[1] = vec.y * base_weight;
wr[2] = vec.z * base_weight;
} else {
Vector2 oct(((int16_t *)rd)[0] / 32767.0, ((int16_t *)rd)[1] / 32767.0);
Vector3 vec = VS::oct_to_norm(oct);
wr[0] = vec.x * base_weight;
wr[1] = vec.y * base_weight;
wr[2] = vec.z * base_weight;
}
} else {
wr[0] = rd[0] * base_weight;
wr[1] = rd[1] * base_weight;
wr[2] = rd[2] * base_weight;
if (s->format & VS::ARRAY_COMPRESS_NORMAL) {
wr[0] = (((int8_t *)rd)[0] / 127.0) * base_weight;
wr[1] = (((int8_t *)rd)[1] / 127.0) * base_weight;
wr[2] = (((int8_t *)rd)[2] / 127.0) * base_weight;
} else {
wr[0] = rd[0] * base_weight;
wr[1] = rd[1] * base_weight;
wr[2] = rd[2] * base_weight;
}
}
} break;
case VS::ARRAY_TANGENT: {
if (s->format & VS::ARRAY_COMPRESS_TANGENT) {
wr[0] = (((int8_t *)rd)[0] / 127.0) * base_weight;
wr[1] = (((int8_t *)rd)[1] / 127.0) * base_weight;
wr[2] = (((int8_t *)rd)[2] / 127.0) * base_weight;
wr[3] = (((int8_t *)rd)[3] / 127.0) * base_weight;
if (s->format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (s->format & VS::ARRAY_COMPRESS_TANGENT && s->format & VS::ARRAY_FORMAT_NORMAL && s->format & VS::ARRAY_COMPRESS_NORMAL) {
Vector2 oct(((int8_t *)rd)[0] / 127.0, ((int8_t *)rd)[1] / 127.0);
float sign;
Vector3 vec = VS::oct_to_tangent(oct, &sign);
wr[0] = vec.x * base_weight;
wr[1] = vec.y * base_weight;
wr[2] = vec.z * base_weight;
wr[3] = sign * base_weight;
} else {
Vector2 oct(((int16_t *)rd)[0] / 32767.0, ((int16_t *)rd)[1] / 32767.0);
float sign;
Vector3 vec = VS::oct_to_tangent(oct, &sign);
wr[0] = vec.x * base_weight;
wr[1] = vec.y * base_weight;
wr[2] = vec.z * base_weight;
wr[3] = sign * base_weight;
}
} else {
wr[0] = rd[0] * base_weight;
wr[1] = rd[1] * base_weight;
wr[2] = rd[2] * base_weight;
wr[3] = rd[3] * base_weight;
if (s->format & VS::ARRAY_COMPRESS_TANGENT) {
wr[0] = (((int8_t *)rd)[0] / 127.0) * base_weight;
wr[1] = (((int8_t *)rd)[1] / 127.0) * base_weight;
wr[2] = (((int8_t *)rd)[2] / 127.0) * base_weight;
wr[3] = (((int8_t *)rd)[3] / 127.0) * base_weight;
} else {
wr[0] = rd[0] * base_weight;
wr[1] = rd[1] * base_weight;
wr[2] = rd[2] * base_weight;
wr[3] = rd[3] * base_weight;
}
}
} break;
case VS::ARRAY_COLOR: {
@ -3891,6 +3928,7 @@ void RasterizerStorageGLES2::update_dirty_blend_shapes() {
wr[0] += Math::halfptr_to_float(&((uint16_t *)br)[0]) * weight;
wr[1] += Math::halfptr_to_float(&((uint16_t *)br)[1]) * weight;
wr[2] += Math::halfptr_to_float(&((uint16_t *)br)[2]) * weight;
wr[3] = 1.0f;
} else {
wr[0] += br[0] * weight;
wr[1] += br[1] * weight;
@ -3898,27 +3936,63 @@ void RasterizerStorageGLES2::update_dirty_blend_shapes() {
}
} break;
case VS::ARRAY_NORMAL: {
if (s->format & VS::ARRAY_COMPRESS_NORMAL) {
wr[0] += (float(((int8_t *)br)[0]) / 127.0) * weight;
wr[1] += (float(((int8_t *)br)[1]) / 127.0) * weight;
wr[2] += (float(((int8_t *)br)[2]) / 127.0) * weight;
if (s->format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (s->format & VS::ARRAY_COMPRESS_NORMAL && s->format & VS::ARRAY_FORMAT_TANGENT && s->format & VS::ARRAY_COMPRESS_TANGENT) {
Vector2 oct(((int8_t *)br)[0] / 127.0, ((int8_t *)br)[1] / 127.0);
Vector3 vec = VS::oct_to_norm(oct);
wr[0] += vec.x * weight;
wr[1] += vec.y * weight;
wr[2] += vec.z * weight;
} else {
Vector2 oct(((int16_t *)br)[0] / 32767.0, ((int16_t *)br)[1] / 32767.0);
Vector3 vec = VS::oct_to_norm(oct);
wr[0] += vec.x * weight;
wr[1] += vec.y * weight;
wr[2] += vec.z * weight;
}
} else {
wr[0] += br[0] * weight;
wr[1] += br[1] * weight;
wr[2] += br[2] * weight;
if (s->format & VS::ARRAY_COMPRESS_NORMAL) {
wr[0] += (float(((int8_t *)br)[0]) / 127.0) * weight;
wr[1] += (float(((int8_t *)br)[1]) / 127.0) * weight;
wr[2] += (float(((int8_t *)br)[2]) / 127.0) * weight;
} else {
wr[0] += br[0] * weight;
wr[1] += br[1] * weight;
wr[2] += br[2] * weight;
}
}
} break;
case VS::ARRAY_TANGENT: {
if (s->format & VS::ARRAY_COMPRESS_TANGENT) {
wr[0] += (float(((int8_t *)br)[0]) / 127.0) * weight;
wr[1] += (float(((int8_t *)br)[1]) / 127.0) * weight;
wr[2] += (float(((int8_t *)br)[2]) / 127.0) * weight;
wr[3] = (float(((int8_t *)br)[3]) / 127.0);
if (s->format & VS::ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (s->format & VS::ARRAY_COMPRESS_TANGENT && s->format & VS::ARRAY_FORMAT_NORMAL && s->format & VS::ARRAY_COMPRESS_NORMAL) {
Vector2 oct(((int8_t *)br)[0] / 127.0, ((int8_t *)br)[1] / 127.0);
float sign;
Vector3 vec = VS::oct_to_tangent(oct, &sign);
wr[0] += vec.x * weight;
wr[1] += vec.y * weight;
wr[2] += vec.z * weight;
wr[3] = sign * weight;
} else {
Vector2 oct(((int16_t *)rd)[0] / 32767.0, ((int16_t *)rd)[1] / 32767.0);
float sign;
Vector3 vec = VS::oct_to_tangent(oct, &sign);
wr[0] += vec.x * weight;
wr[1] += vec.y * weight;
wr[2] += vec.z * weight;
wr[3] = sign * weight;
}
} else {
wr[0] += br[0] * weight;
wr[1] += br[1] * weight;
wr[2] += br[2] * weight;
wr[3] = br[3];
if (s->format & VS::ARRAY_COMPRESS_TANGENT) {
wr[0] += (float(((int8_t *)br)[0]) / 127.0) * weight;
wr[1] += (float(((int8_t *)br)[1]) / 127.0) * weight;
wr[2] += (float(((int8_t *)br)[2]) / 127.0) * weight;
wr[3] = (float(((int8_t *)br)[3]) / 127.0);
} else {
wr[0] += br[0] * weight;
wr[1] += br[1] * weight;
wr[2] += br[2] * weight;
wr[3] = br[3];
}
}
} break;
case VS::ARRAY_COLOR: {