From: Luke Lau Date: Mon, 10 Feb 2020 17:18:56 +0000 (+0000) Subject: Allow materials to not have some properties X-Git-Tag: cs7gv5-a2~8 X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=commitdiff_plain;h=83eb84c159c8ec75cda9fbeb05e3d5746b54ad53 Allow materials to not have some properties Also start work on IK --- diff --git a/main.cpp b/main.cpp index fd6159d..aa78a22 100644 --- a/main.cpp +++ b/main.cpp @@ -205,7 +205,8 @@ void init() { pbrProg = new Program("pbrvert.glsl", "pbrfrag.glsl"); glUseProgram(pbrProg->progId); - const aiScene *scene = importer.ReadFile("models/newtonsCradle.glb", aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_FlipUVs); + const std::string scenePath = "models/ik.glb"; + const aiScene *scene = importer.ReadFile(scenePath, aiProcess_Triangulate | aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_FlipUVs); if (!scene) { std::cerr << importer.GetErrorString() << std::endl; exit(1); diff --git a/material.cpp b/material.cpp index 9ed7e90..e1fb5c3 100644 --- a/material.cpp +++ b/material.cpp @@ -5,28 +5,25 @@ 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); } @@ -56,19 +53,39 @@ Material::Texture::Texture(const aiString fileName, const aiScene &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); + } } diff --git a/model.cpp b/model.cpp index a11a074..3c1ecf4 100644 --- a/model.cpp +++ b/model.cpp @@ -241,6 +241,9 @@ void Model::Node::draw( const std::vector &meshes, for (std::pair> 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 @@ -301,7 +304,7 @@ Model::Model(const aiScene *scene, Program p): program(p) { } // 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)); } diff --git a/models/ik.blend b/models/ik.blend new file mode 100644 index 0000000..03af46d Binary files /dev/null and b/models/ik.blend differ diff --git a/models/ik.glb b/models/ik.glb new file mode 100644 index 0000000..b992585 Binary files /dev/null and b/models/ik.glb differ diff --git a/pbrfrag.glsl b/pbrfrag.glsl index c45242d..1d0f759 100644 --- a/pbrfrag.glsl +++ b/pbrfrag.glsl @@ -7,10 +7,15 @@ in vec2 texCoords; 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; @@ -51,7 +56,9 @@ float geometrySmith(vec3 N, vec3 V, vec3 L, float roughness) { } 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); @@ -66,11 +73,18 @@ vec3 getNormalFromMap() { } 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);