From 08e1c3248bffb82979cb5c7c19b9bae055faeab8 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Sat, 20 May 2023 21:51:57 +0200 Subject: [PATCH] Physically based rendering with textures --- .gitattributes | 1 + Shaders/pbr.fs | 37 ++++++++++++++++++++---- Textures/rusted_iron/albedo.png | 3 ++ Textures/rusted_iron/ao.png | 3 ++ Textures/rusted_iron/metallic.png | 3 ++ Textures/rusted_iron/normal.png | 3 ++ Textures/rusted_iron/roughness.png | 3 ++ src/Renderer/Renderer.cpp | 45 +++++++++++++++++++++++++----- src/model.h | 2 ++ 9 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 Textures/rusted_iron/albedo.png create mode 100644 Textures/rusted_iron/ao.png create mode 100644 Textures/rusted_iron/metallic.png create mode 100644 Textures/rusted_iron/normal.png create mode 100644 Textures/rusted_iron/roughness.png diff --git a/.gitattributes b/.gitattributes index 000c6b3..bd2ae09 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.obj filter=lfs diff=lfs merge=lfs -text *.mtl filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/Shaders/pbr.fs b/Shaders/pbr.fs index 6077d89..6e69a49 100644 --- a/Shaders/pbr.fs +++ b/Shaders/pbr.fs @@ -7,10 +7,11 @@ in vec3 Normal; uniform vec3 camPos; -uniform vec3 albedo; -uniform float metallic; -uniform float roughness; -uniform float ao; +uniform sampler2D albedoMap; +uniform sampler2D metallicMap; +uniform sampler2D normalMap; +uniform sampler2D roughnessMap; +uniform sampler2D aoMap; uniform vec3 lightPositions[4]; uniform vec3 lightColors[4]; @@ -59,8 +60,31 @@ float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) return ggx1 * ggx2; } -void main(){ +vec3 getNormalFromNormalMap(){ + vec3 tangentNormal = texture(normalMap, TexCoords).xyz * 2.0 - 1.0; + + vec3 Q1 = dFdx(WorldPos); + vec3 Q2 = dFdy(WorldPos); + vec2 st1 = dFdx(TexCoords); + vec2 st2 = dFdy(TexCoords); + vec3 N = normalize(Normal); + vec3 T = normalize(Q1 *st2.t - Q2*st1.t); + vec3 B = -normalize(cross(N, T)); + mat3 TBN = mat3(T, B, N); + + return normalize(TBN * tangentNormal); +} + +void main(){ + + vec3 albedo = pow(texture(albedoMap, TexCoords).rgb, vec3(2.2)); + float metallic = texture(metallicMap, TexCoords).r; + float roughness = texture(roughnessMap, TexCoords).r; + float ao = texture(aoMap, TexCoords).r; + + + vec3 N = getNormalFromNormalMap(); vec3 V = normalize(camPos - WorldPos); vec3 F0 = vec3(0.04); @@ -98,8 +122,9 @@ void main(){ vec3 ambient = vec3(0.03) * albedo * ao; vec3 color = ambient + Lo; - // Gamma correct the result + // HDR tonemapping color = color / (color + vec3(1.0)); + // gamma correct color = pow(color, vec3(1.0/2.2)); FragColor = vec4(color, 1.0); diff --git a/Textures/rusted_iron/albedo.png b/Textures/rusted_iron/albedo.png new file mode 100644 index 0000000..d31d292 --- /dev/null +++ b/Textures/rusted_iron/albedo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea49f2c44684c8810dfb628297c6b1bd8a8477fc77c469510f54db83edd1ba3b +size 10806142 diff --git a/Textures/rusted_iron/ao.png b/Textures/rusted_iron/ao.png new file mode 100644 index 0000000..8d28e72 --- /dev/null +++ b/Textures/rusted_iron/ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:239842079db09bd951d2c79c779a2b1b89ebf7212dfbb637519afb6d0dddde98 +size 13026 diff --git a/Textures/rusted_iron/metallic.png b/Textures/rusted_iron/metallic.png new file mode 100644 index 0000000..3bc5d4b --- /dev/null +++ b/Textures/rusted_iron/metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:571e89a4552fd8ae250e39a6058b484047798815f751f9eace60455ae64f0f91 +size 3419179 diff --git a/Textures/rusted_iron/normal.png b/Textures/rusted_iron/normal.png new file mode 100644 index 0000000..aa607df --- /dev/null +++ b/Textures/rusted_iron/normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dea7d47c6c25f557803e4be7337c5bdb7b5b1592115d1dde18c1d661f17aa5e3 +size 7725049 diff --git a/Textures/rusted_iron/roughness.png b/Textures/rusted_iron/roughness.png new file mode 100644 index 0000000..7e3bdd7 --- /dev/null +++ b/Textures/rusted_iron/roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b078c4d5c20f9a04e7fe48c96119629d4692897bb6fa414c8419200946f125bc +size 3116093 diff --git a/src/Renderer/Renderer.cpp b/src/Renderer/Renderer.cpp index 87d9336..a523fa4 100644 --- a/src/Renderer/Renderer.cpp +++ b/src/Renderer/Renderer.cpp @@ -10,6 +10,7 @@ #include #include #include "../Primitives/Scene.h" +#include "../model.h" static enum class RenderPass { NONE = 0, SKYBOX, @@ -37,7 +38,11 @@ glm::vec3 lightColors[] = { int nrRows = 7; int nrColumns = 7; float spacing = 2.5; - +unsigned int albedo; +unsigned int normal; +unsigned int metallic; +unsigned int roughness; +unsigned int ao; void Renderer::Setup() { // Create ScreenVAO @@ -70,6 +75,14 @@ void Renderer::Setup() shaders[static_cast(RenderPass::PBR)] = Shader(); shaders[static_cast(RenderPass::PBR)].Load("../Shaders/pbr.vs", "../Shaders/pbr.fs"); + + albedo = TextureFromFile("../Textures/rusted_iron/albedo.png", "."); + normal = TextureFromFile("../Textures/rusted_iron/normal.png", "."); + metallic = TextureFromFile("../Textures/rusted_iron/metallic.png", "."); + roughness = TextureFromFile("../Textures/rusted_iron/roughness.png", "."); + ao = TextureFromFile("../Textures/rusted_iron/ao.png","."); + + } void Renderer::resize(int width, int height ) { @@ -116,7 +129,6 @@ void Renderer::resize(int width, int height ) { - unsigned int sphereVAO = 0; unsigned int indexCount; void renderSphere() { @@ -232,6 +244,7 @@ void Renderer::Render(Scene& scene) auto centeredView = glm::mat4(glm::mat3(scene.MainCamera.GetViewMatrix())); shader.setMat4("view", centeredView); + glActiveTexture(GL_TEXTURE0); scene.skybox.Bind(); glDrawArrays(GL_TRIANGLES, 0, 36); @@ -266,20 +279,38 @@ void Renderer::Render(Scene& scene) shader = shaders.at(static_cast(RenderPass::PBR)); shader.use(); - shader.setVec3("albedo", glm::vec3(0.5f, 0.0f, 0.0f)); - shader.setFloat("ao", 1.0f); + shader.setInt("albedoMap", 0); + shader.setInt("normalMap", 1); + shader.setInt("metallicMap", 2); + shader.setInt("roughnessMap", 3); + shader.setInt("aoMap", 4); + shader.setMat4("projection", projection); view = scene.MainCamera.GetViewMatrix(); shader.setMat4("view", view); shader.setVec3("camPos", scene.MainCamera.Position); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, albedo); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, normal); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, metallic); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, roughness); + + + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, ao); + + model = glm::mat4(1.0f); for (int row = 0; row < nrRows; ++row) { - shader.setFloat("metallic", (float)row / (float)nrRows); for (int col = 0; col < nrColumns; ++col) { - shader.setFloat("roughness", glm::clamp((float)col / (float)nrColumns, 0.05f, 1.0f)); - model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3( (col - (nrColumns / 2)) * spacing, diff --git a/src/model.h b/src/model.h index 15dc6d6..bc37faa 100644 --- a/src/model.h +++ b/src/model.h @@ -21,3 +21,5 @@ class Model { Mesh processMesh(aiMesh* mesh, const aiScene* scene); std::vector loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName ); }; + +unsigned int TextureFromFile(const char* path, const std::string& directory);