Physically based rendering with textures

This commit is contained in:
Nigel Barink 2023-05-20 21:51:57 +02:00
parent 7627df0fa0
commit 08e1c3248b
9 changed files with 87 additions and 13 deletions

1
.gitattributes vendored
View File

@ -1,3 +1,4 @@
*.obj filter=lfs diff=lfs merge=lfs -text *.obj filter=lfs diff=lfs merge=lfs -text
*.mtl filter=lfs diff=lfs merge=lfs -text *.mtl filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text

View File

@ -7,10 +7,11 @@ in vec3 Normal;
uniform vec3 camPos; uniform vec3 camPos;
uniform vec3 albedo; uniform sampler2D albedoMap;
uniform float metallic; uniform sampler2D metallicMap;
uniform float roughness; uniform sampler2D normalMap;
uniform float ao; uniform sampler2D roughnessMap;
uniform sampler2D aoMap;
uniform vec3 lightPositions[4]; uniform vec3 lightPositions[4];
uniform vec3 lightColors[4]; uniform vec3 lightColors[4];
@ -59,8 +60,31 @@ float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
return ggx1 * ggx2; 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 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 V = normalize(camPos - WorldPos);
vec3 F0 = vec3(0.04); vec3 F0 = vec3(0.04);
@ -98,8 +122,9 @@ void main(){
vec3 ambient = vec3(0.03) * albedo * ao; vec3 ambient = vec3(0.03) * albedo * ao;
vec3 color = ambient + Lo; vec3 color = ambient + Lo;
// Gamma correct the result // HDR tonemapping
color = color / (color + vec3(1.0)); color = color / (color + vec3(1.0));
// gamma correct
color = pow(color, vec3(1.0/2.2)); color = pow(color, vec3(1.0/2.2));
FragColor = vec4(color, 1.0); FragColor = vec4(color, 1.0);

BIN
Textures/rusted_iron/albedo.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Textures/rusted_iron/ao.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Textures/rusted_iron/metallic.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Textures/rusted_iron/normal.png (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Textures/rusted_iron/roughness.png (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -10,6 +10,7 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include "../Primitives/Scene.h" #include "../Primitives/Scene.h"
#include "../model.h"
static enum class RenderPass { static enum class RenderPass {
NONE = 0, NONE = 0,
SKYBOX, SKYBOX,
@ -37,7 +38,11 @@ glm::vec3 lightColors[] = {
int nrRows = 7; int nrRows = 7;
int nrColumns = 7; int nrColumns = 7;
float spacing = 2.5; float spacing = 2.5;
unsigned int albedo;
unsigned int normal;
unsigned int metallic;
unsigned int roughness;
unsigned int ao;
void Renderer::Setup() void Renderer::Setup()
{ {
// Create ScreenVAO // Create ScreenVAO
@ -70,6 +75,14 @@ void Renderer::Setup()
shaders[static_cast<int>(RenderPass::PBR)] = Shader(); shaders[static_cast<int>(RenderPass::PBR)] = Shader();
shaders[static_cast<int>(RenderPass::PBR)].Load("../Shaders/pbr.vs", "../Shaders/pbr.fs"); shaders[static_cast<int>(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 ) { void Renderer::resize(int width, int height ) {
@ -116,7 +129,6 @@ void Renderer::resize(int width, int height ) {
unsigned int sphereVAO = 0; unsigned int sphereVAO = 0;
unsigned int indexCount; unsigned int indexCount;
void renderSphere() { void renderSphere() {
@ -232,6 +244,7 @@ void Renderer::Render(Scene& scene)
auto centeredView = glm::mat4(glm::mat3(scene.MainCamera.GetViewMatrix())); auto centeredView = glm::mat4(glm::mat3(scene.MainCamera.GetViewMatrix()));
shader.setMat4("view", centeredView); shader.setMat4("view", centeredView);
glActiveTexture(GL_TEXTURE0);
scene.skybox.Bind(); scene.skybox.Bind();
glDrawArrays(GL_TRIANGLES, 0, 36); glDrawArrays(GL_TRIANGLES, 0, 36);
@ -266,20 +279,38 @@ void Renderer::Render(Scene& scene)
shader = shaders.at(static_cast<int>(RenderPass::PBR)); shader = shaders.at(static_cast<int>(RenderPass::PBR));
shader.use(); shader.use();
shader.setVec3("albedo", glm::vec3(0.5f, 0.0f, 0.0f)); shader.setInt("albedoMap", 0);
shader.setFloat("ao", 1.0f); shader.setInt("normalMap", 1);
shader.setInt("metallicMap", 2);
shader.setInt("roughnessMap", 3);
shader.setInt("aoMap", 4);
shader.setMat4("projection", projection); shader.setMat4("projection", projection);
view = scene.MainCamera.GetViewMatrix(); view = scene.MainCamera.GetViewMatrix();
shader.setMat4("view", view); shader.setMat4("view", view);
shader.setVec3("camPos", scene.MainCamera.Position); 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); model = glm::mat4(1.0f);
for (int row = 0; row < nrRows; ++row) { for (int row = 0; row < nrRows; ++row) {
shader.setFloat("metallic", (float)row / (float)nrRows);
for (int col = 0; col < nrColumns; ++col) { 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::mat4(1.0f);
model = glm::translate(model, glm::vec3( model = glm::translate(model, glm::vec3(
(col - (nrColumns / 2)) * spacing, (col - (nrColumns / 2)) * spacing,

View File

@ -21,3 +21,5 @@ class Model {
Mesh processMesh(aiMesh* mesh, const aiScene* scene); Mesh processMesh(aiMesh* mesh, const aiScene* scene);
std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName ); std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName );
}; };
unsigned int TextureFromFile(const char* path, const std::string& directory);