Commit: 6e2f17ea02be5caa9eee8a68ccd558474030b29a
Author: Clément Foucault
Date:   Thu Aug 10 15:43:15 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB6e2f17ea02be5caa9eee8a68ccd558474030b29a

Eevee: Refraction: Add "thickness" parameter.

This enables to fake a second refraction event. This is great to simulate thin 
planar objects such as glass panels.

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

M       release/scripts/startup/bl_ui/properties_material.py
M       source/blender/draw/engines/eevee/eevee_materials.c
M       source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M       source/blender/gpu/shaders/gpu_shader_material.glsl
M       source/blender/makesdna/DNA_material_types.h
M       source/blender/makesrna/intern/rna_material.c

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

diff --git a/release/scripts/startup/bl_ui/properties_material.py 
b/release/scripts/startup/bl_ui/properties_material.py
index 02025f458e4..29cb2466ee5 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -1183,8 +1183,8 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, 
Panel):
         if mat.blend_method not in {"OPAQUE", "CLIP", "HASHED"}:
             layout.prop(mat, "transparent_hide_backside")
 
-        layout.prop(mat, "transparent_screen_refraction")
-
+        layout.prop(mat, "use_screen_refraction")
+        layout.prop(mat, "refraction_depth")
 
 
 classes = (
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c 
b/source/blender/draw/engines/eevee/eevee_materials.c
index cf27cba0b1a..517d7780719 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -353,7 +353,7 @@ static char *eevee_get_volume_defines(int options)
  **/
 static void add_standard_uniforms(
         DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data 
*vedata,
-        int *ssr_id, float *refract_thickness)
+        int *ssr_id, float *refract_depth, bool use_ssrefraction)
 {
        if (ssr_id == NULL) {
                static int no_ssr = -1.0f;
@@ -379,13 +379,15 @@ static void add_standard_uniforms(
        DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", 
&sldata->shadow_depth_cube_pool);
        DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", 
&sldata->shadow_depth_cascade_pool);
        DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
-       if (vedata->stl->effects->use_ao || refract_thickness) {
+       if (refract_depth != NULL) {
+               DRW_shgroup_uniform_float(shgrp, "refractionDepth", 
refract_depth, 1);
+       }
+       if (vedata->stl->effects->use_ao || use_ssrefraction) {
                DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float 
*)vedata->stl->g_data->viewvecs, 2);
                DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", 
&vedata->txl->maxzbuffer);
        }
-       if (refract_thickness) {
+       if (use_ssrefraction) {
                DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", 
&vedata->txl->refract_color);
-               DRW_shgroup_uniform_float(shgrp, "refractionThickness", 
refract_thickness, 1);
                DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", 
&vedata->stl->effects->ssr_quality, 1);
                DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", 
&vedata->stl->effects->ssr_border_fac, 1);
                DRW_shgroup_uniform_float(shgrp, "maxRoughness", 
&vedata->stl->effects->ssr_max_roughness, 1);
@@ -733,7 +735,7 @@ static struct DRWShadingGroup 
*EEVEE_default_shading_group_create(
        }
 
        DRWShadingGroup *shgrp = 
DRW_shgroup_create(e_data.default_lit[options], pass);
-       add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL);
+       add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false);
 
        return shgrp;
 }
@@ -763,7 +765,7 @@ static struct DRWShadingGroup 
*EEVEE_default_shading_group_get(
                vedata->psl->default_pass[options] = DRW_pass_create("Default 
Lit Pass", state);
 
                DRWShadingGroup *shgrp = 
DRW_shgroup_create(e_data.default_lit[options], 
vedata->psl->default_pass[options]);
-               add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL);
+               add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, 
false);
        }
 
        return DRW_shgroup_create(e_data.default_lit[options], 
vedata->psl->default_pass[options]);
@@ -944,10 +946,10 @@ static void material_opaque(
 
                *shgrp = DRW_shgroup_material_create(*gpumat, use_refract ? 
psl->refract_pass : psl->material_pass);
                if (*shgrp) {
-                       static int ssr_id;
-                       static float refract_thickness = 0.0f; /* TODO Param */
-                       ssr_id = (stl->effects->use_ssr) ? 0 : -1;
-                       add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, 
(use_refract) ? &refract_thickness : NULL);
+                       static int no_ssr = -1;
+                       static int first_ssr = 0;
+                       int *ssr_id = (stl->effects->use_ssr && !use_refract) ? 
&first_ssr : &no_ssr;
+                       add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, 
&ma->refract_depth, use_refract);
                }
                else {
                        /* Shader failed : pink color */
@@ -1036,9 +1038,7 @@ static void material_transparent(
                *shgrp = DRW_shgroup_material_create(*gpumat, 
psl->transparent_pass);
                if (*shgrp) {
                        static int ssr_id = -1; /* TODO transparent SSR */
-                       static float refract_thickness = 0.0f; /* TODO Param */
-                       add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id,
-                               (use_refract) ? &refract_thickness : NULL);
+                       add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, 
&ma->refract_depth, use_refract);
                }
                else {
                        /* Shader failed : pink color */
@@ -1272,7 +1272,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, 
EEVEE_SceneLayerData *sl
 
                                                                        shgrp = 
DRW_shgroup_material_create(gpumat, psl->material_pass);
                                                                        if 
(shgrp) {
-                                                                               
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL);
+                                                                               
add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false);
 
                                                                                
BLI_ghash_insert(material_hash, ma, shgrp);
 
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 b3559e3d366..4ee2e778c21 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -7,9 +7,7 @@ uniform int planar_count;
 uniform bool specToggle;
 uniform bool ssrToggle;
 
-#ifdef USE_REFRACTION
-uniform float refractionThickness;
-#endif
+uniform float refractionDepth;
 
 #ifndef UTIL_TEX
 #define UTIL_TEX
@@ -551,7 +549,7 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float 
roughness, float ao, int ss
 
 /* ----------- Transmission -----------  */
 
-vec3 eevee_surface_refraction(vec3 N, vec3 f0, float roughness, float ior, int 
ssr_id, out vec3 ssr_spec)
+vec3 eevee_surface_refraction(vec3 N, vec3 f0, float roughness, float ior)
 {
        /* Zero length vectors cause issues, see: T51979. */
 #if 0
@@ -581,16 +579,26 @@ vec3 eevee_surface_refraction(vec3 N, vec3 f0, float 
roughness, float ior, int s
        /* Accumulate light from all sources until accumulator is full. Then 
apply Occlusion and BRDF. */
        vec4 trans_accum = vec4(0.0);
 
+       /* Refract the view vector using the depth heuristic.
+        * Then later Refract a second time the already refracted
+        * ray using the inverse ior. */
+       float final_ior = (refractionDepth > 0.0) ? 1.0 / ior : ior;
+       vec3 refr_V = (refractionDepth > 0.0) ? -refract(-V, N, final_ior) : V;
+       vec3 refr_pos = (refractionDepth > 0.0) ? 
line_plane_intersect(worldPosition, refr_V, worldPosition - N * 
refractionDepth, N) : worldPosition;
+
 #ifdef USE_REFRACTION
        /* Screen Space Refraction */
        if (ssrToggle && roughness < maxRoughness + 0.2) {
                vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 
2.0)).xzw;
 
+               /* Find approximated position of the 2nd refraction event. */
+               vec3 refr_vpos = (refractionDepth > 0.0) ? 
transform_point(ViewMatrix, refr_pos) : viewPosition;
+
                float ray_ofs = 1.0 / float(rayCount);
-               vec4 spec = screen_space_refraction(viewPosition, N, V, ior, 
roughnessSquared, rand, 0.0);
-               if (rayCount > 1) spec += screen_space_refraction(viewPosition, 
N, V, ior, roughnessSquared, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
-               if (rayCount > 2) spec += screen_space_refraction(viewPosition, 
N, V, ior, roughnessSquared, rand.xzy * vec3(1.0,  1.0, -1.0), 2.0 * ray_ofs);
-               if (rayCount > 3) spec += screen_space_refraction(viewPosition, 
N, V, ior, roughnessSquared, rand.xzy * vec3(1.0, -1.0,  1.0), 3.0 * ray_ofs);
+               vec4 spec = screen_space_refraction(refr_vpos, N, refr_V, 
final_ior, roughnessSquared, rand, 0.0);
+               if (rayCount > 1) spec += screen_space_refraction(refr_vpos, N, 
refr_V, final_ior, roughnessSquared, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * 
ray_ofs);
+               if (rayCount > 2) spec += screen_space_refraction(refr_vpos, N, 
refr_V, final_ior, roughnessSquared, rand.xzy * vec3(1.0,  1.0, -1.0), 2.0 * 
ray_ofs);
+               if (rayCount > 3) spec += screen_space_refraction(refr_vpos, N, 
refr_V, final_ior, roughnessSquared, rand.xzy * vec3(1.0, -1.0,  1.0), 3.0 * 
ray_ofs);
                spec /= float(rayCount);
                spec.a *= smoothstep(maxRoughness + 0.2, maxRoughness, 
roughness);
                accumulate_light(spec.rgb, spec.a, trans_accum);
@@ -599,7 +607,7 @@ vec3 eevee_surface_refraction(vec3 N, vec3 f0, float 
roughness, float ior, int s
 
        /* Specular probes */
        /* NOTE: This bias the IOR */
-       vec3 spec_dir = get_specular_refraction_dominant_dir(N, V, roughness, 
ior);
+       vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, 
roughness, final_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) {
@@ -608,14 +616,14 @@ vec3 eevee_surface_refraction(vec3 N, vec3 f0, float 
roughness, float ior, int s
                float fade = probe_attenuation_cube(cd, worldPosition);
 
                if (fade > 0.0) {
-                       vec3 spec = probe_evaluate_cube(float(i), cd, 
worldPosition, spec_dir, roughnessSquared);
+                       vec3 spec = probe_evaluate_cube(float(i), cd, refr_pos, 
refr_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);
+               vec3 spec = probe_evaluate_world_spec(refr_dir, 
roughnessSquared);
                accumulate_light(spec, 1.0, trans_accum);
        }
 
@@ -701,9 +709,13 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, 
float roughness, float i
                }
        }
 
-       /* 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);
+       /* Refract the view vector using the depth heuristic.
+        * Then later Refract a second time the already refracted
+        * ray using the inverse ior. */
+       float final_ior = (refractionDepth > 0.0) ? 1.0 / ior : ior;
+       vec3 refr_V = (refractionDepth > 0.0) ? -refract(-V, N, final_ior) : V;
+       vec3 refr_pos = (refractionDepth > 0.0) ? 
line_plane_intersect(worldPosition, refr_V, worldPosition - N * 
refractionDepth, N) : worldPosition;
+
        vec4 trans_accum = vec4(0.0);
 
 #ifdef USE_REFRACTION
@@ -711,17 +723,24 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, 
float roughn

@@ 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