Skip to content

Commit

Permalink
- Replaced max(dot(a,b), 0.0) with clamp as some rounding errors caus…
Browse files Browse the repository at this point in the history
…ed pow to receive negative values when then value was subtracted from 1.0 (undefined glsl behavior)

- Fixed that surface angle attenuation was getting applied twice
  • Loading branch information
dpjudas committed Feb 3, 2018
1 parent 7b9a334 commit 7698674
Showing 1 changed file with 52 additions and 47 deletions.
99 changes: 52 additions & 47 deletions wadsrc/static/shaders/glsl/main.fp
Expand Up @@ -432,29 +432,25 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}

float pointLightAttenuationQuadratic(vec4 lightpos, float lightcolorA)
float quadraticDistanceAttenuation(vec4 lightpos)
{
float strength = (1.0 + lightpos.w * lightpos.w * 0.25) * 0.5;

vec3 distVec = lightpos.xyz - pixelpos.xyz;
float attenuation = strength / (1.0 + dot(distVec, distVec));
if (attenuation <= 1.0 / 256.0) return 0.0;

return attenuation;
}

float shadowAttenuation(vec4 lightpos, float lightcolorA)
{
#ifdef SUPPORTS_SHADOWMAPS
float shadowIndex = abs(lightcolorA) - 1.0;
attenuation *= shadowmapAttenuation(lightpos, shadowIndex);
return shadowmapAttenuation(lightpos, shadowIndex);
#else
return 1.0;
#endif

if (lightcolorA >= 0.0) // Sign bit is the attenuated light flag
{
return attenuation;
}
else
{
vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz);
vec3 pixelnormal = ApplyNormalMap();
return attenuation * diffuseContribution(lightDirection, pixelnormal);
}
}

vec3 applyLight(vec3 albedo, vec3 ambientLight)
Expand All @@ -464,12 +460,11 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
albedo = pow(albedo, vec3(2.2)); // sRGB to linear
ambientLight = pow(ambientLight, vec3(2.2));

vec3 normal = ApplyNormalMap();
float metallic = texture(metallictexture, vTexCoord.st).r;
float roughness = texture(roughnesstexture, vTexCoord.st).r;
float ao = texture(aotexture, vTexCoord.st).r;

vec3 N = normalize(normal);
vec3 N = ApplyNormalMap();
vec3 V = normalize(uCameraPos.xyz - worldpos);

vec3 F0 = mix(vec3(0.04), albedo, metallic);
Expand All @@ -494,28 +489,33 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)

vec3 L = normalize(lightpos.xyz - worldpos);
vec3 H = normalize(V + L);
//float distance = length(lightpos.xyz - worldpos);
//float attenuation = 1.0 / (distance * distance);
float attenuation = pointLightAttenuationQuadratic(lightpos, lightcolor.a);

float attenuation = quadraticDistanceAttenuation(lightpos) * shadowAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
if (lightcolor.a < 0.0)
attenuation *= clamp(dot(N, L), 0.0, 1.0); // Sign bit is the attenuated light flag

if (attenuation > 0.0)
{
attenuation *= shadowAttenuation(lightpos, lightcolor.a);

vec3 radiance = lightcolor.rgb * attenuation;
vec3 radiance = lightcolor.rgb * attenuation;

// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);

vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);

vec3 nominator = NDF * G * F;
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
vec3 specular = nominator / max(denominator, 0.001);
vec3 nominator = NDF * G * F;
float denominator = 4.0 * clamp(dot(N, V), 0.0, 1.0) * clamp(dot(N, L), 0.0, 1.0);
vec3 specular = nominator / max(denominator, 0.001);

float NdotL = max(dot(N, L), 0.0);
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
Lo += (kD * albedo / PI + specular) * radiance;
}
}
//
// subtractive lights
Expand All @@ -529,36 +529,41 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)

vec3 L = normalize(lightpos.xyz - worldpos);
vec3 H = normalize(V + L);
//float distance = length(lightpos.xyz - worldpos);
//float attenuation = 1.0 / (distance * distance);
float attenuation = pointLightAttenuationQuadratic(lightpos, lightcolor.a);

float attenuation = quadraticDistanceAttenuation(lightpos) * shadowAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
if (lightcolor.a < 0.0)
attenuation *= clamp(dot(N, L), 0.0, 1.0); // Sign bit is the attenuated light flag

vec3 radiance = lightcolor.rgb * attenuation;
if (attenuation > 0.0)
{
attenuation *= shadowAttenuation(lightpos, lightcolor.a);

// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
vec3 radiance = lightcolor.rgb * attenuation;

vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);

vec3 nominator = NDF * G * F;
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
vec3 specular = nominator / max(denominator, 0.001);
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);

float NdotL = max(dot(N, L), 0.0);
Lo -= (kD * albedo / PI + specular) * radiance * NdotL;
vec3 nominator = NDF * G * F;
float denominator = 4.0 * clamp(dot(N, V), 0.0, 1.0) * clamp(dot(N, L), 0.0, 1.0);
vec3 specular = nominator / max(denominator, 0.001);

Lo -= (kD * albedo / PI + specular) * radiance;
}
}
}
}
#endif

// Pretend we sampled the sector light level from an irradiance map

vec3 F = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness);
vec3 F = fresnelSchlickRoughness(clamp(dot(N, V), 0.0, 1.0), F0, roughness);

vec3 kS = F;
vec3 kD = 1.0 - kS;
Expand All @@ -569,7 +574,7 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
//kD *= 1.0 - metallic;
//const float MAX_REFLECTION_LOD = 4.0;
//vec3 prefilteredColor = textureLod(prefilterMap, R, roughness * MAX_REFLECTION_LOD).rgb;
//vec2 envBRDF = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
//vec2 envBRDF = texture(brdfLUT, vec2(clamp(dot(N, V), 0.0, 1.0), roughness)).rg;
//vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);

//vec3 ambient = (kD * diffuse + specular) * ao;
Expand Down

0 comments on commit 7698674

Please sign in to comment.