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

eevee_raytrace_resolve_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: 75b65052726cda17e458d13b89445e45d435e030 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106

/**
 * Final denoise step using a bilateral filter. Filter radius is controled by variance estimate.
 *
 * Inputs: Ray radiance (denoised), Mean hit depth, Extimated variance from ray reconstruction
 * Outputs: Ray radiance (filtered).
 *
 * Linear depth is packed in ray_radiance for this step.
 * Following "Stochastic All The Things: Raytracing in Hybrid Real-Time Rendering"
 * by Tomasz Stachowiak
 * https://www.ea.com/seed/news/seed-dd18-presentation-slides-raytracing
 */

#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_bsdf_microfacet_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_gbuffer_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)

#if defined(DIFFUSE)
#  define RADIUS 4
#elif defined(REFRACTION)
#  define RADIUS 1
#else
#  define RADIUS 1
#endif

float normal_pdf(float x_sqr, float sigma_inv, float sigma_inv_sqr)
{
  return exp(-0.5 * x_sqr * sigma_inv_sqr) * sigma_inv;
}

void main(void)
{
  vec2 uv = uvcoordsvar.xy;
  float ray_variance = texture(ray_variance_tx, uv).r;
  vec4 ray_data = texture(ray_radiance_tx, uv);
  float center_depth = ray_data.w;
  vec2 texel_size = hiz_buf.pixel_to_ndc * 0.5;

  out_combined = vec4(0.0);
  out_diffuse = vec4(0.0);
  out_specular = vec3(0.0);

#if defined(DIFFUSE)
  ClosureDiffuse closure = gbuffer_load_diffuse_data(cl_color_tx, cl_normal_tx, cl_data_tx, uv);
  if (closure.sss_radius.r < 0.0) {
    return;
  }
  float sigma_pixel = 3.0;
#elif defined(REFRACTION)
  ClosureRefraction closure = gbuffer_load_refraction_data(
      cl_color_tx, cl_normal_tx, cl_data_tx, uv);
  if (closure.ior == -1.0) {
    return;
  }
  float sigma_pixel = 1.0;
#else
  ClosureReflection closure = gbuffer_load_reflection_data(cl_color_tx, cl_normal_tx, uv);
  float sigma_pixel = 1.0;
#endif
  /* TODO(fclem): Sigma based on variance. */
  float sigma_depth = 0.1; /* TODO user option? */

  float px_sigma_inv = 1.0 / sigma_pixel;
  float px_sigma_inv_sqr = sqr(px_sigma_inv);
  float depth_sigma_inv = 1.0 / sigma_depth;
  float depth_sigma_inv_sqr = sqr(depth_sigma_inv);

  float weight_accum = normal_pdf(0.0, px_sigma_inv, px_sigma_inv_sqr);
  vec3 radiance_accum = ray_data.rgb * weight_accum;
  for (int x = -RADIUS; x <= RADIUS; x++) {
    for (int y = -RADIUS; y <= RADIUS; y++) {
      /* Skip center pixels. */
      if (x == 0 && y == 0) {
        continue;
      }
      vec2 sample_uv = uv + vec2(x, y) * texel_size;
      vec4 ray_data = texture(ray_radiance_tx, sample_uv);
      /* Skip unprocessed pixels. */
      if (ray_data.w == 0.0) {
        continue;
      }
      float delta_pixel_sqr = len_squared(vec2(x, y));
      float delta_depth_sqr = sqr(abs(center_depth - ray_data.w));
      /* TODO(fclem): OPTI might be a good idea to compare view normal to avoid one matrix mult. */
      vec3 sample_N = gbuffer_decode_normal(texture(cl_normal_tx, sample_uv).xy);
      /* Bilateral weight. */
      float weight = saturate(dot(sample_N, closure.N)) *
                     normal_pdf(delta_pixel_sqr, px_sigma_inv, px_sigma_inv_sqr) *
                     normal_pdf(delta_depth_sqr, depth_sigma_inv, depth_sigma_inv_sqr);

      radiance_accum += ray_data.rgb * weight;
      weight_accum += weight;
    }
  }
  radiance_accum *= safe_rcp(weight_accum);
  radiance_accum *= closure.color;

  out_combined = vec4(radiance_accum, 0.0);
#if defined(DIFFUSE)
  out_diffuse.rgb = radiance_accum;
#else
  out_specular = radiance_accum;
#endif
}