Material::Material(const aiMaterial &ai, const aiScene &scene, GLuint progId): progId(progId) {
aiString name;
ai.Get(AI_MATKEY_NAME, name);
- if (name == aiString("default material")) {
- abort();
- }
aiString path;
ai.GetTexture(aiTextureType_DIFFUSE, 1, &path);
+ if (path.length != 0)
albedo = new Texture(path, scene);
path = "";
ai.GetTexture(aiTextureType_NORMALS, 0, &path);
+ if (path.length != 0)
normal = new Texture(path, scene);
path = "";
ai.GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &path);
+ if (path.length != 0)
metallicRoughness = new Texture(path, scene);
path = "";
ai.GetTexture(aiTextureType_LIGHTMAP, 0, &path);
- if (path == aiString("")) {
- fprintf(stderr, "Material %s does not have an AO map", name.C_Str());
- abort();
- }
+ if (path.length != 0)
ambientOcclusion = new Texture(path, scene);
}
}
void Material::bind() const {
- glUniform1i(glGetUniformLocation(progId, "albedoMap"), 0);
+ if (ambientOcclusion != nullptr) {
+ glUniform1i(glGetUniformLocation(progId, "material.albedoMap"), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, albedo->texId);
+ glUniform1i(glGetUniformLocation(progId, "material.hasAlbedo"), 1);
+ } else {
+ glUniform1i(glGetUniformLocation(progId, "material.hasAlbedo"), 0);
+ }
- glUniform1i(glGetUniformLocation(progId, "normalMap"), 1);
+ if (normal != nullptr) {
+ glUniform1i(glGetUniformLocation(progId, "material.normalMap"), 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normal->texId);
+ glUniform1i(glGetUniformLocation(progId, "material.hasNormal"), 1);
+ } else {
+ glUniform1i(glGetUniformLocation(progId, "material.hasNormal"), 0);
+ }
+ if (metallicRoughness != nullptr) {
glUniform1i(glGetUniformLocation(progId, "metallicRoughnessMap"), 2);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, metallicRoughness->texId);
+ glUniform1i(glGetUniformLocation(progId, "material.hasMetallicRoughness"), 1);
+ } else {
+ glUniform1i(glGetUniformLocation(progId, "material.hasMetallicRoughness"), 0);
+ }
+ if (ambientOcclusion != nullptr) {
glUniform1i(glGetUniformLocation(progId, "aoMap"), 3);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, ambientOcclusion->texId);
+ glUniform1i(glGetUniformLocation(progId, "material.hasAo"), 1);
+ } else {
+ glUniform1i(glGetUniformLocation(progId, "material.hasAo"), 0);
+ }
}
for (std::pair<std::string, std::pair<unsigned int, glm::mat4>> pair: mesh.boneMap) {
std::string nodeName = pair.first;
+
+ if (animMap->count(nodeName) <= 0) break;
+
unsigned int boneId = pair.second.first;
// This is actually an inverse-bind matrix
// i.e. position of the mesh in bone space
}
// TODO: handle default material inserted at the end by assimp
- for (unsigned int i = 0; i < scene->mNumMaterials - 1; i++) {
+ for (unsigned int i = 0; i < scene->mNumMaterials; i++) {
const aiMaterial &material = *scene->mMaterials[i];
materials.push_back(Material(material, *scene, p.progId));
}
--- a/models/ik.glb
uniform vec3 camPos;
-uniform sampler2D albedoMap;
-uniform sampler2D normalMap;
-uniform sampler2D metallicRoughnessMap;
-uniform sampler2D aoMap;
+struct Material {
+ sampler2D albedoMap;
+ sampler2D normalMap;
+ sampler2D metallicRoughnessMap;
+ sampler2D aoMap;
+ bool hasAlbedo, hasNormal, hasMetallicRoughness, hasAo;
+};
+uniform Material mat;
+
uniform samplerCube irradianceMap;
uniform samplerCube prefilterMap;
uniform sampler2D brdfMap;
}
vec3 getNormalFromMap() {
- vec3 tangentNormal = texture(normalMap, texCoords).xyz * 2.f - 1.f;
+ vec3 tangentNormal = vec3(0, 0, 1);
+ if (mat.hasNormal)
+ tangentNormal = texture(mat.normalMap, texCoords).xyz * 2.f - 1.f;
vec3 Q1 = dFdx(worldPos);
vec3 Q2 = dFdy(worldPos);
vec2 st1 = dFdx(texCoords);
}
void main() {
- vec3 albedo = pow(texture(albedoMap, texCoords).rgb, vec3(2.2));
+ vec3 albedo = vec3(1);
+ if (mat.hasAlbedo)
+ albedo = pow(texture(mat.albedoMap, texCoords).rgb, vec3(2.2));
+
vec3 normal = getNormalFromMap();
- float metallic = texture(metallicRoughnessMap, texCoords).b;
- float roughness = texture(metallicRoughnessMap, texCoords).g;
- float ao = texture(aoMap, texCoords).r;
+
+ float metallic = 0, roughness = 1;
+ if (mat.hasMetallicRoughness) {
+ metallic = texture(mat.metallicRoughnessMap, texCoords).b;
+ roughness = texture(mat.metallicRoughnessMap, texCoords).g;
+ }
+ float ao = mat.hasAo ? texture(mat.aoMap, texCoords).r : 1;
vec3 N = normalize(normal);
vec3 V = normalize(camPos - worldPos);