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

eevee_lightprobe_eval_grid_lib.glsl « shaders « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ef8a7c3678bd03763637f35e80c1a697d515cb70 (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

/**
 * The resources expected to be defined are:
 * - probes_buf
 * - lightprobe_grid_tx
 * - grids
 */

#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_irradiance_lib.glsl)

float lightprobe_grid_weight(GridData grid, vec3 P)
{
  vec3 lP = transform_point(grid.local_mat, P);
  vec3 pos_to_edge = max(vec3(0.0), abs(lP) - 1.0);
  float fade = length(pos_to_edge);
  return saturate(-fade * grid.attenuation_scale + grid.attenuation_bias);
}

vec3 lightprobe_grid_evaluate(
    GridInfoData info, sampler2DArray grid_tx, GridData grid, vec3 P, vec3 N)
{
  vec3 lP = transform_point(grid.local_mat, P) * 0.5 + 0.5;
  lP = lP * vec3(grid.resolution) - 0.5;

  ivec3 lP_floored = ivec3(floor(lP));
  vec3 trilinear_weight = fract(lP);

  if (grid.offset == 0) {
    N = transform_direction(info.lookdev_rotation, N);
  }

  float weight_accum = 0.0;
  vec3 irradiance_accum = vec3(0.0);
  /* For each neighbor cells */
  for (int i = 0; i < 8; i++) {
    ivec3 offset = ivec3(i, i >> 1, i >> 2) & ivec3(1);
    ivec3 cell_coord = clamp(lP_floored + offset, ivec3(0), grid.resolution - 1);
    /* Skip cells not yet rendered during baking. */
    cell_coord = (cell_coord / grid.level_skip) * grid.level_skip;
    /* Keep in sync with update_irradiance_probe. */
    int cell_id = grid.offset + cell_coord.z + cell_coord.y * grid.resolution.z +
                  cell_coord.x * grid.resolution.z * grid.resolution.y;

    vec3 color = irradiance_load_cell(info, grid_tx, cell_id, N);

    /* We need this because we render probes in world space (so we need light vector in WS).
     * And rendering them in local probe space is too much problem. */
    mat4 cell_to_world = mat4(vec4(grid.increment_x, 0.0),
                              vec4(grid.increment_y, 0.0),
                              vec4(grid.increment_z, 0.0),
                              vec4(grid.corner, 1.0));
    vec3 ws_cell_location = transform_point(cell_to_world, vec3(cell_coord));

    vec3 ws_point_to_cell = ws_cell_location - P;
    float ws_dist_point_to_cell = length(ws_point_to_cell);
    vec3 ws_light = ws_point_to_cell / ws_dist_point_to_cell;

    /* Smooth backface test. */
    float weight = saturate(dot(ws_light, N));
    /* Precomputed visibility. */
    weight *= visibility_load_cell(info,
                                   grid_tx,
                                   cell_id,
                                   ws_light,
                                   ws_dist_point_to_cell,
                                   grid.visibility_bias,
                                   grid.visibility_bleed,
                                   grid.visibility_range);
    /* Smoother transition. */
    weight += info.irradiance_smooth;
    /* Trilinear weights. */
    vec3 trilinear = mix(1.0 - trilinear_weight, trilinear_weight, offset);
    weight *= trilinear.x * trilinear.y * trilinear.z;
    /* Avoid zero weight. */
    weight = max(0.00001, weight);

    weight_accum += weight;
    irradiance_accum += color * weight;
  }
  return irradiance_accum / weight_accum;
}

vec3 lightprobe_grid_eval(vec3 P, vec3 N, float random_threshold)
{
  /* Go through all grids, computing and adding their weights for this pixel
   * until reaching a random threshold. */
  float weight = 0.0;
  int grid_index = probes_buf.grids_info.grid_count - 1;
  for (; grid_index > 0; grid_index--) {
    weight += lightprobe_grid_weight(grids_buf[grid_index], P);
    if (weight >= random_threshold) {
      break;
    }
  }

  return lightprobe_grid_evaluate(
      probes_buf.grids_info, lightprobe_grid_tx, grids_buf[grid_index], P, N);
}