From 041c676a43cf71d5499753e0424d76a8a561e61d Mon Sep 17 00:00:00 2001 From: devZoGok Date: Mon, 15 Nov 2021 19:42:33 +0200 Subject: [PATCH] expanded PBR shader to accept textures --- pbr.frag | 61 +++++++++++++++++++++++++++++++++++++++++---------- pbrSample.cpp | 31 ++++++++++++++++++-------- 2 files changed, 72 insertions(+), 20 deletions(-) diff --git a/pbr.frag b/pbr.frag index 6acfb70..d1082b0 100644 --- a/pbr.frag +++ b/pbr.frag @@ -30,13 +30,17 @@ struct Texture{ }; uniform Light lights[numLights]; -uniform Texture textures[1]; +uniform Texture textures[5]; uniform bool albedoMapEnabled; +uniform bool normalMapEnabled; +uniform bool roughnessMapEnabled; +uniform bool metallnessMapEnabled; +uniform bool ambientOcclutionMapEnabled; uniform vec4 albedoColor; -uniform float roughness; -uniform float metalness; -uniform vec3 baseReflectivity; +uniform float roughnessVal; +uniform float metalnessVal; +uniform float ambientOcclusion; uniform vec3 camPos; float trowbridgeReitz(vec3 n, vec3 h, float a){ @@ -65,8 +69,33 @@ vec3 lambertDiffuse(vec4 color){ void main() { vec4 finalColor = vec4(0, 0, 0, 1); vec3 normal = norm; + + if(normalMapEnabled) { + mat3 normMat = mat3(tan, biTan, norm); + vec3 n = texture(textures[1].pastTexture, texCoords).rgb; + normal = normMat * n; + } + vec3 viewDir = normalize(camPos - fragPos); - vec4 albedo = (albedoMapEnabled ? texture(textures[0].pastTexture, texCoords) : albedoColor); + + vec4 albedo = albedoColor; + + if(albedoMapEnabled) + albedo = texture(textures[0].pastTexture, texCoords); + + albedo.rgb = pow(albedo.rgb, vec3(1 / 2.2)); + + float roughness = roughnessVal; + + if(roughnessMapEnabled) + roughness = texture(textures[2].pastTexture, texCoords).r; + + float metalness = metalnessVal; + + if(metallnessMapEnabled) + metalness = texture(textures[3].pastTexture, texCoords).r; + + vec3 f0 = mix(vec3(.04), albedo.rgb, metalness); for(int i = 0; i < numLights; ++i){ vec3 lightDir; @@ -74,33 +103,43 @@ void main() { if(lights[i].type == 0){ lightDir = normalize(lights[i].pos - fragPos); - attenuation = 1 / (a * dist * dist + b * dist + c); + attenuation = 1 / (dist * dist); } else if(lights[i].type == 1){ lightDir = -normalize(lights[i].direction); } else if(lights[i].type == 2){ lightDir = normalize(lights[i].pos - fragPos); - attenuation = 1 / (a * dist * dist + b * dist + c); + attenuation = 1 / (dist * dist); } vec3 halfVec = normalize(lightDir + normal); float D = trowbridgeReitz(normal, halfVec, roughness * roughness); - float G = geoSmith(normal, halfVec, lightDir, 0.5 * roughness * roughness); - vec3 F = fresnelSchlick(viewDir, halfVec, baseReflectivity); - vec3 cookTor = D * G * F / max(4 * max(dot(viewDir, normal), 0) * max(dot(lightDir, normal), 0), .000001); + 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); + float nDotL = max(dot(lightDir, normal), 0); + vec3 cookTor = D * G * F / max(4 * nDotV * nDotL, .001); vec3 fDiff = lambertDiffuse(albedo); vec3 kDiff = (vec3(1) - F) * (1 - metalness); - finalColor.rgb += (kDiff * fDiff + cookTor) * lights[i].color * attenuation * max(dot(lightDir, normal), 0); + finalColor.rgb += (kDiff * fDiff + cookTor) * lights[i].color * attenuation * nDotL; } + float ao = ambientOcclusion; + + finalColor.rgb += vec3(.03) * albedo.rgb * ao; + float brightness = dot(finalColor.rgb, vec3(0.2126, 0.7152, 0.0722)); if(brightness > 1) BrightColor = vec4(finalColor.rgb, 1); + finalColor.rgb /= finalColor.rgb + vec3(1.0); + finalColor.rgb = pow(finalColor.rgb, vec3(1.0 / 2.2)); + FragColor = finalColor; } diff --git a/pbrSample.cpp b/pbrSample.cpp index 7026cdf..4403b46 100644 --- a/pbrSample.cpp +++ b/pbrSample.cpp @@ -28,21 +28,34 @@ int main() { Root *root = Root::getSingleton(); root->start(800, 600, PATH, "Light sample"); root->createSkybox(skyboxTextures); - root->setHDREnabled(true); Camera *cam = root->getCamera(); - cam->setPosition(Vector3(1, 1, 1) * 5); - cam->lookAt(Vector3(-1, -1, -1).norm(), Vector3(-1, 1, -1).norm()); + cam->setPosition(Vector3(1, 1, 0) * 5); + cam->lookAt(Vector3(-1, -1, 0).norm(), Vector3(-1, 1, 0).norm()); Node *rootNode = root->getRootNode(); Model *model = new Model(MODEL_PATH + "teapot.vb"); Material *mat = new Material(PATH + "pbr"); - mat->addBoolUniform("albedoMapEnabled", false); - mat->addVec4Uniform("albedoColor", Vector4(1, 1, 1, 1)); - mat->addFloatUniform("roughness", .1); - mat->addFloatUniform("metalness", .1); - mat->addVec3Uniform("baseReflectivity", Vector3(0.563, 0.579, 0.579)); + mat->addBoolUniform("albedoMapEnabled", true); + mat->addBoolUniform("normalMapEnabled", true); + mat->addBoolUniform("roughnessMapEnabled", true); + mat->addBoolUniform("metallnessMapEnabled", true); + string fr0[]{TEX_PATH + "rustediron2_albedo.jpg"}; + string fr1[]{TEX_PATH + "rustediron2_normal.jpg"}; + string fr2[]{TEX_PATH + "rustediron2_roughness.jpg"}; + string fr3[]{TEX_PATH + "rustediron2_metallic.jpg"}; + string fr4[]{TEX_PATH + "rustediron2_ao.jpg"}; + mat->addTexUniform("textures[0]", new Texture(fr0, 1), true); + mat->addTexUniform("textures[1]", new Texture(fr1, 1), true); + mat->addTexUniform("textures[2]", new Texture(fr2, 1), true); + mat->addTexUniform("textures[3]", new Texture(fr3, 1), true); + /* + mat->addVec4Uniform("albedoColor", Vector4(1, 0, 1, 1)); + mat->addFloatUniform("roughnessVal", .09); + mat->addFloatUniform("metalnessVal", .1); + mat->addFloatUniform("ambientOcclusion", 0); + */ /* mat = new Material(PATH + "texture"); mat->addBoolUniform("texturingEnabled", true); @@ -56,7 +69,7 @@ int main() { { Light *light = new Light(Light::POINT); light->setAttenuationValues(.00001, .00001, 1); - light->setColor(Vector3(1, 0, 0)); + light->setColor(Vector3(1, 1, 1)); light->setInnerAngle(.1); light->setOuterAngle(.1); Node *lightNode = new Node();