Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-07-04 15:47:06 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-07-05 19:03:36 +0300
commited4e62997ee86ffb337c5aee582379d5fd1628e9 (patch)
treea27c7ae8c2645bc0dbabaabb0569a79fd8758ed5 /source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
parent971ecfa72149ed9cd983cc6101a936d82c296ba7 (diff)
Eevee: Volumetrics: Match cycles scattering.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl64
1 files changed, 51 insertions, 13 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
index fe80fed232f..c0a46c93d9c 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
@@ -5,13 +5,19 @@ out vec4 FragColor;
uniform sampler2D depthFull;
-void participating_media_properties(vec3 wpos, out vec3 absorption, out vec3 scattering, out float anisotropy)
+void participating_media_properties(vec3 wpos, out vec3 extinction, out vec3 scattering, out float anisotropy)
{
Closure cl = nodetree_exec();
- absorption = cl.absorption;
scattering = cl.scatter;
anisotropy = cl.anisotropy;
+ extinction = max(vec3(1e-8), cl.absorption + cl.scatter); /* mu_t */
+}
+
+vec3 participating_media_extinction(vec3 wpos)
+{
+ Closure cl = nodetree_exec();
+ return max(vec3(1e-8), cl.absorption + cl.scatter); /* mu_t */
}
float phase_function_isotropic()
@@ -24,6 +30,7 @@ float phase_function(vec3 v, vec3 l, float g)
#if 1
/* Henyey-Greenstein */
float cos_theta = dot(v, l);
+ g = clamp(g, -1.0 + 1e-3, 1.0 - 1e-3);
float sqr_g = g * g;
return (1- sqr_g) / (4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0));
#else
@@ -31,10 +38,46 @@ float phase_function(vec3 v, vec3 l, float g)
#endif
}
-vec3 light_volume(LightData ld, vec4 l_vector, vec3 l_col)
+vec3 light_volume(LightData ld, vec4 l_vector)
{
+ float power;
float dist = max(1e-4, abs(l_vector.w - ld.l_radius));
- return l_col * (4.0 * ld.l_radius * ld.l_radius * M_PI * M_PI) / (dist * dist);
+ /* TODO : put this out of the shader. */
+ /* Removing Area Power. */
+ if (ld.l_type == AREA) {
+ power = 0.0962 * (ld.l_sizex * ld.l_sizey * 4.0f * M_PI);
+ }
+ else {
+ power = 0.0248 * (4.0 * ld.l_radius * ld.l_radius * M_PI * M_PI);
+ }
+ return ld.l_color * power / (l_vector.w * l_vector.w);
+}
+
+vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, vec3 s_extinction)
+{
+#ifdef VOLUME_SHADOW
+
+#ifdef VOLUME_HOMOGENEOUS
+ /* Simple extinction */
+ return exp(-s_extinction * l_vector.w);
+#else
+ /* Heterogeneous volume shadows */
+ const float numStep = 16.0;
+ float dd = l_vector.w / numStep;
+ vec3 L = l_vector.xyz * l_vector.w;
+ vec3 shadow = vec3(1.0);
+ /* start at 0.5 to sample at center of integral part */
+ for (float s = 0.5; s < (numStep - 0.1); s += 1.0) {
+ vec3 pos = ray_wpos + L * (s / numStep);
+ vec3 s_extinction = participating_media_extinction(pos);
+ shadow *= exp(-s_extinction * dd);
+ }
+ return shadow;
+#endif /* VOLUME_HOMOGENEOUS */
+
+#else
+ return vec3(1.0);
+#endif /* VOLUME_SHADOW */
}
float find_next_step(float near, float far, float noise, int iter, int iter_count)
@@ -96,11 +139,9 @@ void main()
vec3 ray_wpos = ray_origin + wdir_proj * dist;
/* Volume Sample */
- vec3 s_absorption, s_scattering; /* mu_a, mu_s */
+ vec3 s_extinction, s_scattering; /* mu_a, mu_t */
float s_anisotropy;
- participating_media_properties(ray_wpos, s_absorption, s_scattering, s_anisotropy);
-
- vec3 s_extinction = max(vec3(1e-8), s_absorption + s_scattering); /* mu_t */
+ participating_media_properties(ray_wpos, s_extinction, s_scattering, s_anisotropy);
/* Evaluate each light */
vec3 Lscat = vec3(0.0);
@@ -113,12 +154,9 @@ void main()
l_vector.xyz = ld.l_position - ray_wpos;
l_vector.w = length(l_vector.xyz);
-#if 1 /* Shadows & Spots */
float Vis = light_visibility(ld, ray_wpos, l_vector);
-#else
- float Vis = 1.0;
-#endif
- vec3 Li = light_volume(ld, l_vector, ld.l_color);
+
+ vec3 Li = light_volume(ld, l_vector) * light_volume_shadow(ld, ray_wpos, l_vector, s_extinction);
Lscat += Li * Vis * s_scattering * phase_function(-wdir, l_vector.xyz / l_vector.w, s_anisotropy);
}