Commit: e0078cd953e67dcf12b9d48ec3625a33ff0d1a8c
Author: Clément Foucault
Date:   Fri Aug 4 18:47:41 2017 +0200
Branches: blender2.8
https://developer.blender.org/rBe0078cd953e67dcf12b9d48ec3625a33ff0d1a8c

Eevee: Add Refraction via probes.

===================================================================

M       release/scripts/startup/nodeitems_builtins.py
M       source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M       source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M       source/blender/gpu/shaders/gpu_shader_material.glsl

===================================================================

diff --git a/release/scripts/startup/nodeitems_builtins.py 
b/release/scripts/startup/nodeitems_builtins.py
index 6f226e8cf87..2ab47c2575d 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -265,8 +265,8 @@ shader_node_categories = [
         NodeItem("ShaderNodeBsdfPrincipled", 
poll=object_eevee_cycles_shader_nodes_poll),
         NodeItem("ShaderNodeBsdfGlossy", 
poll=object_eevee_cycles_shader_nodes_poll),
         NodeItem("ShaderNodeBsdfTransparent", 
poll=object_cycles_shader_nodes_poll),
-        NodeItem("ShaderNodeBsdfRefraction", 
poll=object_cycles_shader_nodes_poll),
-        NodeItem("ShaderNodeBsdfGlass", poll=object_cycles_shader_nodes_poll),
+        NodeItem("ShaderNodeBsdfRefraction", 
poll=object_eevee_cycles_shader_nodes_poll),
+        NodeItem("ShaderNodeBsdfGlass", 
poll=object_eevee_cycles_shader_nodes_poll),
         NodeItem("ShaderNodeBsdfTranslucent", 
poll=object_cycles_shader_nodes_poll),
         NodeItem("ShaderNodeBsdfAnisotropic", 
poll=object_cycles_shader_nodes_poll),
         NodeItem("ShaderNodeBsdfVelvet", poll=object_cycles_shader_nodes_poll),
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl 
b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 61ccfe665fc..f5ddbd0679c 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -294,6 +294,69 @@ float specular_occlusion(float NV, float AO, float 
roughness)
        return saturate(pow(NV + AO, roughness) - 1.0 + AO);
 }
 
+/* --- Refraction utils --- */
+
+float ior_from_f0(float f0)
+{
+       float f = sqrt(f0);
+       return (-f - 1.0) / (f - 1.0);
+}
+
+float f0_from_ior(float eta)
+{
+       float A = (eta - 1.0) / (eta + 1.0);
+       return A * A;
+}
+
+vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, 
float ior)
+{
+       /* TODO: This a bad approximation. Better approximation should fit
+        * the refracted vector and roughness into the best prefiltered 
reflection
+        * lobe. */
+       /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or 
the TIR */
+       ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior;
+       float eta = 1.0 / ior;
+
+       float NV = dot(N, -V);
+
+       /* Custom Refraction. */
+       float k = 1.0 - eta * eta * (1.0 - NV * NV);
+       k = max(0.0, k); /* Only this changes. */
+       vec3 R = eta * -V - (eta * NV + sqrt(k)) * N;
+
+       return R;
+}
+
+float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, 
float ior)
+{
+       const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) 
/ LUT_SIZE;
+
+       vec3 coords;
+       /* Try to compensate for the low resolution and interpolation error. */
+       coords.x = (ior > 1.0)
+                  ? (0.9 + lut_scale_bias_texel_size.z) + (0.1 - 
lut_scale_bias_texel_size.z) * f0_from_ior(ior)
+                  : (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
+       coords.y = 1.0 - NV;
+       coords.xy *= lut_scale_bias_texel_size.x;
+       coords.xy += lut_scale_bias_texel_size.y;
+
+       const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
+       const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the 
lut. */
+
+       float mip = roughness * lut_lvl_scale;
+       float mip_floor = floor(mip);
+
+       coords.z = lut_lvl_ofs + mip_floor + 1.0;
+       float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r;
+
+       coords.z -= 1.0;
+       float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r;
+
+       float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - 
coords.z);
+
+       return btdf;
+}
+
 /* ---- Encode / Decode Normal buffer data ---- */
 /* From http://aras-p.info/texts/CompactNormalStorage.html
  * Using Method #4: Spheremap Transform */
@@ -314,6 +377,32 @@ vec3 normal_decode(vec2 enc, vec3 view)
     return n;
 }
 
+/* Fresnel monochromatic, perfect mirror */
+float F_eta(float eta, float cos_theta)
+{
+       /* compute fresnel reflectance without explicitly computing
+        * the refracted direction */
+       float c = abs(cos_theta);
+       float g = eta * eta - 1.0 + c * c;
+       float result;
+
+       if (g > 0.0) {
+               g = sqrt(g);
+               vec2 g_c = vec2(g) + vec2(c, -c);
+               float A = g_c.y / g_c.x;
+               A *= A;
+               g_c *= c;
+               float B = (g_c.y - 1.0) / (g_c.x + 1.0);
+               B *= B;
+               result = 0.5 * A * (1.0 + B);
+       }
+       else {
+               result = 1.0;  /* TIR (no refracted component) */
+       }
+
+       return result;
+}
+
 /* Fresnel */
 vec3 F_schlick(vec3 f0, float cos_theta)
 {
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl 
b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 71c327940ae..9e5b0472513 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -544,3 +544,192 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float 
roughness, float ao, int ss
 
        return out_light;
 }
+
+/* ----------- Transmission -----------  */
+
+vec3 eevee_surface_refraction(vec3 N, vec3 f0, float roughness, float ior, int 
ssr_id, out vec3 ssr_spec)
+{
+       /* Zero length vectors cause issues, see: T51979. */
+#if 0
+       N = normalize(N);
+#else
+       {
+               float len = length(N);
+               if (isnan(len)) {
+                       return vec3(0.0);
+               }
+               N /= len;
+       }
+#endif
+       vec3 V = cameraVec;
+       ior = (gl_FrontFacing) ? ior : 1.0 / ior;
+
+       roughness = clamp(roughness, 1e-8, 0.9999);
+       float roughnessSquared = roughness * roughness;
+
+       /* ---------------- SCENE LAMPS LIGHTING ----------------- */
+
+       /* No support for now. Supporting LTCs mean having a 3D LUT.
+        * We could support point lights easily though. */
+
+       /* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
+
+       /* Accumulate light from all sources until accumulator is full. Then 
apply Occlusion and BRDF. */
+       vec4 trans_accum = vec4(0.0);
+
+       /* Specular probes */
+       vec3 spec_dir = get_specular_refraction_dominant_dir(N, V, roughness, 
ior);
+
+       /* Starts at 1 because 0 is world probe */
+       for (int i = 1; i < MAX_PROBE && i < probe_count && trans_accum.a < 
0.999; ++i) {
+               CubeData cd = probes_data[i];
+
+               float fade = probe_attenuation_cube(cd, worldPosition);
+
+               if (fade > 0.0) {
+                       vec3 spec = probe_evaluate_cube(float(i), cd, 
worldPosition, spec_dir, roughnessSquared);
+                       accumulate_light(spec, fade, trans_accum);
+               }
+       }
+
+       /* World Specular */
+       if (trans_accum.a < 0.999) {
+               vec3 spec = probe_evaluate_world_spec(spec_dir, 
roughnessSquared);
+               accumulate_light(spec, 1.0, trans_accum);
+       }
+
+       float btdf = get_btdf_lut(utilTex, dot(N, V), roughness, ior);
+
+       return trans_accum.rgb * btdf;
+}
+
+vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float 
ior, int ssr_id, out vec3 ssr_spec)
+{
+       /* Zero length vectors cause issues, see: T51979. */
+#if 0
+       N = normalize(N);
+#else
+       {
+               float len = length(N);
+               if (isnan(len)) {
+                       return vec3(0.0);
+               }
+               N /= len;
+       }
+#endif
+       vec3 V = cameraVec;
+       ior = (gl_FrontFacing) ? ior : 1.0 / ior;
+
+       if (!specToggle) return vec3(0.0);
+
+       roughness = clamp(roughness, 1e-8, 0.9999);
+       float roughnessSquared = roughness * roughness;
+
+       /* ---------------- SCENE LAMPS LIGHTING ----------------- */
+
+#ifdef HAIR_SHADER
+       vec3 norm_view = cross(V, N);
+       norm_view = normalize(cross(norm_view, N)); /* Normal facing view */
+#endif
+
+       vec3 spec = vec3(0.0);
+       for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
+               LightData ld = lights_data[i];
+
+               vec4 l_vector; /* Non-Normalized Light Vector with length in 
last component. */
+               l_vector.xyz = ld.l_position - worldPosition;
+               l_vector.w = length(l_vector.xyz);
+
+               vec3 l_color_vis = ld.l_color * light_visibility(ld, 
worldPosition, l_vector);
+
+#ifdef HAIR_SHADER
+               vec3 norm_lamp, view_vec;
+               float occlu_trans, occlu;
+               light_hair_common(ld, N, V, l_vector, norm_view, occlu_trans, 
occlu, norm_lamp, view_vec);
+
+               spec += l_color_vis * light_specular(ld, N, view_vec, l_vector, 
roughnessSquared, vec3(1.0)) * occlu;
+#else
+               spec += l_color_vis * light_specular(ld, N, V, l_vector, 
roughnessSquared, vec3(1.0));
+#endif
+       }
+
+       /* Accumulate outgoing radiance */
+       vec3 out_light = spec;
+
+#ifdef HAIR_SHADER
+       N = -norm_view;
+#endif
+
+
+       /* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
+
+       /* Accumulate light from all sources until accumulator is full. Then 
apply Occlusion and BRDF. */
+       vec4 spec_accum = vec4(0.0);
+
+       /* Planar Reflections */
+       if (!(ssrToggle && ssr_id == outputSsrId)) {
+               for (int i = 0; i < MAX_PLANAR && i < planar_count && 
spec_accum.a < 0.999 && roughness < 0.1; ++i) {
+                       PlanarData pd = planars_data[i];
+
+                       float fade = probe_attenuation_planar(pd, 
worldPosition, N, roughness);
+
+                       if (fade > 0.0) {
+                               vec3 spec = probe_evaluate_planar(float(i), pd, 
worldPosition, N, V, roughness, fade);
+                               accumulate_light(spec, fade, spec_accum);
+                       }
+               }
+       }
+
+       /* Specular probes */
+       vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, 
roughnessSquared);
+       vec3 refr_dir = get_specular_refraction_dominant_dir(N, V, roughness, 
ior);
+       vec4 trans_accum = vec4(0.0);
+
+       /* Starts at 1 because 0 is world probe */
+       for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 
0.999 && trans_accum.a < 0.999; ++i) {
+               CubeData cd = probes_data[i];
+
+               float fade = probe_attenuation_cube(cd, worldPosition);
+
+               if (fade > 0.0) {
+                       if (!(ssrToggle && ssr_id == outputSsrId)) {
+                               vec3 spec = probe_evaluate_cube(float(i), cd, 
worldPosition, spec_dir, roughness);
+                               accumulate_light(spec, fade, spec_accum);
+
+                               spec = probe_evaluate_cube(float(i), cd, 
worldPosition, refr_dir, roughnessSquared);
+                               accumulate_light(spec, fade, trans_accum);
+                       }
+               }
+       }
+
+       /* World Specular */
+       if (spec_accum.a < 0.999) {
+               if (!(ssrToggle && ssr_id == outputSsrId)) {
+                       vec3 spec = probe_evaluate_world_spec(spec_dir, 
roughness);
+                       accumulate_light(spec, 1.0, spec_accum);
+
+                       spec = probe_evaluate_world_spec(refr_dir, 
roughnessSquared);
+                       accumulate_light(spec, 1.0, trans_accum);
+               }
+       }
+
+       /* Ambient Occlusion */
+       /* TODO : when AO will be cheaper */
+       float final_ao = 1.0;
+
+       float NV = dot(N, V);
+       /* Get Brdf intensity */
+       vec2 uv = lut_coords(NV, roughness);
+       vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
+
+       

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to