Grafika_2024/projekt_grk/shaders/shader_pbr.frag

75 lines
2.3 KiB
GLSL
Raw Permalink Normal View History

2024-02-27 10:10:17 +01:00
#version 430 core
const float DIFFUSE_INTENSITY = 0.6;
const float MAX_RENDER_DISTANCE = 16.0;
float surfaceRoughness;
float metalnessValue;
uniform vec3 primaryColor;
uniform sampler2D colorTexture;
uniform sampler2D normalMap;
uniform sampler2D metalnessMap;
uniform sampler2D roughnessMap;
in vec3 worldPos;
in vec2 vecTex;
in vec3 viewDirTS;
in vec3 lightDirTS;
in float distanceToCamera;
out vec4 fragmentColor;
float calculateMicrofacetDistribution(float roughness, vec3 normal, vec3 halfVector) {
float NdotH = max(0.0, dot(normal, halfVector));
float roughnessSq = roughness * roughness;
float denom = 3.14159 * pow(NdotH * NdotH * (roughnessSq - 1.0) + 1.0, 2.0);
return roughnessSq / denom;
}
float calculateGeometryTerm(float roughness, float NdotV, float NdotL) {
float k = pow(roughness + 1.0, 2.0) / 8.0;
return NdotV / (NdotV * (1.0 - k) + k) * NdotL / (NdotL * (1.0 - k) + k);
}
vec3 calculateFresnelTerm(float metallic, vec3 F0, float VdotH) {
return F0 + (1.0 - F0) * pow(1.0 - VdotH, 5.0);
}
void main() {
vec3 textureColor = texture(colorTexture, vecTex).xyz;
metalnessValue = texture(metalnessMap, vecTex).r;
surfaceRoughness = texture(roughnessMap, vecTex).r;
vec3 normal = texture(normalMap, vecTex).xyz;
normal = normalize(normal);
vec3 viewDir = normalize(viewDirTS);
vec3 lightDir = normalize(lightDirTS);
vec3 halfVector = normalize(lightDir + viewDir);
float microfacetDistribution = calculateMicrofacetDistribution(surfaceRoughness, normal, halfVector);
float NdotV = max(0.0, dot(normal, viewDir));
float NdotL = max(dot(normal, lightDir), 0.0000001);
float geometryTerm = calculateGeometryTerm(surfaceRoughness, NdotV, NdotL);
vec3 F0 = mix(vec3(0.04), vec3(1.0), vec3(metalnessValue));
float VdotH = max(0.00001, dot(viewDir, halfVector));
vec3 fresnelTerm = calculateFresnelTerm(metalnessValue, F0, VdotH);
vec3 specular = (microfacetDistribution * geometryTerm * fresnelTerm) / (4.0 * NdotL * NdotV + 0.00001);
vec3 diffuseReflectance = vec3(1.0) - fresnelTerm;
vec3 BRDF = diffuseReflectance * (textureColor / 3.1458493) + specular;
if (distanceToCamera > MAX_RENDER_DISTANCE) {
discard;
}
float diffuse = max(0.0001, dot(normal, lightDir));
fragmentColor = vec4(BRDF * (DIFFUSE_INTENSITY + diffuse) * 1.5, 1.0);
}