diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-11-22 06:51:21 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-11-22 06:51:21 +0300 |
commit | 846cdf53187174ac87dd24af4b7b0d413db4ad03 (patch) | |
tree | 11139716a842f878f7d350a3cffeb6e4ecfbf02c /source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl | |
parent | ff810f08d8670b3d016e865e9b32df44c270ddaa (diff) |
Eevee : SSS : Add Translucency support.
This adds the possibility to simulate things like red ears with strong backlight or material with high scattering distances.
To enable it you need to turn on the "Subsurface Translucency" option in the "Options" tab of the Material Panel (and of course to have "regular" SSS enabled in both render settings and material options).
Since the effect is adding another overhead I prefer to make it optional. But this is open to discussion.
Be aware that the effect only works for direct lights (so no indirect/world lighting) that have shadowmaps, and is affected by the "softness" of the shadowmap and resolution.
Technical notes:
This is inspired by http://www.iryoku.com/translucency/ but goes a bit beyond that.
We do not use a sum of gaussian to apply in regards to the object thickness but we precompute a 1D kernel texture.
This texture stores the light transmited to a point at the back of an infinite slab of material of variying thickness.
We make the assumption that the slab is perpendicular to the light so that no fresnel or diffusion term is taken into account.
The light is considered constant.
If the setup is similar to the one assume during the profile baking, the realtime render matches cycles reference.
Due to these assumptions the computed transmitted light is in most cases too bright for curvy objects.
Finally we jitter the shadow map sample per pixel so we can simulate dispersion inside the medium.
Radius of the dispersion is in world space and derived by from the "soft" shadowmap parameter.
Idea for this come from this presentation http://www.iryoku.com/stare-into-the-future (slide 164).
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl')
-rw-r--r-- | source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl | 58 |
1 files changed, 58 insertions, 0 deletions
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 f63a9665810..44410be700b 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -810,3 +810,61 @@ vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float i return out_light; } + +/* ----------- Translucency ----------- */ + +vec3 eevee_surface_translucent_lit(vec3 N, vec3 albedo, float sss_scale) +{ +#ifndef USE_TRANSLUCENCY + return vec3(0.0); +#endif + + vec3 V = cameraVec; + + /* 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 + + /* We only enlit the backfaces */ + N = -N; + + /* ---------------- SCENE LAMPS LIGHTING ----------------- */ + +#ifdef HAIR_SHADER + vec3 norm_view = cross(V, N); + norm_view = normalize(cross(norm_view, N)); /* Normal facing view */ +#endif + + vec3 diff = 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); + +#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); + + diff += ld.l_color * light_translucent(ld, worldPosition, norm_lamp, l_vector, sss_scale) * occlu_trans; +#else + diff += ld.l_color * light_translucent(ld, worldPosition, N, l_vector, sss_scale); +#endif + } + + /* Accumulate outgoing radiance */ + vec3 out_light = diff * albedo; + + return out_light; +} |