Blender  V3.3
eevee_depth_of_field.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
17 #include "DRW_render.h"
18 
19 #include "DNA_camera_types.h"
20 #include "DNA_screen_types.h"
21 #include "DNA_view3d_types.h"
22 #include "DNA_world_types.h"
23 
24 #include "BKE_camera.h"
25 
26 #include "BLI_string_utils.h"
27 
28 #include "DEG_depsgraph.h"
29 #include "DEG_depsgraph_query.h"
30 
31 #include "GPU_framebuffer.h"
32 #include "GPU_texture.h"
33 #include "eevee_private.h"
34 
35 #define CAMERA_JITTER_RING_DENSITY 6
36 
37 static float coc_radius_from_camera_depth(bool is_ortho, EEVEE_EffectsInfo *fx, float camera_depth)
38 {
39  float multiplier = fx->dof_coc_params[0];
40  float bias = fx->dof_coc_params[1];
41  if (multiplier == 0.0f || bias == 0.0f) {
42  return 0.0f;
43  }
44  if (is_ortho) {
45  return (camera_depth + multiplier / bias) * multiplier;
46  }
47  return multiplier / camera_depth - bias;
48 }
49 
50 static float polygon_sides_length(float sides_count)
51 {
52  return 2.0 * sin(M_PI / sides_count);
53 }
54 
55 /* Returns intersection ratio between the radius edge at theta and the polygon edge.
56  * Start first corners at theta == 0. */
57 static float circle_to_polygon_radius(float sides_count, float theta)
58 {
59  /* From Graphics Gems from CryENGINE 3 (Siggraph 2013) by Tiago Sousa (slide 36). */
60  float side_angle = (2.0f * M_PI) / sides_count;
61  return cosf(side_angle * 0.5f) /
62  cosf(theta - side_angle * floorf((sides_count * theta + M_PI) / (2.0f * M_PI)));
63 }
64 
65 /* Remap input angle to have homogeneous spacing of points along a polygon edge.
66  * Expect theta to be in [0..2pi] range. */
67 static float circle_to_polygon_angle(float sides_count, float theta)
68 {
69  float side_angle = (2.0f * M_PI) / sides_count;
70  float halfside_angle = side_angle * 0.5f;
71  float side = floorf(theta / side_angle);
72  /* Length of segment from center to the middle of polygon side. */
73  float adjacent = circle_to_polygon_radius(sides_count, 0.0f);
74 
75  /* This is the relative position of the sample on the polygon half side. */
76  float local_theta = theta - side * side_angle;
77  float ratio = (local_theta - halfside_angle) / halfside_angle;
78 
79  float halfside_len = polygon_sides_length(sides_count) * 0.5f;
80  float opposite = ratio * halfside_len;
81 
82  /* NOTE: atan(y_over_x) has output range [-M_PI_2..M_PI_2]. */
83  float final_local_theta = atanf(opposite / adjacent);
84 
85  return side * side_angle + final_local_theta;
86 }
87 
88 static int dof_jitter_total_sample_count(int ring_density, int ring_count)
89 {
90  return ((ring_count * ring_count + ring_count) / 2) * ring_density + 1;
91 }
92 
94  float r_jitter[2],
95  float *r_focus_distance)
96 {
97  if (fx->dof_jitter_radius == 0.0f) {
98  return false;
99  }
100 
101  int ring_density = CAMERA_JITTER_RING_DENSITY;
102  int ring_count = fx->dof_jitter_ring_count;
103  int sample_count = dof_jitter_total_sample_count(ring_density, ring_count);
104 
105  int s = fx->taa_current_sample - 1;
106 
107  int ring = 0;
108  int ring_sample_count = 1;
109  int ring_sample = 1;
110 
111  s = s * (ring_density - 1);
112  s = s % sample_count;
113 
114  int samples_passed = 1;
115  while (s >= samples_passed) {
116  ring++;
117  ring_sample_count = ring * ring_density;
118  ring_sample = s - samples_passed;
119  ring_sample = (ring_sample + 1) % ring_sample_count;
120  samples_passed += ring_sample_count;
121  }
122 
123  r_jitter[0] = (float)ring / ring_count;
124  r_jitter[1] = (float)ring_sample / ring_sample_count;
125 
126  {
127  /* Bokeh shape parameterization. */
128  float r = r_jitter[0];
129  float T = r_jitter[1] * 2.0f * M_PI;
130 
131  if (fx->dof_jitter_blades >= 3.0f) {
134  }
135 
136  T += fx->dof_bokeh_rotation;
137 
138  r_jitter[0] = r * cosf(T);
139  r_jitter[1] = r * sinf(T);
140 
141  mul_v2_v2(r_jitter, fx->dof_bokeh_aniso);
142  }
143 
144  mul_v2_fl(r_jitter, fx->dof_jitter_radius);
145 
146  *r_focus_distance = fx->dof_jitter_focus;
147  return true;
148 }
149 
151  int sample_count,
152  int *r_ring_count)
153 {
154  if (effects->dof_jitter_radius == 0.0f) {
155  if (r_ring_count != NULL) {
156  *r_ring_count = 0;
157  }
158  return 1;
159  }
160 
161  if (sample_count == TAA_MAX_SAMPLE) {
162  /* Special case for viewport continuous rendering. We clamp to a max sample to avoid the
163  * jittered dof never converging. */
164  sample_count = 1024;
165  }
166  /* Inversion of dof_jitter_total_sample_count. */
167  float x = 2.0f * (sample_count - 1.0f) / CAMERA_JITTER_RING_DENSITY;
168  /* Solving polynomial. We only search positive solution. */
169  float discriminant = 1.0f + 4.0f * x;
170  int ring_count = ceilf(0.5f * (sqrt(discriminant) - 1.0f));
171 
172  sample_count = dof_jitter_total_sample_count(CAMERA_JITTER_RING_DENSITY, ring_count);
173 
174  if (r_ring_count != NULL) {
175  *r_ring_count = ring_count;
176  }
177  return sample_count;
178 }
179 
181  EEVEE_Data *vedata,
182  Object *camera)
183 {
184  EEVEE_TextureList *txl = vedata->txl;
185  EEVEE_StorageList *stl = vedata->stl;
186  EEVEE_FramebufferList *fbl = vedata->fbl;
187  EEVEE_EffectsInfo *effects = stl->effects;
188 
189  const DRWContextState *draw_ctx = DRW_context_state_get();
190  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
191 
192  Camera *cam = (camera != NULL && camera->type == OB_CAMERA) ? camera->data : NULL;
193 
194  if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
195  RegionView3D *rv3d = draw_ctx->rv3d;
196  const float *viewport_size = DRW_viewport_size_get();
197 
198  effects->dof_hq_slight_focus = (scene_eval->eevee.flag & SCE_EEVEE_DOF_HQ_SLIGHT_FOCUS) != 0;
199 
200  /* Retrieve Near and Far distance */
201  effects->dof_coc_near_dist = -cam->clip_start;
202  effects->dof_coc_far_dist = -cam->clip_end;
203 
204  /* Parameters */
205  bool is_ortho = cam->type == CAM_ORTHO;
206  float fstop = cam->dof.aperture_fstop;
207  float blades = cam->dof.aperture_blades;
208  float rotation = cam->dof.aperture_rotation;
209  float ratio = 1.0f / max_ff(cam->dof.aperture_ratio, 0.00001f);
210  float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
211  float focus_dist = BKE_camera_object_dof_distance(camera);
212  float focal_len = cam->lens;
213 
214  if (is_ortho) {
215  /* (fclem) A bit of black magic here. I don't know if this is correct. */
216  fstop *= 1.3f;
217  focal_len = 1.0f;
218  sensor = cam->ortho_scale;
219  }
220 
221  const float scale_camera = (is_ortho) ? 1.0 : 0.001f;
222  /* We want radius here for the aperture number. */
223  float aperture = 0.5f * scale_camera * focal_len / fstop;
224  float focal_len_scaled = scale_camera * focal_len;
225  float sensor_scaled = scale_camera * sensor;
226 
227  if (rv3d != NULL) {
228  sensor_scaled *= rv3d->viewcamtexcofac[0];
229  }
230 
231  if (ratio > 1.0) {
232  /* If ratio is scaling the bokeh outwards, we scale the aperture so that the gather
233  * kernel size will encompass the maximum axis. */
234  aperture *= ratio;
235  }
236 
237  effects->dof_coc_params[1] = -aperture *
238  fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
239  /* FIXME(@fclem): This is broken for vertically fit sensor. */
240  effects->dof_coc_params[1] *= viewport_size[0] / sensor_scaled;
241 
242  if ((scene_eval->eevee.flag & SCE_EEVEE_DOF_JITTER) != 0) {
243  effects->dof_jitter_radius = effects->dof_coc_params[1];
244  effects->dof_jitter_focus = focus_dist;
245  effects->dof_jitter_blades = blades;
246 
247  int sample_count = EEVEE_temporal_sampling_sample_count_get(scene_eval, stl);
249  effects, sample_count, &effects->dof_jitter_ring_count);
250 
251  if (effects->dof_jitter_ring_count == 0) {
252  effects->dof_jitter_radius = 0.0f;
253  }
254  else {
255  /* Compute a minimal overblur radius to fill the gaps between the samples.
256  * This is just the simplified form of dividing the area of the bokeh
257  * by the number of samples. */
258  float minimal_overblur = 1.0f / sqrtf(sample_count);
259  float user_overblur = scene_eval->eevee.bokeh_overblur / 100.0f;
260 
261  minimal_overblur *= effects->dof_coc_params[1];
262  user_overblur *= effects->dof_coc_params[1];
263 
264  effects->dof_coc_params[1] = minimal_overblur + user_overblur;
265  /* Avoid dilating the shape. Over-blur only soften. */
266  effects->dof_jitter_radius -= minimal_overblur + user_overblur * 0.5f;
267  }
268  }
269  else {
270  effects->dof_jitter_radius = 0.0f;
271  }
272 
273  if (is_ortho) {
274  /* (fclem) A bit of black magic here. Needed to match cycles. */
275  effects->dof_coc_params[1] *= 0.225;
276  }
277 
278  effects->dof_coc_params[0] = -focus_dist * effects->dof_coc_params[1];
279 
280  effects->dof_bokeh_blades = blades;
281  effects->dof_bokeh_rotation = rotation;
282  effects->dof_bokeh_aniso[0] = min_ff(ratio, 1.0f);
283  effects->dof_bokeh_aniso[1] = min_ff(1.0f / ratio, 1.0f);
284  effects->dof_bokeh_max_size = scene_eval->eevee.bokeh_max_size;
285 
286  copy_v2_v2(effects->dof_bokeh_aniso_inv, effects->dof_bokeh_aniso);
287  invert_v2(effects->dof_bokeh_aniso_inv);
288 
289  effects->dof_scatter_color_threshold = scene_eval->eevee.bokeh_threshold;
291  effects->dof_denoise_factor = clamp_f(scene_eval->eevee.bokeh_denoise_fac, 0.0f, 1.0f);
292 
293  float max_abs_fg_coc, max_abs_bg_coc;
294  if (is_ortho) {
295  max_abs_fg_coc = fabsf(coc_radius_from_camera_depth(true, effects, -cam->clip_start));
296  max_abs_bg_coc = fabsf(coc_radius_from_camera_depth(true, effects, -cam->clip_end));
297  }
298  else {
299  max_abs_fg_coc = fabsf(coc_radius_from_camera_depth(false, effects, -cam->clip_start));
300  /* Background is at infinity so maximum CoC is the limit of the function at -inf. */
301  max_abs_bg_coc = fabsf(effects->dof_coc_params[1]);
302  }
303 
304  float max_coc = max_ff(max_abs_bg_coc, max_abs_fg_coc);
305  /* Clamp with user defined max. */
306  effects->dof_fx_max_coc = min_ff(scene_eval->eevee.bokeh_max_size, max_coc);
307 
308  if (effects->dof_fx_max_coc < 0.5f) {
309  return 0;
310  }
311 
313  }
314 
315  effects->dof_jitter_radius = 0.0f;
316 
317  /* Cleanup to release memory */
318  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_setup_fb);
319  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_flatten_tiles_fb);
320  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_dilate_tiles_fb);
321  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_reduce_fb);
322  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_reduce_copy_fb);
323  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_gather_fg_fb);
324  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_gather_bg_fb);
325  GPU_FRAMEBUFFER_FREE_SAFE(fbl->dof_scatter_bg_fb);
328 
329  return 0;
330 }
331 
332 #define WITH_FILTERING (GPU_SAMPLER_MIPMAP | GPU_SAMPLER_FILTER)
333 #define NO_FILTERING GPU_SAMPLER_MIPMAP
334 #define COLOR_FORMAT fx->dof_color_format
335 #define FG_TILE_FORMAT GPU_RGBA16F
336 #define BG_TILE_FORMAT GPU_R11F_G11F_B10F
337 
342  EEVEE_PassList *psl,
343  EEVEE_EffectsInfo *fx)
344 {
345  if ((fx->dof_bokeh_aniso[0] == 1.0f) && (fx->dof_bokeh_aniso[1] == 1.0f) &&
346  (fx->dof_bokeh_blades == 0.0)) {
350  return;
351  }
352 
353  void *owner = (void *)&EEVEE_depth_of_field_init;
354  int res[2] = {DOF_BOKEH_LUT_SIZE, DOF_BOKEH_LUT_SIZE};
355 
357 
360  DRW_shgroup_uniform_float_copy(grp, "bokehSides", fx->dof_bokeh_blades);
361  DRW_shgroup_uniform_float_copy(grp, "bokehRotation", fx->dof_bokeh_rotation);
362  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
364 
368 
369  GPU_framebuffer_ensure_config(&fbl->dof_bokeh_fb,
370  {
371  GPU_ATTACHMENT_NONE,
372  GPU_ATTACHMENT_TEXTURE(fx->dof_bokeh_gather_lut_tx),
373  GPU_ATTACHMENT_TEXTURE(fx->dof_bokeh_scatter_lut_tx),
374  GPU_ATTACHMENT_TEXTURE(fx->dof_bokeh_resolve_lut_tx),
375  });
376 }
377 
382  EEVEE_PassList *psl,
383  EEVEE_EffectsInfo *fx)
384 {
386 
387  void *owner = (void *)&EEVEE_depth_of_field_init;
388  const float *fullres = DRW_viewport_size_get();
389  int res[2] = {divide_ceil_u(fullres[0], 2), divide_ceil_u(fullres[1], 2)};
390 
392 
396  DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &dtxl->depth, NO_FILTERING);
397  DRW_shgroup_uniform_vec4_copy(grp, "cocParams", fx->dof_coc_params);
398  DRW_shgroup_uniform_float_copy(grp, "bokehMaxSize", fx->dof_bokeh_max_size);
400 
403 
404  GPU_framebuffer_ensure_config(&fbl->dof_setup_fb,
405  {
406  GPU_ATTACHMENT_NONE,
407  GPU_ATTACHMENT_TEXTURE(fx->dof_half_res_color_tx),
408  GPU_ATTACHMENT_TEXTURE(fx->dof_half_res_coc_tx),
409  });
410 }
411 
416  EEVEE_PassList *psl,
417  EEVEE_EffectsInfo *fx)
418 {
419  void *owner = (void *)&EEVEE_depth_of_field_init;
420  const float *fullres = DRW_viewport_size_get();
421  int res[2] = {divide_ceil_u(fullres[0], DOF_TILE_DIVISOR),
422  divide_ceil_u(fullres[1], DOF_TILE_DIVISOR)};
423 
425 
429  grp, "halfResCocBuffer", &fx->dof_half_res_coc_tx, NO_FILTERING);
431 
434 
435  GPU_framebuffer_ensure_config(&fbl->dof_flatten_tiles_fb,
436  {
437  GPU_ATTACHMENT_NONE,
438  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_tiles_fg_tx),
439  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_tiles_bg_tx),
440  });
441 }
442 
449  EEVEE_PassList *psl,
450  EEVEE_EffectsInfo *fx)
451 {
452  void *owner = (void *)&EEVEE_depth_of_field_init;
453  const float *fullres = DRW_viewport_size_get();
454  int res[2] = {divide_ceil_u(fullres[0], DOF_TILE_DIVISOR),
455  divide_ceil_u(fullres[1], DOF_TILE_DIVISOR)};
456 
459 
460  for (int pass = 0; pass < 2; pass++) {
461  DRWPass *drw_pass = (pass == 0) ? psl->dof_dilate_tiles_minmax : psl->dof_dilate_tiles_minabs;
463  DRWShadingGroup *grp = DRW_shgroup_create(sh, drw_pass);
464  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_tiles_fg_tx);
465  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_tiles_bg_tx);
466  DRW_shgroup_uniform_bool(grp, "dilateSlightFocus", &fx->dof_dilate_slight_focus, 1);
467  DRW_shgroup_uniform_int(grp, "ringCount", &fx->dof_dilate_ring_count, 1);
468  DRW_shgroup_uniform_int(grp, "ringWidthMultiplier", &fx->dof_dilate_ring_width_multiplier, 1);
470  }
471 
474 
475  GPU_framebuffer_ensure_config(&fbl->dof_dilate_tiles_fb,
476  {
477  GPU_ATTACHMENT_NONE,
478  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_dilated_tiles_fg_tx),
479  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_dilated_tiles_bg_tx),
480  });
481 }
482 
484  EEVEE_PassList *psl,
485  EEVEE_EffectsInfo *fx)
486 {
487  for (int pass = 0; pass < 2; pass++) {
488  DRWPass *drw_pass = (pass == 0) ? psl->dof_dilate_tiles_minmax : psl->dof_dilate_tiles_minabs;
489 
490  /* Error introduced by gather center jittering. */
491  const float error_multiplier = 1.0f + 1.0f / (DOF_GATHER_RING_COUNT + 0.5f);
492  int dilation_end_radius = ceilf((fx->dof_fx_max_coc * error_multiplier) / DOF_TILE_DIVISOR);
493 
494  /* This algorithm produce the exact dilation radius by dividing it in multiple passes. */
495  int dilation_radius = 0;
496  while (dilation_radius < dilation_end_radius) {
497  /* Dilate slight focus only on first iteration. */
498  fx->dof_dilate_slight_focus = (dilation_radius == 0) ? 1 : 0;
499 
500  int remainder = dilation_end_radius - dilation_radius;
501  /* Do not step over any unvisited tile. */
502  int max_multiplier = dilation_radius + 1;
503 
504  int ring_count = min_ii(DOF_DILATE_RING_COUNT, ceilf(remainder / (float)max_multiplier));
505  int multiplier = min_ii(max_multiplier, floor(remainder / (float)ring_count));
506 
507  dilation_radius += ring_count * multiplier;
508 
509  fx->dof_dilate_ring_count = ring_count;
510  fx->dof_dilate_ring_width_multiplier = multiplier;
511 
513  DRW_draw_pass(drw_pass);
514 
518  }
519  }
520  /* Swap again so that final textures are dof_coc_dilated_tiles_*_tx. */
524 }
525 
530  EEVEE_PassList *psl,
531  EEVEE_TextureList *txl,
532  EEVEE_EffectsInfo *fx)
533 {
534  const float *fullres = DRW_viewport_size_get();
535 
536  /* Divide by 2 because dof_fx_max_coc is in fullres CoC radius and the reduce texture begins at
537  * half resolution. */
538  float max_space_between_sample = fx->dof_fx_max_coc * 0.5f / DOF_GATHER_RING_COUNT;
539 
540  int mip_count = max_ii(1, log2_ceil_u(max_space_between_sample));
541 
542  fx->dof_reduce_steps = mip_count - 1;
543  /* This ensure the mipmaps are aligned for the needed 4 mip levels.
544  * Starts at 2 because already at half resolution. */
545  int multiple = 2 << (mip_count - 1);
546  int res[2] = {(multiple * divide_ceil_u(fullres[0], multiple)) / 2,
547  (multiple * divide_ceil_u(fullres[1], multiple)) / 2};
548 
549  int quater_res[2] = {divide_ceil_u(fullres[0], 4), divide_ceil_u(fullres[1], 4)};
550 
551  /* TODO(fclem): Make this dependent of the quality of the gather pass. */
552  fx->dof_scatter_coc_threshold = 4.0f;
553 
554  {
556 
560  grp, "colorBuffer", &fx->dof_reduce_input_color_tx, NO_FILTERING);
562  grp, "cocBuffer", &fx->dof_reduce_input_coc_tx, NO_FILTERING);
564 
565  void *owner = (void *)&EEVEE_depth_of_field_init;
567 
568  GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb,
569  {
570  GPU_ATTACHMENT_NONE,
571  GPU_ATTACHMENT_TEXTURE(fx->dof_downsample_tx),
572  });
573  }
574 
575  {
577 
578  const bool is_copy_pass = true;
582  grp, "colorBuffer", &fx->dof_reduce_input_color_tx, NO_FILTERING);
584  grp, "cocBuffer", &fx->dof_reduce_input_coc_tx, NO_FILTERING);
586  grp, "downsampledBuffer", &fx->dof_downsample_tx, NO_FILTERING);
587  DRW_shgroup_uniform_float_copy(grp, "scatterColorThreshold", fx->dof_scatter_color_threshold);
589  grp, "scatterColorNeighborMax", fx->dof_scatter_neighbor_max_color);
590  DRW_shgroup_uniform_float_copy(grp, "scatterCocThreshold", fx->dof_scatter_coc_threshold);
591  DRW_shgroup_uniform_float_copy(grp, "colorNeighborClamping", fx->dof_denoise_factor);
592  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
594 
595  void *owner = (void *)&EEVEE_depth_of_field_init;
597  }
598 
599  {
601 
602  const bool is_copy_pass = false;
606  grp, "colorBuffer", &fx->dof_reduce_input_color_tx, NO_FILTERING);
608  grp, "cocBuffer", &fx->dof_reduce_input_coc_tx, NO_FILTERING);
610  }
611 
612  if (txl->dof_reduced_color) {
613  /* TODO(@fclem): In the future, we need to check if mip_count did not change.
614  * For now it's ok as we always define all mip level. */
615  if (res[0] != GPU_texture_width(txl->dof_reduced_color) ||
616  res[1] != GPU_texture_width(txl->dof_reduced_color)) {
619  }
620  }
621 
622  if (txl->dof_reduced_color == NULL) {
623  /* Color needs to be signed format here. See note in shader for explanation. */
624  /* Do not use texture pool because of needs mipmaps. */
626  "dof_reduced_color", UNPACK2(res), mip_count, GPU_RGBA16F, NULL);
628  "dof_reduced_coc", UNPACK2(res), mip_count, GPU_R16F, NULL);
629  }
630 
631  GPU_framebuffer_ensure_config(&fbl->dof_reduce_fb,
632  {
633  GPU_ATTACHMENT_NONE,
634  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_color),
635  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_coc),
636  });
637 
638  GPU_framebuffer_ensure_config(&fbl->dof_reduce_copy_fb,
639  {
640  GPU_ATTACHMENT_NONE,
641  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_color),
642  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_coc),
643  GPU_ATTACHMENT_TEXTURE(fx->dof_scatter_src_tx),
644  });
645 }
646 
652  EEVEE_PassList *psl,
653  EEVEE_TextureList *txl,
654  EEVEE_EffectsInfo *fx)
655 {
656  void *owner = (void *)&EEVEE_depth_of_field_init;
657  const float *fullres = DRW_viewport_size_get();
658  int res[2] = {divide_ceil_u(fullres[0], 2), divide_ceil_u(fullres[1], 2)};
659  int input_size[2];
660  GPU_texture_get_mipmap_size(txl->dof_reduced_color, 0, input_size);
661  float uv_correction_fac[2] = {res[0] / (float)input_size[0], res[1] / (float)input_size[1]};
662  float output_texel_size[2] = {1.0f / res[0], 1.0f / res[1]};
663  const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != NULL);
664 
665  {
667 
671  grp, "colorBufferBilinear", &txl->dof_reduced_color, WITH_FILTERING);
674  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_dilated_tiles_fg_tx);
675  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_dilated_tiles_bg_tx);
677  DRW_shgroup_uniform_vec2_copy(grp, "gatherInputUvCorrection", uv_correction_fac);
678  DRW_shgroup_uniform_vec2_copy(grp, "gatherOutputTexelSize", output_texel_size);
680 
681  /* Reuse textures from the setup pass. */
682  /* NOTE: We could use the texture pool do that for us but it does not track usage and it might
683  * backfire (it does in practice). */
686 
687  GPU_framebuffer_ensure_config(&fbl->dof_gather_fg_holefill_fb,
688  {
689  GPU_ATTACHMENT_NONE,
690  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_color_tx),
691  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_weight_tx),
692  });
693  }
694  {
696 
700  grp, "colorBufferBilinear", &txl->dof_reduced_color, WITH_FILTERING);
703  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_dilated_tiles_fg_tx);
704  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_dilated_tiles_bg_tx);
706  DRW_shgroup_uniform_vec2_copy(grp, "gatherInputUvCorrection", uv_correction_fac);
707  DRW_shgroup_uniform_vec2_copy(grp, "gatherOutputTexelSize", output_texel_size);
708  if (use_bokeh_tx) {
709  /* Negate to flip bokeh shape. Mimics optical phenomenon. */
711  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
713  /* Restore. */
715  }
717 
720  /* Reuse textures from the setup pass. */
721  /* NOTE: We could use the texture pool do that for us but it does not track usage and it might
722  * backfire (it does in practice). */
724 
725  /* NOTE: First target is holefill texture so we can use the median filter on it.
726  * See the filter function. */
727  GPU_framebuffer_ensure_config(&fbl->dof_gather_fg_fb,
728  {
729  GPU_ATTACHMENT_NONE,
730  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_color_tx),
731  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_weight_tx),
732  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_occlusion_tx),
733  });
734  }
735  {
737 
741  grp, "colorBufferBilinear", &txl->dof_reduced_color, WITH_FILTERING);
744  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_dilated_tiles_fg_tx);
745  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_dilated_tiles_bg_tx);
747  DRW_shgroup_uniform_vec2_copy(grp, "gatherInputUvCorrection", uv_correction_fac);
748  DRW_shgroup_uniform_vec2_copy(grp, "gatherOutputTexelSize", output_texel_size);
749  if (use_bokeh_tx) {
750  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
752  }
754 
757  /* Reuse, since only used for scatter. Foreground is processed before background. */
759 
760  /* NOTE: First target is holefill texture so we can use the median filter on it.
761  * See the filter function. */
762  GPU_framebuffer_ensure_config(&fbl->dof_gather_bg_fb,
763  {
764  GPU_ATTACHMENT_NONE,
765  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_color_tx),
766  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_weight_tx),
767  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_occlusion_tx),
768  });
769  }
770 }
771 
778  EEVEE_PassList *psl,
779  EEVEE_EffectsInfo *fx)
780 {
782 
786  grp, "colorBuffer", &fx->dof_fg_holefill_color_tx, NO_FILTERING);
788  grp, "weightBuffer", &fx->dof_fg_holefill_weight_tx, NO_FILTERING);
790 
791  GPU_framebuffer_ensure_config(&fbl->dof_filter_fg_fb,
792  {
793  GPU_ATTACHMENT_NONE,
794  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_color_tx),
795  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_weight_tx),
796  });
797 
798  GPU_framebuffer_ensure_config(&fbl->dof_filter_bg_fb,
799  {
800  GPU_ATTACHMENT_NONE,
801  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_color_tx),
802  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_weight_tx),
803  });
804 }
805 
811  EEVEE_PassList *psl,
812  EEVEE_TextureList *txl,
813  EEVEE_EffectsInfo *fx)
814 {
815  int input_size[2], target_size[2];
817  GPU_texture_get_mipmap_size(fx->dof_bg_color_tx, 0, target_size);
818  /* Draw a sprite for every four half-res pixels. */
819  int sprite_count = (input_size[0] / 2) * (input_size[1] / 2);
820  float target_texel_size[2] = {1.0f / target_size[0], 1.0f / target_size[1]};
821  const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != NULL);
822 
823  {
825 
826  const bool is_foreground = true;
827  GPUShader *sh = EEVEE_shaders_depth_of_field_scatter_get(is_foreground, use_bokeh_tx);
831  DRW_shgroup_uniform_texture_ref(grp, "occlusionBuffer", &fx->dof_fg_occlusion_tx);
832  DRW_shgroup_uniform_vec2_copy(grp, "targetTexelSize", target_texel_size);
833  DRW_shgroup_uniform_int_copy(grp, "spritePerRow", input_size[0] / 2);
834  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
835  if (use_bokeh_tx) {
836  /* Negate to flip bokeh shape. Mimics optical phenomenon. */
838  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
840  /* Restore. */
842  }
843  DRW_shgroup_call_procedural_triangles(grp, NULL, sprite_count);
844 
845  GPU_framebuffer_ensure_config(&fbl->dof_scatter_fg_fb,
846  {
847  GPU_ATTACHMENT_NONE,
848  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_color_tx),
849  });
850  }
851  {
853 
854  const bool is_foreground = false;
855  GPUShader *sh = EEVEE_shaders_depth_of_field_scatter_get(is_foreground, use_bokeh_tx);
859  DRW_shgroup_uniform_texture_ref(grp, "occlusionBuffer", &fx->dof_bg_occlusion_tx);
860  DRW_shgroup_uniform_vec2_copy(grp, "targetTexelSize", target_texel_size);
861  DRW_shgroup_uniform_int_copy(grp, "spritePerRow", input_size[0] / 2);
862  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
863  if (use_bokeh_tx) {
864  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
866  }
867  DRW_shgroup_call_procedural_triangles(grp, NULL, sprite_count);
868 
869  GPU_framebuffer_ensure_config(&fbl->dof_scatter_bg_fb,
870  {
871  GPU_ATTACHMENT_NONE,
872  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_color_tx),
873  });
874  }
875 }
876 
882  EEVEE_PassList *psl,
883  EEVEE_EffectsInfo *fx)
884 {
886  const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != NULL);
887 
889 
892  DRW_shgroup_uniform_texture_ref_ex(grp, "fullResColorBuffer", &fx->source_buffer, NO_FILTERING);
893  DRW_shgroup_uniform_texture_ref_ex(grp, "fullResDepthBuffer", &dtxl->depth, NO_FILTERING);
894  DRW_shgroup_uniform_texture_ref(grp, "bgColorBuffer", &fx->dof_bg_color_tx);
895  DRW_shgroup_uniform_texture_ref(grp, "bgWeightBuffer", &fx->dof_bg_weight_tx);
897  DRW_shgroup_uniform_texture_ref(grp, "fgColorBuffer", &fx->dof_fg_color_tx);
898  DRW_shgroup_uniform_texture_ref(grp, "fgWeightBuffer", &fx->dof_fg_weight_tx);
899  DRW_shgroup_uniform_texture_ref(grp, "holefillColorBuffer", &fx->dof_fg_holefill_color_tx);
900  DRW_shgroup_uniform_texture_ref(grp, "holefillWeightBuffer", &fx->dof_fg_holefill_weight_tx);
903  DRW_shgroup_uniform_vec4_copy(grp, "cocParams", fx->dof_coc_params);
904  DRW_shgroup_uniform_float_copy(grp, "bokehMaxSize", fx->dof_bokeh_max_size);
905  if (use_bokeh_tx) {
906  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
908  }
910 }
911 
913 {
914  EEVEE_TextureList *txl = vedata->txl;
915  EEVEE_FramebufferList *fbl = vedata->fbl;
916  EEVEE_PassList *psl = vedata->psl;
917  EEVEE_StorageList *stl = vedata->stl;
918  EEVEE_EffectsInfo *fx = stl->effects;
919 
920  if ((fx->enabled_effects & EFFECT_DOF) != 0) {
921  /* GPU_RGBA16F is sufficient now that all scattered bokeh are premultiplied.
922  * GPU_R11F_G11F_B10F is not enough when lots of scattered sprites are big and offers
923  * relatively small benefits. */
925 
926  dof_bokeh_pass_init(fbl, psl, fx);
927  dof_setup_pass_init(fbl, psl, fx);
928  dof_flatten_tiles_pass_init(fbl, psl, fx);
929  dof_dilate_tiles_pass_init(fbl, psl, fx);
930  dof_reduce_pass_init(fbl, psl, txl, fx);
931  dof_gather_pass_init(fbl, psl, txl, fx);
932  dof_filter_pass_init(fbl, psl, fx);
933  dof_scatter_pass_init(fbl, psl, txl, fx);
934  dof_recombine_pass_init(fbl, psl, fx);
935  }
936 }
937 
938 static void dof_recursive_reduce(void *vedata, int UNUSED(level))
939 {
940  EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
941  EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
942  EEVEE_EffectsInfo *fx = ((EEVEE_Data *)vedata)->stl->effects;
943 
946 
948 }
949 
951 {
952  EEVEE_PassList *psl = vedata->psl;
953  EEVEE_TextureList *txl = vedata->txl;
954  EEVEE_FramebufferList *fbl = vedata->fbl;
955  EEVEE_StorageList *stl = vedata->stl;
956  EEVEE_EffectsInfo *effects = stl->effects; /* TODO(fclem): Because of silly SWAP_BUFFERS. */
957  EEVEE_EffectsInfo *fx = effects;
958 
959  /* Depth Of Field */
960  if ((effects->enabled_effects & EFFECT_DOF) != 0) {
961  DRW_stats_group_start("Depth of Field");
962 
963  if (fx->dof_bokeh_gather_lut_tx != NULL) {
965  DRW_draw_pass(psl->dof_bokeh);
966  }
967 
969  DRW_draw_pass(psl->dof_setup);
970 
973 
974  dof_dilate_tiles_pass_draw(fbl, psl, fx);
975 
978 
979  /* First step is just a copy. */
982 
983  /* First step is just a copy. */
986 
989 
990  {
991  /* Foreground convolution. */
994 
997 
1000  }
1001 
1002  {
1003  /* Background convolution. */
1006 
1008  DRW_draw_pass(psl->dof_filter);
1009 
1012  }
1013 
1014  {
1015  /* Hole-fill convolution. */
1018 
1019  /* NOTE: do not filter the hole-fill pass as we use it as out filter input buffer. */
1020  }
1021 
1023  DRW_draw_pass(psl->dof_resolve);
1024 
1025  SWAP_BUFFERS();
1026 
1028  }
1029 }
typedef float(TangentPoint)[2]
Camera data-block and utility functions.
float BKE_camera_sensor_size(int sensor_fit, float sensor_x, float sensor_y)
Definition: camera.c:236
float BKE_camera_object_dof_distance(const struct Object *ob)
sqrt(x)+1/max(0
MINLINE unsigned int log2_ceil_u(unsigned int x)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE uint divide_ceil_u(uint a, uint b)
MINLINE float clamp_f(float value, float min, float max)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
#define M_PI
Definition: BLI_math_base.h:20
MINLINE void mul_v2_v2(float r[2], const float a[2])
MINLINE void mul_v2_fl(float r[2], float f)
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void negate_v2(float r[2])
MINLINE void invert_v2(float r[2])
#define UNPACK2(a)
#define SWAP(type, a, b)
#define UNUSED(x)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ CAM_DOF_ENABLED
@ CAM_ORTHO
@ OB_CAMERA
@ SCE_EEVEE_DOF_HQ_SLIGHT_FOCUS
@ SCE_EEVEE_DOF_JITTER
@ DRW_STATE_BLEND_ADD_FULL
Definition: DRW_render.h:326
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:183
struct GPUFrameBuffer GPUFrameBuffer
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
struct GPUShader GPUShader
Definition: GPU_shader.h:20
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:602
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
Definition: gpu_texture.cc:688
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
@ GPU_RG16F
Definition: GPU_texture.h:103
@ GPU_R16F
Definition: GPU_texture.h:113
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:118
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:638
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex, eGPUSamplerState sampler_state)
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob, uint tri_count)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_draw_pass(DRWPass *pass)
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end(void)
GPUTexture * DRW_texture_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
static float circle_to_polygon_angle(float sides_count, float theta)
int EEVEE_depth_of_field_sample_count_get(EEVEE_EffectsInfo *effects, int sample_count, int *r_ring_count)
#define CAMERA_JITTER_RING_DENSITY
static int dof_jitter_total_sample_count(int ring_density, int ring_count)
#define BG_TILE_FORMAT
#define COLOR_FORMAT
static void dof_flatten_tiles_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
static void dof_filter_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
static float coc_radius_from_camera_depth(bool is_ortho, EEVEE_EffectsInfo *fx, float camera_depth)
static void dof_scatter_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_TextureList *txl, EEVEE_EffectsInfo *fx)
static float circle_to_polygon_radius(float sides_count, float theta)
static void dof_recursive_reduce(void *vedata, int UNUSED(level))
static void dof_setup_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
static void dof_recombine_pass_init(EEVEE_FramebufferList *UNUSED(fbl), EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
void EEVEE_depth_of_field_draw(EEVEE_Data *vedata)
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *camera)
static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_TextureList *txl, EEVEE_EffectsInfo *fx)
#define WITH_FILTERING
#define NO_FILTERING
#define FG_TILE_FORMAT
void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
static void dof_gather_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_TextureList *txl, EEVEE_EffectsInfo *fx)
static void dof_dilate_tiles_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
static float polygon_sides_length(float sides_count)
static void dof_dilate_tiles_pass_draw(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
static void dof_bokeh_pass_init(EEVEE_FramebufferList *fbl, EEVEE_PassList *psl, EEVEE_EffectsInfo *fx)
bool EEVEE_depth_of_field_jitter_get(EEVEE_EffectsInfo *fx, float r_jitter[2], float *r_focus_distance)
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
struct GPUTexture * EEVEE_materials_get_util_tex(void)
@ DOF_GATHER_HOLEFILL
@ DOF_GATHER_FOREGROUND
@ DOF_GATHER_BACKGROUND
struct GPUShader * EEVEE_shaders_depth_of_field_setup_get(void)
#define SWAP_BUFFERS()
Definition: eevee_private.h:88
#define DOF_TILE_DIVISOR
struct GPUShader * EEVEE_shaders_depth_of_field_bokeh_get(void)
#define TAA_MAX_SAMPLE
Definition: eevee_private.h:44
struct GPUShader * EEVEE_shaders_depth_of_field_dilate_tiles_get(bool pass)
int EEVEE_temporal_sampling_sample_count_get(const Scene *scene, const EEVEE_StorageList *stl)
#define DOF_BOKEH_LUT_SIZE
#define DOF_DILATE_RING_COUNT
@ EFFECT_DOF
@ EFFECT_POST_BUFFER
struct GPUShader * EEVEE_shaders_depth_of_field_scatter_get(bool is_foreground, bool bokeh_tx)
struct GPUShader * EEVEE_shaders_depth_of_field_gather_get(EEVEE_DofGatherPass pass, bool bokeh_tx)
#define DOF_GATHER_RING_COUNT
struct GPUShader * EEVEE_shaders_depth_of_field_flatten_tiles_get(void)
struct GPUShader * EEVEE_shaders_depth_of_field_resolve_get(bool use_bokeh_tx, bool use_hq_gather)
struct GPUShader * EEVEE_shaders_depth_of_field_reduce_get(bool is_copy_pass)
struct GPUShader * EEVEE_shaders_depth_of_field_downsample_get(void)
struct GPUShader * EEVEE_shaders_depth_of_field_filter_get(void)
void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *gpu_fb, int max_lvl, void(*callback)(void *userData, int level), void *userData)
ccl_gpu_kernel_postfix ccl_global float int int int int sh
#define T
#define ceilf(x)
Definition: metal/compat.h:225
#define atanf(x)
Definition: metal/compat.h:223
#define floorf(x)
Definition: metal/compat.h:224
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
T floor(const T &a)
float clip_end
char sensor_fit
float sensor_y
float lens
float sensor_x
float clip_start
struct CameraDOFSettings dof
float ortho_scale
struct Depsgraph * depsgraph
Definition: DRW_render.h:987
struct RegionView3D * rv3d
Definition: DRW_render.h:975
struct GPUTexture * depth
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUTexture * dof_scatter_src_tx
struct GPUTexture * dof_coc_dilated_tiles_bg_tx
struct GPUTexture * source_buffer
struct GPUTexture * dof_bokeh_scatter_lut_tx
struct GPUTexture * dof_reduce_input_color_tx
struct GPUTexture * dof_coc_dilated_tiles_fg_tx
struct GPUTexture * dof_fg_holefill_weight_tx
struct GPUTexture * dof_fg_color_tx
float dof_scatter_color_threshold
struct GPUTexture * dof_bg_color_tx
struct GPUFrameBuffer * target_buffer
struct GPUTexture * dof_coc_tiles_bg_tx
float dof_bokeh_aniso[2]
float dof_bokeh_aniso_inv[2]
struct GPUTexture * dof_downsample_tx
struct GPUTexture * dof_fg_weight_tx
struct GPUTexture * dof_fg_occlusion_tx
EEVEE_EffectsFlag enabled_effects
struct GPUTexture * dof_half_res_color_tx
struct GPUTexture * dof_bokeh_resolve_lut_tx
float dof_scatter_coc_threshold
struct GPUTexture * dof_reduce_input_coc_tx
struct GPUTexture * dof_fg_holefill_color_tx
struct GPUTexture * dof_coc_tiles_fg_tx
float dof_coc_params[2]
eGPUTextureFormat dof_color_format
int dof_dilate_ring_width_multiplier
float dof_scatter_neighbor_max_color
struct GPUTexture * dof_bg_occlusion_tx
struct GPUTexture * dof_bokeh_gather_lut_tx
struct GPUTexture * dof_half_res_coc_tx
struct GPUTexture * dof_bg_weight_tx
struct GPUFrameBuffer * dof_gather_fg_fb
struct GPUFrameBuffer * dof_reduce_copy_fb
struct GPUFrameBuffer * dof_flatten_tiles_fb
struct GPUFrameBuffer * dof_filter_fg_fb
struct GPUFrameBuffer * dof_bokeh_fb
struct GPUFrameBuffer * dof_setup_fb
struct GPUFrameBuffer * dof_downsample_fb
struct GPUFrameBuffer * dof_reduce_fb
struct GPUFrameBuffer * dof_gather_bg_fb
struct GPUFrameBuffer * dof_scatter_bg_fb
struct GPUFrameBuffer * dof_dilate_tiles_fb
struct GPUFrameBuffer * dof_gather_fg_holefill_fb
struct GPUFrameBuffer * dof_scatter_fg_fb
struct GPUFrameBuffer * dof_filter_bg_fb
struct DRWPass * dof_reduce_copy
struct DRWPass * dof_setup
struct DRWPass * dof_gather_bg
struct DRWPass * dof_bokeh
struct DRWPass * dof_gather_fg
struct DRWPass * dof_gather_fg_holefill
struct DRWPass * dof_scatter_fg
struct DRWPass * dof_scatter_bg
struct DRWPass * dof_reduce
struct DRWPass * dof_downsample
struct DRWPass * dof_flatten_tiles
struct DRWPass * dof_resolve
struct DRWPass * dof_dilate_tiles_minmax
struct DRWPass * dof_dilate_tiles_minabs
struct DRWPass * dof_filter
struct EEVEE_EffectsInfo * effects
struct GPUTexture * dof_reduced_coc
struct GPUTexture * dof_reduced_color
float viewcamtexcofac[4]
float bokeh_denoise_fac
float bokeh_overblur
float bokeh_threshold
float bokeh_neighbor_max
float bokeh_max_size
struct SceneEEVEE eevee