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)
(cherry picked from commit 733a84f7a4
)
This commit is contained in:
parent
fb9aa26b9d
commit
56d3abdbcc
@ -1401,7 +1401,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);
|
||||
@ -2429,7 +2443,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;
|
||||
|
@ -3790,6 +3790,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;
|
||||
@ -3799,27 +3800,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: {
|
||||
@ -3884,6 +3921,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;
|
||||
@ -3891,27 +3929,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 New Issue
Block a user