Skip to content

Commit

Permalink
Restore the Fresnel term in the BRDF.
Browse files Browse the repository at this point in the history
Was uncommented in 65fd37c, mostly likely by mistake since its important.

Also made a few corrections of specular -> specular_blob_intensity (gles2).
  • Loading branch information
tagcup committed Sep 30, 2018
1 parent 3ee657e commit e94f6aa
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 39 deletions.
44 changes: 25 additions & 19 deletions drivers/gles2/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -897,10 +897,11 @@ varying vec2 uv2_interp;

varying vec3 view_interp;

vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
float dielectric = (0.034 * 2.0) * specular;
// energy conservation
return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
vec3 F0(float metallic, float specular, vec3 albedo) {
float dielectric = 0.16 * specular * specular;
// use albedo * metallic as colored specular reflectance at 0 angle for metallic materials;
// see https://google.github.io/filament/Filament.md.html
return mix(vec3(dielectric), albedo, vec3(metallic));
}

/* clang-format off */
Expand Down Expand Up @@ -995,6 +996,7 @@ void light_compute(
float specular_blob_intensity,
float roughness,
float metallic,
float specular,
float rim,
float rim_tint,
float clearcoat,
Expand Down Expand Up @@ -1113,8 +1115,6 @@ LIGHT_SHADER_CODE

// D

float specular_brdf_NL;

#if defined(SPECULAR_BLINN)

//normalized blinn
Expand All @@ -1125,7 +1125,7 @@ LIGHT_SHADER_CODE
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float blinn = pow(cNdotH, shininess);
blinn *= (shininess + 8.0) / (8.0 * 3.141592654);
specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);
float specular_brdf_NL = (blinn) / max(4.0 * cNdotV * cNdotL, 0.75);

#elif defined(SPECULAR_PHONG)

Expand All @@ -1134,19 +1134,19 @@ LIGHT_SHADER_CODE
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float phong = pow(cRdotV, shininess);
phong *= (shininess + 8.0) / (8.0 * 3.141592654);
specular_brdf_NL = (phong) / max(4.0 * cNdotV * cNdotL, 0.75);
float specular_brdf_NL = (phong) / max(4.0 * cNdotV * cNdotL, 0.75);

#elif defined(SPECULAR_TOON)

vec3 R = normalize(-reflect(L, N));
float RdotV = dot(R, V);
float mid = 1.0 - roughness;
mid *= mid;
specular_brdf_NL = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid;
float specular_brdf_NL = smoothstep(mid - roughness * 0.5, mid + roughness * 0.5, RdotV) * mid;

#elif defined(SPECULAR_DISABLED)
// none..
specular_brdf_NL = 0.0;
float specular_brdf_NL = 0.0;
#elif defined(SPECULAR_SCHLICK_GGX)
// shlick+ggx as default

Expand All @@ -1173,11 +1173,11 @@ LIGHT_SHADER_CODE
float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
#endif
// F
//float F0 = 1.0;
//float cLdotH5 = SchlickFresnel(cLdotH);
//float F = mix(cLdotH5, 1.0, F0);
vec3 f0 = F0(metallic, specular, diffuse_color);
float cLdotH5 = SchlickFresnel(cLdotH);
vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);

specular_brdf_NL = cNdotL * D /* F */ * G;
vec3 specular_brdf_NL = cNdotL * D * F * G;

#endif

Expand Down Expand Up @@ -1282,6 +1282,11 @@ void main() {
float alpha = 1.0;
float side = 1.0;

float specular_blob_intensity = 1.0;
#if defined(SPECULAR_TOON)
specular_blob_intensity *= specular * 2.0;
#endif

#if defined(ENABLE_AO)
float ao = 1.0;
float ao_light_affect = 0.0;
Expand Down Expand Up @@ -1691,7 +1696,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_VERTEX_LIGHTING
//vertex lighting

specular_light += specular_interp * specular * light_att;
specular_light += specular_interp * specular_blob_intensity * light_att;
diffuse_light += diffuse_interp * albedo * light_att;

#else
Expand All @@ -1706,9 +1711,10 @@ FRAGMENT_SHADER_CODE
light_att,
albedo,
transmission,
specular * light_specular,
specular_blob_intensity * light_specular,
roughness,
metallic,
specular,
rim,
rim_tint,
clearcoat,
Expand Down Expand Up @@ -1755,10 +1761,10 @@ FRAGMENT_SHADER_CODE
vec4 r = roughness * c0 + c1;
float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;

vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo);
specular_light *= AB.x * specular_color + AB.y;
vec3 f0 = F0(metallic, specular, albedo);
specular_light *= env.x * f0 + env.y;
#endif
}

Expand Down
41 changes: 21 additions & 20 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -920,13 +920,14 @@ float GTR1(float NdotH, float a) {
return (a2 - 1.0) / (M_PI * log(a2) * t);
}

vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
float dielectric = (0.034 * 2.0) * specular;
// energy conservation
return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
vec3 F0(float metallic, float specular, vec3 albedo) {
float dielectric = 0.16 * specular * specular;
// use albedo * metallic as colored specular reflectance at 0 angle for metallic materials;
// see https://google.github.io/filament/Filament.md.html
return mix(vec3(dielectric), albedo, vec3(metallic));
}

void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {

#if defined(USE_LIGHT_SHADER_CODE)
// light is written by the light shader
Expand Down Expand Up @@ -1085,11 +1086,11 @@ LIGHT_SHADER_CODE
float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
#endif
// F
//float F0 = 1.0;
//float cLdotH5 = SchlickFresnel(cLdotH);
//float F = mix(cLdotH5, 1.0, F0);
vec3 f0 = F0(metallic, specular, diffuse_color);
float cLdotH5 = SchlickFresnel(cLdotH);
vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0);

float specular_brdf_NL = cNdotL * D /* F */ * G;
vec3 specular_brdf_NL = cNdotL * D * F * G;

specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif
Expand Down Expand Up @@ -1191,7 +1192,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif

void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {

vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz - vertex;
float light_length = length(light_rel_vec);
Expand Down Expand Up @@ -1245,10 +1246,10 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation *= mix(omni_lights[idx].shadow_color_contact.rgb, vec3(1.0), shadow);
}
#endif //SHADOWS_DISABLED
light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
}

void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {
void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) {

vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz - vertex;
float light_length = length(light_rel_vec);
Expand Down Expand Up @@ -1280,7 +1281,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
}
#endif //SHADOWS_DISABLED

light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
}

void reflection_process(int idx, vec3 vertex, vec3 normal, vec3 binormal, vec3 tangent, float roughness, float anisotropy, vec3 ambient, vec3 skybox, inout highp vec4 reflection_accum, inout highp vec4 ambient_accum) {
Expand Down Expand Up @@ -1895,7 +1896,7 @@ FRAGMENT_SHADER_CODE
specular_light *= mix(vec3(1.0), light_attenuation, specular_light_interp.a);

#else
light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light);
#endif

#endif //#USE_LIGHT_DIRECTIONAL
Expand Down Expand Up @@ -1969,11 +1970,11 @@ FRAGMENT_SHADER_CODE
#else

for (int i = 0; i < omni_light_count; i++) {
light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
}

for (int i = 0; i < spot_light_count; i++) {
light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light);
}

#endif //USE_VERTEX_LIGHTING
Expand All @@ -1994,7 +1995,7 @@ FRAGMENT_SHADER_CODE
diffuse_light *= ao_light_affect;
#endif

//energy conservation
// base color remapping
diffuse_light *= 1.0 - metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point
ambient_light *= 1.0 - metallic;

Expand All @@ -2011,10 +2012,10 @@ FRAGMENT_SHADER_CODE
vec4 r = roughness * c0 + c1;
float ndotv = clamp(dot(normal, eye_vec), 0.0, 1.0);
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;

vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo);
specular_light *= AB.x * specular_color + AB.y;
vec3 f0 = F0(metallic, specular, albedo);
specular_light *= env.x * f0 + env.y;
#endif
}

Expand Down

0 comments on commit e94f6aa

Please sign in to comment.