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

volumetric_scatter_frag.glsl « shaders « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: dc755aeab8bb89d5fa2d8192018c479dd66fb357 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86

#pragma BLENDER_REQUIRE(volumetric_lib.glsl)

/* 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;

flat in int slice;

layout(location = 0) out vec4 outScattering;
layout(location = 1) out vec4 outTransmittance;

void main()
{
  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) + volJitter.xyz) * volInvTexSize.xyz);
  vec3 P = get_world_space_from_depth(volume_ndc.xy, volume_ndc.z);
  vec3 V = cameraVec(P);

  vec2 phase = texelFetch(volumePhase, volume_cell, 0).rg;
  float s_anisotropy = phase.x / max(1.0, phase.y);

  /* Environment : Average color. */
  outScattering.rgb += irradiance_volumetric(P) * s_scattering * phase_function_isotropic();

#ifdef VOLUME_LIGHTING /* Lights */
  for (int i = 0; i < MAX_LIGHT && i < laNumLight; i++) {
    LightData ld = lights_data[i];

    if (ld.l_volume == 0.0) {
      continue;
    }

    vec4 l_vector;
    l_vector.xyz = light_volume_light_vector(ld, P);
    l_vector.w = length(l_vector.xyz);

    float vis = light_visibility(ld, P, l_vector);

    if (vis < 1e-4) {
      continue;
    }

    vec3 Li = light_volume(ld, l_vector) * light_volume_shadow(ld, P, l_vector, volumeExtinction);

    outScattering.rgb += Li * vis * s_scattering *
                         phase_function(-V, 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) * volInvTexSize.xyz);
  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 ((volHistoryAlpha > 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, volHistoryAlpha);
    outTransmittance = mix(outTransmittance, h_Transmittance, volHistoryAlpha);
  }

  /* Catch NaNs */
  if (any(isnan(outScattering)) || any(isnan(outTransmittance))) {
    outScattering = vec4(0.0);
    outTransmittance = vec4(1.0);
  }
}