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);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBitangents));
}
if (_attributes.offBoneIndices != -1) {
if (_attributes.offTanSpaceNormals != -1) {
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) {
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBoneWeights));
glEnableVertexAttribArray(8);
glVertexAttribPointer(8, 4, GL_FLOAT, GL_FALSE, _attributes.stride, reinterpret_cast<void *>(_attributes.offBoneWeights));
}
glBindVertexArray(0);

View file

@ -200,7 +200,7 @@ static const vector<uint16_t> g_aabbIndices = {
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

View file

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

View file

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

View file

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