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-10-24 15:49:00 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-10-27 23:49:15 +0300
commit66d8f82b832b58cba3273c0a4196fae6db0e1efd (patch)
tree682a3aba8fbd23ccd72a4e4f2a02fb36ad0a0d01 /source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
parent1c0c63ce5b3914be2d0828260e5ac777a7596d36 (diff)
Eevee: Overhaul the volumetric system.
The system now uses several 3D textures in order to decouple every steps of the volumetric rendering. See https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite for more details. On the technical side, instead of using a compute shader to populate the 3D textures we use layered rendering with a geometry shader to render 1 fullscreen triangle per 3D texture slice.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl83
1 files changed, 83 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
new file mode 100644
index 00000000000..ec695b2f0ac
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
@@ -0,0 +1,83 @@
+
+/* Based on Frosbite Unified Volumetric.
+ * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
+
+/* Step 2 : Evaluate all light scattering for each froxels.
+ * Also do the temporal reprojection to fight aliasing artifacts. */
+
+uniform sampler3D volumeScattering;
+uniform sampler3D volumeExtinction;
+uniform sampler3D volumeEmission;
+uniform sampler3D volumePhase;
+
+uniform sampler3D historyScattering;
+uniform sampler3D historyTransmittance;
+
+uniform vec3 volume_jitter;
+uniform float volume_history_alpha;
+uniform int light_count;
+uniform mat4 PastViewProjectionMatrix;
+
+flat in int slice;
+
+layout(location = 0) out vec4 outScattering;
+layout(location = 1) out vec4 outTransmittance;
+
+#define VOLUME_LIGHTING
+
+void main()
+{
+ vec3 volume_tex_size = vec3(textureSize(volumeScattering, 0));
+ ivec3 volume_cell = ivec3(gl_FragCoord.xy, slice);
+
+ /* Emission */
+ outScattering = texelFetch(volumeEmission, volume_cell, 0);
+ outTransmittance = texelFetch(volumeExtinction, volume_cell, 0);
+ vec3 s_scattering = texelFetch(volumeScattering, volume_cell, 0).rgb;
+ vec3 volume_ndc = volume_to_ndc((vec3(volume_cell) + volume_jitter) / volume_tex_size);
+ vec3 worldPosition = get_world_space_from_depth(volume_ndc.xy, volume_ndc.z);
+ vec3 wdir = cameraVec;
+
+ vec2 phase = texelFetch(volumePhase, volume_cell, 0).rg;
+ float s_anisotropy = phase.x / phase.y;
+
+ /* Environment : Average color. */
+ outScattering.rgb += irradiance_volumetric(worldPosition) * s_scattering * phase_function_isotropic();
+
+#ifdef VOLUME_LIGHTING /* Lights */
+ for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
+
+ LightData ld = lights_data[i];
+
+ vec4 l_vector;
+ l_vector.xyz = ld.l_position - worldPosition;
+ l_vector.w = length(l_vector.xyz);
+
+ float Vis = light_visibility(ld, worldPosition, l_vector);
+
+ vec3 Li = light_volume(ld, l_vector) * light_volume_shadow(ld, worldPosition, l_vector, volumeExtinction);
+
+ outScattering.rgb += Li * Vis * s_scattering * phase_function(-wdir, l_vector.xyz / l_vector.w, s_anisotropy);
+ }
+#endif
+
+ /* Temporal supersampling */
+ /* Note : this uses the cell non-jittered position (texel center). */
+ vec3 curr_ndc = volume_to_ndc(vec3(gl_FragCoord.xy, float(slice) + 0.5) / volume_tex_size);
+ vec3 wpos = get_world_space_from_depth(curr_ndc.xy, curr_ndc.z);
+ vec3 prev_ndc = project_point(PastViewProjectionMatrix, wpos);
+ vec3 prev_volume = ndc_to_volume(prev_ndc * 0.5 + 0.5);
+
+ if ((volume_history_alpha > 0.0) && all(greaterThan(prev_volume, vec3(0.0))) && all(lessThan(prev_volume, vec3(1.0)))) {
+ vec4 h_Scattering = texture(historyScattering, prev_volume);
+ vec4 h_Transmittance = texture(historyTransmittance, prev_volume);
+ outScattering = mix(outScattering, h_Scattering, volume_history_alpha);
+ outTransmittance = mix(outTransmittance, h_Transmittance, volume_history_alpha);
+ }
+
+ /* Catch NaNs */
+ if (any(isnan(outScattering)) || any(isnan(outTransmittance))) {
+ outScattering = vec4(0.0);
+ outTransmittance = vec4(0.0);
+ }
+}