mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 23:11:58 +00:00
- Replaced max(dot(a,b), 0.0) with clamp as some rounding errors caused 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
This commit is contained in:
parent
7b9a334f77
commit
769867475c
1 changed files with 52 additions and 47 deletions
|
@ -432,7 +432,7 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
|
||||||
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
|
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;
|
float strength = (1.0 + lightpos.w * lightpos.w * 0.25) * 0.5;
|
||||||
|
|
||||||
|
@ -440,21 +440,17 @@ float pointLightAttenuationQuadratic(vec4 lightpos, float lightcolorA)
|
||||||
float attenuation = strength / (1.0 + dot(distVec, distVec));
|
float attenuation = strength / (1.0 + dot(distVec, distVec));
|
||||||
if (attenuation <= 1.0 / 256.0) return 0.0;
|
if (attenuation <= 1.0 / 256.0) return 0.0;
|
||||||
|
|
||||||
|
return attenuation;
|
||||||
|
}
|
||||||
|
|
||||||
|
float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
||||||
|
{
|
||||||
#ifdef SUPPORTS_SHADOWMAPS
|
#ifdef SUPPORTS_SHADOWMAPS
|
||||||
float shadowIndex = abs(lightcolorA) - 1.0;
|
float shadowIndex = abs(lightcolorA) - 1.0;
|
||||||
attenuation *= shadowmapAttenuation(lightpos, shadowIndex);
|
return shadowmapAttenuation(lightpos, shadowIndex);
|
||||||
|
#else
|
||||||
|
return 1.0;
|
||||||
#endif
|
#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)
|
vec3 applyLight(vec3 albedo, vec3 ambientLight)
|
||||||
|
@ -464,12 +460,11 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
|
||||||
albedo = pow(albedo, vec3(2.2)); // sRGB to linear
|
albedo = pow(albedo, vec3(2.2)); // sRGB to linear
|
||||||
ambientLight = pow(ambientLight, vec3(2.2));
|
ambientLight = pow(ambientLight, vec3(2.2));
|
||||||
|
|
||||||
vec3 normal = ApplyNormalMap();
|
|
||||||
float metallic = texture(metallictexture, vTexCoord.st).r;
|
float metallic = texture(metallictexture, vTexCoord.st).r;
|
||||||
float roughness = texture(roughnesstexture, vTexCoord.st).r;
|
float roughness = texture(roughnesstexture, vTexCoord.st).r;
|
||||||
float ao = texture(aotexture, vTexCoord.st).r;
|
float ao = texture(aotexture, vTexCoord.st).r;
|
||||||
|
|
||||||
vec3 N = normalize(normal);
|
vec3 N = ApplyNormalMap();
|
||||||
vec3 V = normalize(uCameraPos.xyz - worldpos);
|
vec3 V = normalize(uCameraPos.xyz - worldpos);
|
||||||
|
|
||||||
vec3 F0 = mix(vec3(0.04), albedo, metallic);
|
vec3 F0 = mix(vec3(0.04), albedo, metallic);
|
||||||
|
@ -494,28 +489,33 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
|
||||||
|
|
||||||
vec3 L = normalize(lightpos.xyz - worldpos);
|
vec3 L = normalize(lightpos.xyz - worldpos);
|
||||||
vec3 H = normalize(V + L);
|
vec3 H = normalize(V + L);
|
||||||
//float distance = length(lightpos.xyz - worldpos);
|
|
||||||
//float attenuation = 1.0 / (distance * distance);
|
float attenuation = quadraticDistanceAttenuation(lightpos) * shadowAttenuation(lightpos, lightcolor.a);
|
||||||
float attenuation = pointLightAttenuationQuadratic(lightpos, lightcolor.a);
|
|
||||||
if (lightspot1.w == 1.0)
|
if (lightspot1.w == 1.0)
|
||||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
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
|
vec3 radiance = lightcolor.rgb * attenuation;
|
||||||
float NDF = DistributionGGX(N, H, roughness);
|
|
||||||
float G = GeometrySmith(N, V, L, roughness);
|
|
||||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
|
||||||
|
|
||||||
vec3 kS = F;
|
// cook-torrance brdf
|
||||||
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
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;
|
vec3 kS = F;
|
||||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
|
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
||||||
vec3 specular = nominator / max(denominator, 0.001);
|
|
||||||
|
|
||||||
float NdotL = max(dot(N, L), 0.0);
|
vec3 nominator = NDF * G * F;
|
||||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// subtractive lights
|
// subtractive lights
|
||||||
|
@ -529,28 +529,33 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
|
||||||
|
|
||||||
vec3 L = normalize(lightpos.xyz - worldpos);
|
vec3 L = normalize(lightpos.xyz - worldpos);
|
||||||
vec3 H = normalize(V + L);
|
vec3 H = normalize(V + L);
|
||||||
//float distance = length(lightpos.xyz - worldpos);
|
|
||||||
//float attenuation = 1.0 / (distance * distance);
|
float attenuation = quadraticDistanceAttenuation(lightpos) * shadowAttenuation(lightpos, lightcolor.a);
|
||||||
float attenuation = pointLightAttenuationQuadratic(lightpos, lightcolor.a);
|
|
||||||
if (lightspot1.w == 1.0)
|
if (lightspot1.w == 1.0)
|
||||||
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
|
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
|
vec3 radiance = lightcolor.rgb * attenuation;
|
||||||
float NDF = DistributionGGX(N, H, roughness);
|
|
||||||
float G = GeometrySmith(N, V, L, roughness);
|
|
||||||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
|
||||||
|
|
||||||
vec3 kS = F;
|
// cook-torrance brdf
|
||||||
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
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;
|
vec3 kS = F;
|
||||||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
|
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
|
||||||
vec3 specular = nominator / max(denominator, 0.001);
|
|
||||||
|
|
||||||
float NdotL = max(dot(N, L), 0.0);
|
vec3 nominator = NDF * G * F;
|
||||||
Lo -= (kD * albedo / PI + specular) * radiance * NdotL;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -558,7 +563,7 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
|
||||||
|
|
||||||
// Pretend we sampled the sector light level from an irradiance map
|
// 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 kS = F;
|
||||||
vec3 kD = 1.0 - kS;
|
vec3 kD = 1.0 - kS;
|
||||||
|
@ -569,7 +574,7 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
|
||||||
//kD *= 1.0 - metallic;
|
//kD *= 1.0 - metallic;
|
||||||
//const float MAX_REFLECTION_LOD = 4.0;
|
//const float MAX_REFLECTION_LOD = 4.0;
|
||||||
//vec3 prefilteredColor = textureLod(prefilterMap, R, roughness * MAX_REFLECTION_LOD).rgb;
|
//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 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
|
||||||
|
|
||||||
//vec3 ambient = (kD * diffuse + specular) * ao;
|
//vec3 ambient = (kD * diffuse + specular) * ao;
|
||||||
|
|
Loading…
Reference in a new issue