diff --git a/mesh.cpp b/mesh.cpp index 6b27424..46ee880 100755 --- a/mesh.cpp +++ b/mesh.cpp @@ -65,15 +65,15 @@ namespace vb01{ irradianceShader = new Shader(libPath + "irradiance"); brdfIntegrationShader = new Shader(libPath + "brdfIntegration"); - prefilterMap = new Texture(reflectionSize, false); - irradianceMap = new Texture(reflectionSize, false); - postfilterMap = new Texture(reflectionSize, false, 5); - brdfIntegrationMap = new Texture(reflectionSize, reflectionSize, false); + prefilterMap = new Texture(preFilterMapSize, false); + irradianceMap = new Texture(irradianceMapSize, false); + postfilterMap = new Texture(environmentMapSize, false, 5); + brdfIntegrationMap = new Texture(brdfMapSize, brdfMapSize, false); - initFramebuffer(preFilterFramebuffer, preFilterRenderbuffer, reflectionSize); - initFramebuffer(irrandianceFramebuffer, irradianceRenderbuffer, reflectionSize); - initFramebuffer(postFilterFramebuffer, postFilterRenderbuffer, reflectionSize); - initFramebuffer(brdfFramebuffer, brdfRenderbuffer, reflectionSize); + initFramebuffer(preFilterFramebuffer, preFilterRenderbuffer, preFilterMapSize); + initFramebuffer(irrandianceFramebuffer, irradianceRenderbuffer, irradianceMapSize); + initFramebuffer(postFilterFramebuffer, postFilterRenderbuffer, environmentMapSize); + initFramebuffer(brdfFramebuffer, brdfRenderbuffer, brdfMapSize); initMesh(); } @@ -280,7 +280,8 @@ namespace vb01{ */ glBindFramebuffer(GL_FRAMEBUFFER, preFilterFramebuffer); - glViewport(0, 0, reflectionSize, reflectionSize); + int width = prefilterMap->getWidth(); + glViewport(0, 0, width, width); Root *root = Root::getSingleton(); Mesh *skybox = root->getSkybox(); @@ -314,7 +315,8 @@ namespace vb01{ glBindFramebuffer(GL_FRAMEBUFFER, irrandianceFramebuffer); glBindRenderbuffer(GL_RENDERBUFFER, irradianceRenderbuffer); - glViewport(0, 0, reflectionSize, reflectionSize); + int width = irradianceMapSize; + glViewport(0, 0, width, width); irradianceShader->use(); irradianceShader->setMat4(proj, "proj"); irradianceShader->setInt(0, "environmentMap"); @@ -348,13 +350,13 @@ namespace vb01{ environmentShader->setMat4(proj, "proj"); environmentShader->setInt(0, "environmentMap"); - prefilterMap->select(0); + prefilterMap->select(); Root *root = Root::getSingleton(); int numMipmaps = postfilterMap->getMipmapLevel(); for(int i = 0; i < numMipmaps; ++i){ - u32 width = reflectionSize * pow(0.5, i); + u32 width = environmentMapSize * pow(0.5, i); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, width); glViewport(0, 0, width, width); @@ -382,11 +384,11 @@ namespace vb01{ void Mesh::updateBrdfLut(){ glBindFramebuffer(GL_FRAMEBUFFER, brdfFramebuffer); + int width = brdfMapSize; + glViewport(0, 0, width, width); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - glViewport(0, 0, reflectionSize, reflectionSize); glBindRenderbuffer(GL_RENDERBUFFER, brdfRenderbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, reflectionSize, reflectionSize); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *brdfIntegrationMap->getTexture(), 0); brdfIntegrationShader->use(); @@ -414,12 +416,12 @@ namespace vb01{ int irradianceId = 10, brdfId = 11, postFilterId = 12; shader->setInt(irradianceId, "irradianceMap"); - shader->setInt(postFilterId, "postFilterMap"); shader->setInt(brdfId, "brdfIntegrationMap"); + shader->setInt(postFilterId, "postFilterMap"); irradianceMap->select(irradianceId); - postfilterMap->select(postFilterId); brdfIntegrationMap->select(brdfId); + postfilterMap->select(postFilterId); } void Mesh::render(){ diff --git a/mesh.h b/mesh.h index 30e74bd..832d116 100755 --- a/mesh.h +++ b/mesh.h @@ -73,7 +73,7 @@ namespace vb01{ void updateShapeKeys(Shader*); inline glm::vec3 getUpVec(glm::vec3 dir){return (fabs(dir.y) == 1 ? glm::vec3(0, 0, -1) : glm::vec3(0, 1, 0));} - int reflectionSize = 512; + int irradianceMapSize = 32, preFilterMapSize = 512, environmentMapSize = 128, brdfMapSize = 512; Texture *prefilterMap = nullptr, *irradianceMap = nullptr, *postfilterMap = nullptr, *brdfIntegrationMap = nullptr; Shader *environmentShader = nullptr, *irradianceShader = nullptr, *brdfIntegrationShader = nullptr; u32 preFilterFramebuffer, preFilterRenderbuffer, irrandianceFramebuffer, irradianceRenderbuffer, postFilterFramebuffer, postFilterRenderbuffer, brdfFramebuffer, brdfRenderbuffer; diff --git a/pbr.frag b/pbr.frag index ffc832f..74bf1a2 100644 --- a/pbr.frag +++ b/pbr.frag @@ -37,7 +37,7 @@ uniform sampler2D brdfIntegrationMap; uniform bool albedoMapEnabled; uniform bool normalMapEnabled; uniform bool roughnessMapEnabled; -uniform bool metallnessMapEnabled; +uniform bool metalnessMapEnabled; uniform bool ambientOcclutionMapEnabled; uniform bool environmentMapEnabled; uniform vec4 albedoColor; @@ -96,7 +96,7 @@ void main() { float metalness = metalnessVal; - if(metallnessMapEnabled) + if(metalnessMapEnabled) metalness = texture(textures[3].pastTexture, texCoords).r; vec3 f0 = mix(vec3(.04), albedo.rgb, metalness); @@ -121,7 +121,7 @@ void main() { vec3 halfVec = normalize(lightDir + normal); float D = trowbridgeReitz(normal, halfVec, roughness * roughness); - float k = pow(roughness * roughness + 1, 2) / 8.0; + float k = pow(roughness + 1, 2) / 8.0; float G = geoSmith(normal, viewDir, lightDir, k); vec3 F = fresnelSchlick(viewDir, halfVec, f0); float nDotV = max(dot(viewDir, normal), 0); @@ -134,21 +134,25 @@ void main() { totalLightColor += (kDiff * fDiff + cookTor) * lights[i].color * attenuation * nDotL; } - vec3 specular = vec3(.03); + vec3 specular = vec3(.03), F = vec3(0); if(environmentMapEnabled){ // sample both the pre-filter map and the BRDF lut and combine them together as per the Split-Sum approximation to get the IBL specular part. - vec3 reflVec = reflect(-viewDir, normal); + vec3 reflVec = reflect(-viewDir, normalize(fragPos + normal)); const float MAX_REFLECTION_LOD = 4.0; vec3 prefilteredColor = textureLod(postFilterMap, reflVec, roughness * MAX_REFLECTION_LOD).rgb; vec2 brdf = texture(brdfIntegrationMap, vec2(max(dot(normal, viewDir), 0.0), roughness)).rg; - vec3 F = fresnelSchlickRoughness(normal, viewDir, f0, roughness); + F = fresnelSchlickRoughness(normal, viewDir, f0, roughness); + specular = prefilteredColor; specular = prefilteredColor * (F * brdf.x + brdf.y); } float ao = ambientOcclusion; - vec3 totalAmbientColor = (albedo.rgb + specular) * ao; + vec3 irradiance = texture(irradianceMap, normal).rgb; + vec3 diffuse = irradiance * albedo.rgb; + vec3 kD = (vec3(1) - F) * (1 - metalness); + vec3 totalAmbientColor = (kD * diffuse + specular) * ao; vec4 finalColor = vec4(totalLightColor + totalAmbientColor, 1); diff --git a/pbr.geo b/pbr.geo new file mode 100644 index 0000000..e69de29 diff --git a/pbr.vert b/pbr.vert index b90458b..5568762 100644 --- a/pbr.vert +++ b/pbr.vert @@ -28,10 +28,10 @@ uniform mat4 proj; uniform float[numShapeKeys] shapeKeyFactors; void main(){ - mat3 normalMat = mat3(transpose(inverse(model))); - norm = (normalMat * aNorm); - tan = (normalMat * aTan); - biTan = (normalMat * aBiTan); + mat3 normalMat = mat3(model); + norm = mat3(normalMat) * aNorm; + tan = mat3(normalMat) * aTan; + biTan = mat3(normalMat) * aBiTan; fragPos = vec3(model * vec4(aPos, 1)); texCoords = aTexCoords; diff --git a/texture.cpp b/texture.cpp index 3fddeab..244cce1 100755 --- a/texture.cpp +++ b/texture.cpp @@ -107,7 +107,7 @@ namespace vb01{ data = stbi_load(paths[i].c_str(), &width, &height, &numChannels, 0); if(data){ - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, data); stbi_image_free(data); } else{ @@ -116,7 +116,7 @@ namespace vb01{ } } else - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_INT, NULL); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, width, width, 0, GL_RGB, GL_UNSIGNED_INT, NULL); } else{ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, width, width, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); @@ -126,9 +126,14 @@ namespace vb01{ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + + if(mipmapLevel > 0){ + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glGenerateMipmap(GL_TEXTURE_CUBE_MAP); + } + else + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } Texture::Texture(FT_Face &face, char ch){ diff --git a/texture.h b/texture.h index 349f994..95ddc74 100755 --- a/texture.h +++ b/texture.h @@ -22,6 +22,8 @@ namespace vb01{ void animate(float, KeyframeChannel); inline u32* getTexture(int i = 0){return &(texture[i]);} inline std::string* getPath(){return paths;} + inline int getWidth(){return width;} + inline int getHeight(){return height;} inline int getNumFrames(){return numFrames;} inline int getMipmapLevel(){return mipmapLevel;} inline float getMixRatio(){return mixRatio;}