Fixed levels between specular, diffuse, ambient specular, ambiend diffuse and background sky

This commit is contained in:
Olivier Prat 2017-12-22 10:39:45 +01:00
parent cb4d78ce5c
commit a6d5e33eca
2 changed files with 17 additions and 15 deletions

View file

@ -22,9 +22,10 @@ vec4 evalSkyboxLight(vec3 direction, float lod) {
<@func declareEvalAmbientSpecularIrradiance(supportAmbientSphere, supportAmbientMap, supportIfAmbientMapElseAmbientSphere)@>
vec3 fresnelSchlickAmbient(vec3 fresnelColor, float ndotd, float gloss) {
vec3 fresnelSchlickAmbient(vec3 fresnelColor, float ndotd, float gloss) {
float f = pow(1.0 - ndotd, 5.0);
return fresnelColor + (max(vec3(gloss), fresnelColor) - fresnelColor) * f;
// return fresnelColor + (vec3(1.0) - fresnelColor) * f;
}
<@if supportAmbientMap@>
@ -40,14 +41,10 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, SurfaceData surface) {
<@if supportAmbientMap@>
{
float levels = getLightAmbientMapNumMips(ambient);
float lod = min(((surface.roughness)* levels), levels);
float m = 12.0 / (1.0+5.0*surface.roughness);
float lod = levels - m;
lod = max(lod, 0);
specularLight = evalSkyboxLight(lightDir, lod).xyz;
// We multiply specular by Pi to match specular / diffuse normalization in
// LightingModel.slh where diffuse and specular arent divided by Pi (when they should, rigourously
// speaking, based on physical equations). The spherical harmonics evaluation, on
// the other hand, seems to be Pi times stronger than usual. So all in all, everything
// should be at the right level now.
specularLight *= 3.1415926;
}
<@endif@>
<@if supportIfAmbientMapElseAmbientSphere@>
@ -56,6 +53,7 @@ vec3 evalAmbientSpecularIrradiance(LightAmbient ambient, SurfaceData surface) {
<@if supportAmbientSphere@>
{
specularLight = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lightDir).xyz;
specularLight /= 3.1415926;
}
<@endif@>
@ -99,7 +97,7 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie
// Diffuse from ambient
diffuse = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lowNormalCurvature.xyz).xyz;
diffuse /= 3.1415926;
specular = vec3(0.0);
}
<@endif@>

View file

@ -183,10 +183,7 @@ float specularDistribution(SurfaceData surface) {
// Add geometric factors G1(n,l) and G1(n,v)
float smithInvG1NdotL = evalSmithInvG1(surface.roughness4, surface.ndotl);
denom *= surface.smithInvG1NdotV * smithInvG1NdotL;
// Don't divide by PI as diffuse isn't either. The real PBR formula normalizes
// by PI on both but if we decide to not do it, it is just as if we
// multiplied all our lights by PI
//denom *= 3.1415926;
// Don't divide by PI as it will be done later
float power = surface.roughness4 / denom;
return power;
}
@ -200,8 +197,11 @@ vec4 evalPBRShading(float metallic, vec3 fresnel, SurfaceData surface) {
vec3 fresnelColor = fresnelSchlickColor(fresnel, surface);
float power = specularDistribution(surface);
vec3 specular = fresnelColor * power * angleAttenuation;
float diffuse = (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x);
return vec4(specular, (1.0 - metallic) * angleAttenuation * (1.0 - fresnelColor.x));
specular /= 3.1415926;
diffuse /= 3.1415926;
return vec4(specular, diffuse);
}
// Frag Shading returns the diffuse amount as W and the specular rgb as xyz
@ -213,8 +213,11 @@ vec4 evalPBRShadingDielectric(SurfaceData surface, float fresnel) {
float fresnelScalar = fresnelSchlickScalar(fresnel, surface);
float power = specularDistribution(surface);
vec3 specular = vec3(fresnelScalar) * power * angleAttenuation;
float diffuse = angleAttenuation * (1.0 - fresnelScalar);
return vec4(specular, angleAttenuation * (1.0 - fresnelScalar));
specular /= 3.1415926;
diffuse /= 3.1415926;
return vec4(specular, diffuse);
}
vec4 evalPBRShadingMetallic(SurfaceData surface, vec3 fresnel) {
@ -226,6 +229,7 @@ vec4 evalPBRShadingMetallic(SurfaceData surface, vec3 fresnel) {
float power = specularDistribution(surface);
vec3 specular = fresnelColor * power * angleAttenuation;
specular /= 3.1415926;
return vec4(specular, 0.f);
}