GLES2 Compression on Blend Shapes Fix
When compressed vertex positions are used in a blend shapes mesh, we need to make sure we set the w-component of the position vector to 1.0 When octahedral compression is used on normals/tangents, they need to be converted to cartesian floats to be used for blend shapes This conversion also changes the number of components of that vertex attribute, which caused issues because previously there was an assumption that you had the same number of components in the blend shape buffer as you did in the original mesh's buffer (which is not true for oct norm/tang)
This commit is contained in:
parent
b81251d4a9
commit
733a84f7a4
2 changed files with 124 additions and 34 deletions
|
@ -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;
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Reference in a new issue