#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); }