75 lines
2.3 KiB
GLSL
75 lines
2.3 KiB
GLSL
|
#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);
|
||
|
}
|