Fix bump mapping

- Use tangent space normals from MDL
- Fix tangent space to world space transform
This commit is contained in:
Vsevolod Kremianskii 2021-05-15 09:01:25 +07:00
parent 5eefe157e7
commit 4c7d588af9
5 changed files with 37 additions and 30 deletions

View file

@ -95,13 +95,17 @@ void Mesh::init() {
glEnableVertexAttribArray(5); glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBitangents)); glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBitangents));
} }
if (_attributes.offBoneIndices != -1) { if (_attributes.offTanSpaceNormals != -1) {
glEnableVertexAttribArray(6); glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBoneIndices)); glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offTanSpaceNormals));
}
if (_attributes.offBoneIndices != -1) {
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBoneIndices));
} }
if (_attributes.offBoneWeights != -1) { if (_attributes.offBoneWeights != -1) {
glEnableVertexAttribArray(7); glEnableVertexAttribArray(8);
glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBoneWeights)); glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBoneWeights));
} }
glBindVertexArray(0); glBindVertexArray(0);

View file

@ -200,7 +200,7 @@ static const vector<uint16_t> g_aabbIndices = {
6, 0, 0, 3, 3, 5, 5, 6 6, 0, 0, 3, 3, 5, 5, 6
}; };
static const VertexAttributes g_aabbAttributes = { 3 * sizeof(float), 0, -1, -1, -1, -1, -1, -1, -1 }; static const VertexAttributes g_aabbAttributes = { 3 * sizeof(float), 0 };
// END AABB // END AABB

View file

@ -31,6 +31,7 @@ struct VertexAttributes {
int offTexCoords2 { -1 }; int offTexCoords2 { -1 };
int offTangents { -1 }; int offTangents { -1 };
int offBitangents { -1 }; int offBitangents { -1 };
int offTanSpaceNormals { -1 };
int offBoneIndices { -1 }; int offBoneIndices { -1 };
int offBoneWeights { -1 }; int offBoneWeights { -1 };
}; };

View file

@ -285,6 +285,7 @@ shared_ptr<ModelNode::TriangleMesh> MdlReader::readMesh(int flags) {
if (offMdxTanSpace != -1) { if (offMdxTanSpace != -1) {
attributes.offBitangents = offMdxTanSpace + 0 * sizeof(float); attributes.offBitangents = offMdxTanSpace + 0 * sizeof(float);
attributes.offTangents = offMdxTanSpace + 3 * sizeof(float); attributes.offTangents = offMdxTanSpace + 3 * sizeof(float);
attributes.offTanSpaceNormals = offMdxTanSpace + 6 * sizeof(float);
} }
if (flags & NodeFlags::skin) { if (flags & NodeFlags::skin) {

View file

@ -239,7 +239,7 @@ vec3 getNormalFromBumpmap(vec2 uv) {
result = normalize(result * 2.0 - 1.0); result = normalize(result * 2.0 - 1.0);
} }
result = normalize(fragTanSpace * result); result = normalize(result * fragTanSpace);
return result; return result;
} }
@ -351,8 +351,9 @@ layout(location = 2) in vec2 aTexCoords;
layout(location = 3) in vec2 aLightmapCoords; layout(location = 3) in vec2 aLightmapCoords;
layout(location = 4) in vec3 aTangent; layout(location = 4) in vec3 aTangent;
layout(location = 5) in vec3 aBitangent; layout(location = 5) in vec3 aBitangent;
layout(location = 6) in vec4 aBoneIndices; layout(location = 6) in vec3 aTanSpaceNormal;
layout(location = 7) in vec4 aBoneWeights; layout(location = 7) in vec4 aBoneIndices;
layout(location = 8) in vec4 aBoneWeights;
out vec3 fragPosition; out vec3 fragPosition;
out vec3 fragNormal; out vec3 fragNormal;
@ -362,8 +363,8 @@ out vec4 fragPosLightSpace;
out mat3 fragTanSpace; out mat3 fragTanSpace;
void main() { void main() {
vec4 P = vec4(aPosition, 1.0); vec4 position = vec4(aPosition, 1.0);
vec4 N = vec4(aNormal, 0.0); vec4 normal = vec4(aNormal, 0.0);
if (isFeatureEnabled(FEATURE_SKELETAL)) { if (isFeatureEnabled(FEATURE_SKELETAL)) {
int i1 = int(aBoneIndices[0]); int i1 = int(aBoneIndices[0]);
@ -376,32 +377,38 @@ void main() {
float w3 = aBoneWeights[2]; float w3 = aBoneWeights[2];
float w4 = aBoneWeights[3]; float w4 = aBoneWeights[3];
P = position =
(uBones[i1] * P) * w1 + (uBones[i1] * position) * w1 +
(uBones[i2] * P) * w2 + (uBones[i2] * position) * w2 +
(uBones[i3] * P) * w3 + (uBones[i3] * position) * w3 +
(uBones[i4] * P) * w4; (uBones[i4] * position) * w4;
N = normal =
(uBones[i1] * N) * w1 + (uBones[i1] * normal) * w1 +
(uBones[i2] * N) * w2 + (uBones[i2] * normal) * w2 +
(uBones[i3] * N) * w3 + (uBones[i3] * normal) * w3 +
(uBones[i4] * N) * w4; (uBones[i4] * normal) * w4;
} else if (isFeatureEnabled(FEATURE_DANGLYMESH)) { } else if (isFeatureEnabled(FEATURE_DANGLYMESH)) {
vec3 maxStride = vec3(uDanglymeshDisplacement * uDanglymeshConstraints[gl_VertexID / 4][gl_VertexID % 4]); vec3 maxStride = vec3(uDanglymeshDisplacement * uDanglymeshConstraints[gl_VertexID / 4][gl_VertexID % 4]);
vec3 stride = clamp(uDanglymeshStride.xyz, -maxStride, maxStride); vec3 stride = clamp(uDanglymeshStride.xyz, -maxStride, maxStride);
P += vec4(stride, 0.0); position += vec4(stride, 0.0);
} }
mat3 normalMatrix = transpose(inverse(mat3(uGeneral.model))); mat3 normalMatrix = transpose(inverse(mat3(uGeneral.model)));
N = vec4(normalize(normalMatrix * N.xyz), 0.0);
fragPosition = vec3(uGeneral.model * P); fragPosition = vec3(uGeneral.model * position);
fragNormal = N.xyz; fragNormal = normalize(normalMatrix * normal.xyz);
fragTexCoords = aTexCoords; fragTexCoords = aTexCoords;
fragLightmapCoords = aLightmapCoords; fragLightmapCoords = aLightmapCoords;
if (isFeatureEnabled(FEATURE_BUMPMAPS)) {
vec3 T = normalize(normalMatrix * aTangent);
vec3 B = normalize(normalMatrix * aBitangent);
vec3 N = normalize(normalMatrix * aTanSpaceNormal);
fragTanSpace = transpose(mat3(T, B, N));
}
// Compute light space fragment position for directional lights // Compute light space fragment position for directional lights
if (uShadows.lightPresent && uShadows.lightPosition.w == 0.0) { if (uShadows.lightPresent && uShadows.lightPosition.w == 0.0) {
fragPosLightSpace = uShadows.lightSpaceMatrices[0] * vec4(fragPosition, 1.0); fragPosLightSpace = uShadows.lightSpaceMatrices[0] * vec4(fragPosition, 1.0);
@ -409,12 +416,6 @@ void main() {
fragPosLightSpace = vec4(0.0); fragPosLightSpace = vec4(0.0);
} }
if (isFeatureEnabled(FEATURE_BUMPMAPS)) {
vec3 T = normalize(normalMatrix * aTangent);
vec3 B = normalize(normalMatrix * aBitangent);
fragTanSpace = transpose(mat3(T, B, N));
}
gl_Position = uGeneral.projection * uGeneral.view * vec4(fragPosition, 1.0); gl_Position = uGeneral.projection * uGeneral.view * vec4(fragPosition, 1.0);
} }
)END"; )END";