Blender  V2.93
eevee_depth_of_field.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18 
32 #include "DRW_render.h"
33 
34 #include "DNA_camera_types.h"
35 #include "DNA_screen_types.h"
36 #include "DNA_view3d_types.h"
37 #include "DNA_world_types.h"
38 
39 #include "BKE_camera.h"
40 
41 #include "BLI_string_utils.h"
42 
43 #include "DEG_depsgraph.h"
44 #include "DEG_depsgraph_query.h"
45 
46 #include "GPU_framebuffer.h"
47 #include "GPU_texture.h"
48 #include "eevee_private.h"
49 
50 #define CAMERA_JITTER_RING_DENSITY 6
51 
52 static float coc_radius_from_camera_depth(bool is_ortho, EEVEE_EffectsInfo *fx, float camera_depth)
53 {
54  float multiplier = fx->dof_coc_params[0];
55  float bias = fx->dof_coc_params[1];
56  if (multiplier == 0.0f || bias == 0.0f) {
57  return 0.0f;
58  }
59  if (is_ortho) {
60  return (camera_depth + multiplier / bias) * multiplier;
61  }
62  return multiplier / camera_depth - bias;
63 }
64 
65 static float polygon_sides_length(float sides_count)
66 {
67  return 2.0 * sin(M_PI / sides_count);
68 }
69 
70 /* Returns intersection ratio between the radius edge at theta and the polygon edge.
71  * Start first corners at theta == 0. */
72 static float circle_to_polygon_radius(float sides_count, float theta)
73 {
74  /* From Graphics Gems from CryENGINE 3 (Siggraph 2013) by Tiago Sousa (slide 36). */
75  float side_angle = (2.0f * M_PI) / sides_count;
76  return cosf(side_angle * 0.5f) /
77  cosf(theta - side_angle * floorf((sides_count * theta + M_PI) / (2.0f * M_PI)));
78 }
79 
80 /* Remap input angle to have homogenous spacing of points along a polygon edge.
81  * Expect theta to be in [0..2pi] range. */
82 static float circle_to_polygon_angle(float sides_count, float theta)
83 {
84  float side_angle = (2.0f * M_PI) / sides_count;
85  float halfside_angle = side_angle * 0.5f;
86  float side = floorf(theta / side_angle);
87  /* Length of segment from center to the middle of polygon side. */
88  float adjacent = circle_to_polygon_radius(sides_count, 0.0f);
89 
90  /* This is the relative position of the sample on the polygon half side. */
91  float local_theta = theta - side * side_angle;
92  float ratio = (local_theta - halfside_angle) / halfside_angle;
93 
94  float halfside_len = polygon_sides_length(sides_count) * 0.5f;
95  float opposite = ratio * halfside_len;
96 
97  /* NOTE: atan(y_over_x) has output range [-M_PI_2..M_PI_2]. */
98  float final_local_theta = atanf(opposite / adjacent);
99 
100  return side * side_angle + final_local_theta;
101 }
102 
103 static int dof_jitter_total_sample_count(int ring_density, int ring_count)
104 {
105  return ((ring_count * ring_count + ring_count) / 2) * ring_density + 1;
106 }
107 
109  float r_jitter[2],
110  float *r_focus_distance)
111 {
112  if (fx->dof_jitter_radius == 0.0f) {
113  return false;
114  }
115 
116  int ring_density = CAMERA_JITTER_RING_DENSITY;
117  int ring_count = fx->dof_jitter_ring_count;
118  int sample_count = dof_jitter_total_sample_count(ring_density, ring_count);
119 
120  int s = fx->taa_current_sample - 1;
121 
122  int ring = 0;
123  int ring_sample_count = 1;
124  int ring_sample = 1;
125 
126  s = s * (ring_density - 1);
127  s = s % sample_count;
128 
129  int samples_passed = 1;
130  while (s >= samples_passed) {
131  ring++;
132  ring_sample_count = ring * ring_density;
133  ring_sample = s - samples_passed;
134  ring_sample = (ring_sample + 1) % ring_sample_count;
135  samples_passed += ring_sample_count;
136  }
137 
138  r_jitter[0] = (float)ring / ring_count;
139  r_jitter[1] = (float)ring_sample / ring_sample_count;
140 
141  {
142  /* Bokeh shape parameterization. */
143  float r = r_jitter[0];
144  float T = r_jitter[1] * 2.0f * M_PI;
145 
146  if (fx->dof_jitter_blades >= 3.0f) {
149  }
150 
151  T += fx->dof_bokeh_rotation;
152 
153  r_jitter[0] = r * cosf(T);
154  r_jitter[1] = r * sinf(T);
155 
156  mul_v2_v2(r_jitter, fx->dof_bokeh_aniso);
157  }
158 
159  mul_v2_fl(r_jitter, fx->dof_jitter_radius);
160 
161  *r_focus_distance = fx->dof_jitter_focus;
162  return true;
163 }
164 
166  int sample_count,
167  int *r_ring_count)
168 {
169  if (effects->dof_jitter_radius == 0.0f) {
170  if (r_ring_count != NULL) {
171  *r_ring_count = 0;
172  }
173  return 1;
174  }
175 
176  if (sample_count == TAA_MAX_SAMPLE) {
177  /* Special case for viewport continuous rendering. We clamp to a max sample to avoid the
178  * jittered dof never converging. */
179  sample_count = 1024;
180  }
181  /* Inversion of dof_jitter_total_sample_count. */
182  float x = 2.0f * (sample_count - 1.0f) / CAMERA_JITTER_RING_DENSITY;
183  /* Solving polynomial. We only search positive solution. */
184  float discriminant = 1.0f + 4.0f * x;
185  int ring_count = ceilf(0.5f * (sqrt(discriminant) - 1.0f));
186 
187  sample_count = dof_jitter_total_sample_count(CAMERA_JITTER_RING_DENSITY, ring_count);
188 
189  if (r_ring_count != NULL) {
190  *r_ring_count = ring_count;
191  }
192  return sample_count;
193 }
194 
196  EEVEE_Data *vedata,
197  Object *camera)
198 {
199  EEVEE_TextureList *txl = vedata->txl;
200  EEVEE_StorageList *stl = vedata->stl;
201  EEVEE_FramebufferList *fbl = vedata->fbl;
202  EEVEE_EffectsInfo *effects = stl->effects;
203 
204  const DRWContextState *draw_ctx = DRW_context_state_get();
205  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
206 
207  Camera *cam = (camera != NULL) ? camera->data : NULL;
208 
209  if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
210  RegionView3D *rv3d = draw_ctx->rv3d;
211  const float *viewport_size = DRW_viewport_size_get();
212 
213  effects->dof_hq_slight_focus = (scene_eval->eevee.flag & SCE_EEVEE_DOF_HQ_SLIGHT_FOCUS) != 0;
214 
215  /* Retrieve Near and Far distance */
216  effects->dof_coc_near_dist = -cam->clip_start;
217  effects->dof_coc_far_dist = -cam->clip_end;
218 
219  /* Parameters */
220  bool is_ortho = cam->type == CAM_ORTHO;
221  float fstop = cam->dof.aperture_fstop;
222  float blades = cam->dof.aperture_blades;
223  float rotation = cam->dof.aperture_rotation;
224  float ratio = 1.0f / max_ff(cam->dof.aperture_ratio, 0.00001f);
225  float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y);
226  float focus_dist = BKE_camera_object_dof_distance(camera);
227  float focal_len = cam->lens;
228 
229  if (is_ortho) {
230  /* (fclem) A bit of black magic here. I don't know if this is correct. */
231  fstop *= 1.3f;
232  focal_len = 1.0f;
233  sensor = cam->ortho_scale;
234  }
235 
236  const float scale_camera = (is_ortho) ? 1.0 : 0.001f;
237  /* we want radius here for the aperture number */
238  float aperture = 0.5f * scale_camera * focal_len / fstop;
239  float focal_len_scaled = scale_camera * focal_len;
240  float sensor_scaled = scale_camera * sensor;
241 
242  if (rv3d != NULL) {
243  sensor_scaled *= rv3d->viewcamtexcofac[0];
244  }
245 
246  if (ratio > 1.0) {
247  /* If ratio is scaling the bokeh outwards, we scale the aperture so that the gather
248  * kernel size will encompass the maximum axis. */
249  aperture *= ratio;
250  }
251 
252  effects->dof_coc_params[1] = -aperture *
253  fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
254  /* FIXME(fclem) This is broken for vertically fit sensor. */
255  effects->dof_coc_params[1] *= viewport_size[0] / sensor_scaled;
256 
257  if ((scene_eval->eevee.flag & SCE_EEVEE_DOF_JITTER) != 0) {
258  effects->dof_jitter_radius = effects->dof_coc_params[1];
259  effects->dof_jitter_focus = focus_dist;
260  effects->dof_jitter_blades = blades;
261 
262  int sample_count = EEVEE_temporal_sampling_sample_count_get(scene_eval, stl);
264  effects, sample_count, &effects->dof_jitter_ring_count);
265 
266  if (effects->dof_jitter_ring_count == 0) {
267  effects->dof_jitter_radius = 0.0f;
268  }
269  else {
270  /* Compute a minimal overblur radius to fill the gaps between the samples.
271  * This is just the simplified form of dividing the area of the bokeh
272  * by the number of samples. */
273  float minimal_overblur = 1.0f / sqrtf(sample_count);
274  float user_overblur = scene_eval->eevee.bokeh_overblur / 100.0f;
275 
276  minimal_overblur *= effects->dof_coc_params[1];
277  user_overblur *= effects->dof_coc_params[1];
278 
279  effects->dof_coc_params[1] = minimal_overblur + user_overblur;
280  /* Avoid dilating the shape. Over-blur only soften. */
281  effects->dof_jitter_radius -= minimal_overblur + user_overblur * 0.5f;
282  }
283  }
284  else {
285  effects->dof_jitter_radius = 0.0f;
286  }
287 
288  if (is_ortho) {
289  /* (fclem) A bit of black magic here. Needed to match cycles. */
290  effects->dof_coc_params[1] *= 0.225;
291  }
292 
293  effects->dof_coc_params[0] = -focus_dist * effects->dof_coc_params[1];
294 
295  effects->dof_bokeh_blades = blades;
296  effects->dof_bokeh_rotation = rotation;
297  effects->dof_bokeh_aniso[0] = min_ff(ratio, 1.0f);
298  effects->dof_bokeh_aniso[1] = min_ff(1.0f / ratio, 1.0f);
299  effects->dof_bokeh_max_size = scene_eval->eevee.bokeh_max_size;
300 
301  copy_v2_v2(effects->dof_bokeh_aniso_inv, effects->dof_bokeh_aniso);
302  invert_v2(effects->dof_bokeh_aniso_inv);
303 
304  effects->dof_scatter_color_threshold = scene_eval->eevee.bokeh_threshold;
306  effects->dof_denoise_factor = clamp_f(scene_eval->eevee.bokeh_denoise_fac, 0.0f, 1.0f);
307 
308  float max_abs_fg_coc, max_abs_bg_coc;
309  if (is_ortho) {
310  max_abs_fg_coc = fabsf(coc_radius_from_camera_depth(true, effects, -cam->clip_start));
311  max_abs_bg_coc = fabsf(coc_radius_from_camera_depth(true, effects, -cam->clip_end));
312  }
313  else {
314  max_abs_fg_coc = fabsf(coc_radius_from_camera_depth(false, effects, -cam->clip_start));
315  /* Background is at infinity so maximum CoC is the limit of the function at -inf. */
316  max_abs_bg_coc = fabsf(effects->dof_coc_params[1]);
317  }
318 
319  float max_coc = max_ff(max_abs_bg_coc, max_abs_fg_coc);
320  /* Clamp with user defined max. */
321  effects->dof_fx_max_coc = min_ff(scene_eval->eevee.bokeh_max_size, max_coc);
322 
323  if (effects->dof_fx_max_coc < 0.5f) {
324  return 0;
325  }
326 
328  }
329 
330  effects->dof_jitter_radius = 0.0f;
331 
332  /* Cleanup to release memory */
343 
344  return 0;
345 }
346 
347 #define WITH_FILTERING (GPU_SAMPLER_MIPMAP | GPU_SAMPLER_FILTER)
348 #define NO_FILTERING GPU_SAMPLER_MIPMAP
349 #define COLOR_FORMAT fx->dof_color_format
350 #define FG_TILE_FORMAT GPU_RGBA16F
351 #define BG_TILE_FORMAT GPU_R11F_G11F_B10F
352 
357  EEVEE_PassList *psl,
358  EEVEE_EffectsInfo *fx)
359 {
360  if ((fx->dof_bokeh_aniso[0] == 1.0f) && (fx->dof_bokeh_aniso[1] == 1.0f) &&
361  (fx->dof_bokeh_blades == 0.0)) {
365  return;
366  }
367 
368  void *owner = (void *)&EEVEE_depth_of_field_init;
369  int res[2] = {DOF_BOKEH_LUT_SIZE, DOF_BOKEH_LUT_SIZE};
370 
372 
375  DRW_shgroup_uniform_float_copy(grp, "bokehSides", fx->dof_bokeh_blades);
376  DRW_shgroup_uniform_float_copy(grp, "bokehRotation", fx->dof_bokeh_rotation);
377  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
379 
383 
384  GPU_framebuffer_ensure_config(&fbl->dof_bokeh_fb,
385  {
386  GPU_ATTACHMENT_NONE,
387  GPU_ATTACHMENT_TEXTURE(fx->dof_bokeh_gather_lut_tx),
388  GPU_ATTACHMENT_TEXTURE(fx->dof_bokeh_scatter_lut_tx),
389  GPU_ATTACHMENT_TEXTURE(fx->dof_bokeh_resolve_lut_tx),
390  });
391 }
392 
397  EEVEE_PassList *psl,
398  EEVEE_EffectsInfo *fx)
399 {
401 
402  void *owner = (void *)&EEVEE_depth_of_field_init;
403  const float *fullres = DRW_viewport_size_get();
404  int res[2] = {divide_ceil_u(fullres[0], 2), divide_ceil_u(fullres[1], 2)};
405 
407 
411  DRW_shgroup_uniform_texture_ref_ex(grp, "depthBuffer", &dtxl->depth, NO_FILTERING);
412  DRW_shgroup_uniform_vec4_copy(grp, "cocParams", fx->dof_coc_params);
413  DRW_shgroup_uniform_float_copy(grp, "bokehMaxSize", fx->dof_bokeh_max_size);
415 
418 
419  GPU_framebuffer_ensure_config(&fbl->dof_setup_fb,
420  {
421  GPU_ATTACHMENT_NONE,
422  GPU_ATTACHMENT_TEXTURE(fx->dof_half_res_color_tx),
423  GPU_ATTACHMENT_TEXTURE(fx->dof_half_res_coc_tx),
424  });
425 }
426 
431  EEVEE_PassList *psl,
432  EEVEE_EffectsInfo *fx)
433 {
434  void *owner = (void *)&EEVEE_depth_of_field_init;
435  const float *fullres = DRW_viewport_size_get();
436  int res[2] = {divide_ceil_u(fullres[0], DOF_TILE_DIVISOR),
437  divide_ceil_u(fullres[1], DOF_TILE_DIVISOR)};
438 
440 
444  grp, "halfResCocBuffer", &fx->dof_half_res_coc_tx, NO_FILTERING);
446 
449 
450  GPU_framebuffer_ensure_config(&fbl->dof_flatten_tiles_fb,
451  {
452  GPU_ATTACHMENT_NONE,
453  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_tiles_fg_tx),
454  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_tiles_bg_tx),
455  });
456 }
457 
464  EEVEE_PassList *psl,
465  EEVEE_EffectsInfo *fx)
466 {
467  void *owner = (void *)&EEVEE_depth_of_field_init;
468  const float *fullres = DRW_viewport_size_get();
469  int res[2] = {divide_ceil_u(fullres[0], DOF_TILE_DIVISOR),
470  divide_ceil_u(fullres[1], DOF_TILE_DIVISOR)};
471 
474 
475  for (int pass = 0; pass < 2; pass++) {
476  DRWPass *drw_pass = (pass == 0) ? psl->dof_dilate_tiles_minmax : psl->dof_dilate_tiles_minabs;
478  DRWShadingGroup *grp = DRW_shgroup_create(sh, drw_pass);
479  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_tiles_fg_tx);
480  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_tiles_bg_tx);
481  DRW_shgroup_uniform_bool(grp, "dilateSlightFocus", &fx->dof_dilate_slight_focus, 1);
482  DRW_shgroup_uniform_int(grp, "ringCount", &fx->dof_dilate_ring_count, 1);
483  DRW_shgroup_uniform_int(grp, "ringWidthMultiplier", &fx->dof_dilate_ring_width_multiplier, 1);
485  }
486 
489 
490  GPU_framebuffer_ensure_config(&fbl->dof_dilate_tiles_fb,
491  {
492  GPU_ATTACHMENT_NONE,
493  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_dilated_tiles_fg_tx),
494  GPU_ATTACHMENT_TEXTURE(fx->dof_coc_dilated_tiles_bg_tx),
495  });
496 }
497 
499  EEVEE_PassList *psl,
500  EEVEE_EffectsInfo *fx)
501 {
502  for (int pass = 0; pass < 2; pass++) {
503  DRWPass *drw_pass = (pass == 0) ? psl->dof_dilate_tiles_minmax : psl->dof_dilate_tiles_minabs;
504 
505  /* Error introduced by gather center jittering. */
506  const float error_multiplier = 1.0f + 1.0f / (DOF_GATHER_RING_COUNT + 0.5f);
507  int dilation_end_radius = ceilf((fx->dof_fx_max_coc * error_multiplier) / DOF_TILE_DIVISOR);
508 
509  /* This algorithm produce the exact dilation radius by dividing it in multiple passes. */
510  int dilation_radius = 0;
511  while (dilation_radius < dilation_end_radius) {
512  /* Dilate slight focus only on first iteration. */
513  fx->dof_dilate_slight_focus = (dilation_radius == 0) ? 1 : 0;
514 
515  int remainder = dilation_end_radius - dilation_radius;
516  /* Do not step over any unvisited tile. */
517  int max_multiplier = dilation_radius + 1;
518 
519  int ring_count = min_ii(DOF_DILATE_RING_COUNT, ceilf(remainder / (float)max_multiplier));
520  int multiplier = min_ii(max_multiplier, floor(remainder / (float)ring_count));
521 
522  dilation_radius += ring_count * multiplier;
523 
524  fx->dof_dilate_ring_count = ring_count;
525  fx->dof_dilate_ring_width_multiplier = multiplier;
526 
528  DRW_draw_pass(drw_pass);
529 
533  }
534  }
535  /* Swap again so that final textures are dof_coc_dilated_tiles_*_tx. */
539 }
540 
545  EEVEE_PassList *psl,
546  EEVEE_TextureList *txl,
547  EEVEE_EffectsInfo *fx)
548 {
549  const float *fullres = DRW_viewport_size_get();
550 
551  /* Divide by 2 because dof_fx_max_coc is in fullres CoC radius and the reduce texture begins at
552  * half resolution. */
553  float max_space_between_sample = fx->dof_fx_max_coc * 0.5f / DOF_GATHER_RING_COUNT;
554 
555  int mip_count = max_ii(1, log2_ceil_u(max_space_between_sample));
556 
557  fx->dof_reduce_steps = mip_count - 1;
558  /* This ensure the mipmaps are aligned for the needed 4 mip levels.
559  * Starts at 2 because already at half resolution. */
560  int multiple = 2 << (mip_count - 1);
561  int res[2] = {(multiple * divide_ceil_u(fullres[0], multiple)) / 2,
562  (multiple * divide_ceil_u(fullres[1], multiple)) / 2};
563 
564  int quater_res[2] = {divide_ceil_u(fullres[0], 4), divide_ceil_u(fullres[1], 4)};
565 
566  /* TODO(fclem): Make this dependent of the quality of the gather pass. */
567  fx->dof_scatter_coc_threshold = 4.0f;
568 
569  {
571 
575  grp, "colorBuffer", &fx->dof_reduce_input_color_tx, NO_FILTERING);
577  grp, "cocBuffer", &fx->dof_reduce_input_coc_tx, NO_FILTERING);
579 
580  void *owner = (void *)&EEVEE_depth_of_field_init;
582 
583  GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb,
584  {
585  GPU_ATTACHMENT_NONE,
586  GPU_ATTACHMENT_TEXTURE(fx->dof_downsample_tx),
587  });
588  }
589 
590  {
592 
593  const bool is_copy_pass = true;
597  grp, "colorBuffer", &fx->dof_reduce_input_color_tx, NO_FILTERING);
599  grp, "cocBuffer", &fx->dof_reduce_input_coc_tx, NO_FILTERING);
601  grp, "downsampledBuffer", &fx->dof_downsample_tx, NO_FILTERING);
602  DRW_shgroup_uniform_float_copy(grp, "scatterColorThreshold", fx->dof_scatter_color_threshold);
604  grp, "scatterColorNeighborMax", fx->dof_scatter_neighbor_max_color);
605  DRW_shgroup_uniform_float_copy(grp, "scatterCocThreshold", fx->dof_scatter_coc_threshold);
606  DRW_shgroup_uniform_float_copy(grp, "colorNeighborClamping", fx->dof_denoise_factor);
607  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
609 
610  void *owner = (void *)&EEVEE_depth_of_field_init;
612  }
613 
614  {
616 
617  const bool is_copy_pass = false;
621  grp, "colorBuffer", &fx->dof_reduce_input_color_tx, NO_FILTERING);
623  grp, "cocBuffer", &fx->dof_reduce_input_coc_tx, NO_FILTERING);
625  }
626 
627  if (txl->dof_reduced_color) {
628  /* TODO(fclem) In the future, we need to check if mip_count did not change.
629  * For now it's ok as we always define all mip level.*/
630  if (res[0] != GPU_texture_width(txl->dof_reduced_color) ||
631  res[1] != GPU_texture_width(txl->dof_reduced_color)) {
634  }
635  }
636 
637  if (txl->dof_reduced_color == NULL) {
638  /* Color needs to be signed format here. See note in shader for explanation. */
639  /* Do not use texture pool because of needs mipmaps. */
641  "dof_reduced_color", UNPACK2(res), mip_count, GPU_RGBA16F, NULL);
643  "dof_reduced_coc", UNPACK2(res), mip_count, GPU_R16F, NULL);
644 
645  /* TODO(fclem) Remove once we have immutable storage or when mips are generated on creation. */
648  }
649 
650  GPU_framebuffer_ensure_config(&fbl->dof_reduce_fb,
651  {
652  GPU_ATTACHMENT_NONE,
653  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_color),
654  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_coc),
655  });
656 
657  GPU_framebuffer_ensure_config(&fbl->dof_reduce_copy_fb,
658  {
659  GPU_ATTACHMENT_NONE,
660  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_color),
661  GPU_ATTACHMENT_TEXTURE(txl->dof_reduced_coc),
662  GPU_ATTACHMENT_TEXTURE(fx->dof_scatter_src_tx),
663  });
664 }
665 
671  EEVEE_PassList *psl,
672  EEVEE_TextureList *txl,
673  EEVEE_EffectsInfo *fx)
674 {
675  void *owner = (void *)&EEVEE_depth_of_field_init;
676  const float *fullres = DRW_viewport_size_get();
677  int res[2] = {divide_ceil_u(fullres[0], 2), divide_ceil_u(fullres[1], 2)};
678  int input_size[2];
679  GPU_texture_get_mipmap_size(txl->dof_reduced_color, 0, input_size);
680  float uv_correction_fac[2] = {res[0] / (float)input_size[0], res[1] / (float)input_size[1]};
681  float output_texel_size[2] = {1.0f / res[0], 1.0f / res[1]};
682  const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != NULL);
683 
684  {
686 
690  grp, "colorBufferBilinear", &txl->dof_reduced_color, WITH_FILTERING);
693  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_dilated_tiles_fg_tx);
694  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_dilated_tiles_bg_tx);
696  DRW_shgroup_uniform_vec2_copy(grp, "gatherInputUvCorrection", uv_correction_fac);
697  DRW_shgroup_uniform_vec2_copy(grp, "gatherOutputTexelSize", output_texel_size);
699 
700  /* Reuse textures from the setup pass. */
701  /* NOTE: We could use the texture pool do that for us but it does not track usage and it might
702  * backfire (it does in practice). */
705 
706  GPU_framebuffer_ensure_config(&fbl->dof_gather_fg_holefill_fb,
707  {
708  GPU_ATTACHMENT_NONE,
709  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_color_tx),
710  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_weight_tx),
711  });
712  }
713  {
715 
719  grp, "colorBufferBilinear", &txl->dof_reduced_color, WITH_FILTERING);
722  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_dilated_tiles_fg_tx);
723  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_dilated_tiles_bg_tx);
725  DRW_shgroup_uniform_vec2_copy(grp, "gatherInputUvCorrection", uv_correction_fac);
726  DRW_shgroup_uniform_vec2_copy(grp, "gatherOutputTexelSize", output_texel_size);
727  if (use_bokeh_tx) {
728  /* Negate to flip bokeh shape. Mimics optical phenomenon. */
730  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
732  /* Restore. */
734  }
736 
739  /* Reuse textures from the setup pass. */
740  /* NOTE: We could use the texture pool do that for us but it does not track usage and it might
741  * backfire (it does in practice). */
743 
744  /* NOTE: First target is holefill texture so we can use the median filter on it.
745  * See the filter function. */
746  GPU_framebuffer_ensure_config(&fbl->dof_gather_fg_fb,
747  {
748  GPU_ATTACHMENT_NONE,
749  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_color_tx),
750  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_weight_tx),
751  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_occlusion_tx),
752  });
753  }
754  {
756 
760  grp, "colorBufferBilinear", &txl->dof_reduced_color, WITH_FILTERING);
763  DRW_shgroup_uniform_texture_ref(grp, "cocTilesFgBuffer", &fx->dof_coc_dilated_tiles_fg_tx);
764  DRW_shgroup_uniform_texture_ref(grp, "cocTilesBgBuffer", &fx->dof_coc_dilated_tiles_bg_tx);
766  DRW_shgroup_uniform_vec2_copy(grp, "gatherInputUvCorrection", uv_correction_fac);
767  DRW_shgroup_uniform_vec2_copy(grp, "gatherOutputTexelSize", output_texel_size);
768  if (use_bokeh_tx) {
769  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
771  }
773 
776  /* Reuse, since only used for scatter. Foreground is processed before background. */
778 
779  /* NOTE: First target is holefill texture so we can use the median filter on it.
780  * See the filter function. */
781  GPU_framebuffer_ensure_config(&fbl->dof_gather_bg_fb,
782  {
783  GPU_ATTACHMENT_NONE,
784  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_color_tx),
785  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_holefill_weight_tx),
786  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_occlusion_tx),
787  });
788  }
789 }
790 
797  EEVEE_PassList *psl,
798  EEVEE_EffectsInfo *fx)
799 {
801 
805  grp, "colorBuffer", &fx->dof_fg_holefill_color_tx, NO_FILTERING);
807  grp, "weightBuffer", &fx->dof_fg_holefill_weight_tx, NO_FILTERING);
809 
810  GPU_framebuffer_ensure_config(&fbl->dof_filter_fg_fb,
811  {
812  GPU_ATTACHMENT_NONE,
813  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_color_tx),
814  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_weight_tx),
815  });
816 
817  GPU_framebuffer_ensure_config(&fbl->dof_filter_bg_fb,
818  {
819  GPU_ATTACHMENT_NONE,
820  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_color_tx),
821  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_weight_tx),
822  });
823 }
824 
830  EEVEE_PassList *psl,
831  EEVEE_TextureList *txl,
832  EEVEE_EffectsInfo *fx)
833 {
834  int input_size[2], target_size[2];
836  GPU_texture_get_mipmap_size(fx->dof_bg_color_tx, 0, target_size);
837  /* Draw a sprite for every four half-res pixels. */
838  int sprite_count = (input_size[0] / 2) * (input_size[1] / 2);
839  float target_texel_size[2] = {1.0f / target_size[0], 1.0f / target_size[1]};
840  const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != NULL);
841 
842  {
844 
845  const bool is_foreground = true;
846  GPUShader *sh = EEVEE_shaders_depth_of_field_scatter_get(is_foreground, use_bokeh_tx);
850  DRW_shgroup_uniform_texture_ref(grp, "occlusionBuffer", &fx->dof_fg_occlusion_tx);
851  DRW_shgroup_uniform_vec2_copy(grp, "targetTexelSize", target_texel_size);
852  DRW_shgroup_uniform_int_copy(grp, "spritePerRow", input_size[0] / 2);
853  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
854  if (use_bokeh_tx) {
855  /* Negate to flip bokeh shape. Mimics optical phenomenon. */
857  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
859  /* Restore. */
861  }
862  DRW_shgroup_call_procedural_triangles(grp, NULL, sprite_count);
863 
864  GPU_framebuffer_ensure_config(&fbl->dof_scatter_fg_fb,
865  {
866  GPU_ATTACHMENT_NONE,
867  GPU_ATTACHMENT_TEXTURE(fx->dof_fg_color_tx),
868  });
869  }
870  {
872 
873  const bool is_foreground = false;
874  GPUShader *sh = EEVEE_shaders_depth_of_field_scatter_get(is_foreground, use_bokeh_tx);
878  DRW_shgroup_uniform_texture_ref(grp, "occlusionBuffer", &fx->dof_bg_occlusion_tx);
879  DRW_shgroup_uniform_vec2_copy(grp, "targetTexelSize", target_texel_size);
880  DRW_shgroup_uniform_int_copy(grp, "spritePerRow", input_size[0] / 2);
881  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropy", fx->dof_bokeh_aniso);
882  if (use_bokeh_tx) {
883  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
885  }
886  DRW_shgroup_call_procedural_triangles(grp, NULL, sprite_count);
887 
888  GPU_framebuffer_ensure_config(&fbl->dof_scatter_bg_fb,
889  {
890  GPU_ATTACHMENT_NONE,
891  GPU_ATTACHMENT_TEXTURE(fx->dof_bg_color_tx),
892  });
893  }
894 }
895 
901  EEVEE_PassList *psl,
902  EEVEE_EffectsInfo *fx)
903 {
905  const bool use_bokeh_tx = (fx->dof_bokeh_gather_lut_tx != NULL);
906 
908 
911  DRW_shgroup_uniform_texture_ref_ex(grp, "fullResColorBuffer", &fx->source_buffer, NO_FILTERING);
912  DRW_shgroup_uniform_texture_ref_ex(grp, "fullResDepthBuffer", &dtxl->depth, NO_FILTERING);
913  DRW_shgroup_uniform_texture_ref(grp, "bgColorBuffer", &fx->dof_bg_color_tx);
914  DRW_shgroup_uniform_texture_ref(grp, "bgWeightBuffer", &fx->dof_bg_weight_tx);
916  DRW_shgroup_uniform_texture_ref(grp, "fgColorBuffer", &fx->dof_fg_color_tx);
917  DRW_shgroup_uniform_texture_ref(grp, "fgWeightBuffer", &fx->dof_fg_weight_tx);
918  DRW_shgroup_uniform_texture_ref(grp, "holefillColorBuffer", &fx->dof_fg_holefill_color_tx);
919  DRW_shgroup_uniform_texture_ref(grp, "holefillWeightBuffer", &fx->dof_fg_holefill_weight_tx);
922  DRW_shgroup_uniform_vec4_copy(grp, "cocParams", fx->dof_coc_params);
923  DRW_shgroup_uniform_float_copy(grp, "bokehMaxSize", fx->dof_bokeh_max_size);
924  if (use_bokeh_tx) {
925  DRW_shgroup_uniform_vec2_copy(grp, "bokehAnisotropyInv", fx->dof_bokeh_aniso_inv);
927  }
929 }
930 
932 {
933  EEVEE_TextureList *txl = vedata->txl;
934  EEVEE_FramebufferList *fbl = vedata->fbl;
935  EEVEE_PassList *psl = vedata->psl;
936  EEVEE_StorageList *stl = vedata->stl;
937  EEVEE_EffectsInfo *fx = stl->effects;
938 
939  if ((fx->enabled_effects & EFFECT_DOF) != 0) {
940  /* GPU_RGBA16F is sufficient now that all scattered bokeh are premultiplied.
941  * GPU_R11F_G11F_B10F is not enough when lots of scattered sprites are big and offers
942  * relatively small benefits. */
944 
945  dof_bokeh_pass_init(fbl, psl, fx);
946  dof_setup_pass_init(fbl, psl, fx);
947  dof_flatten_tiles_pass_init(fbl, psl, fx);
948  dof_dilate_tiles_pass_init(fbl, psl, fx);
949  dof_reduce_pass_init(fbl, psl, txl, fx);
950  dof_gather_pass_init(fbl, psl, txl, fx);
951  dof_filter_pass_init(fbl, psl, fx);
952  dof_scatter_pass_init(fbl, psl, txl, fx);
953  dof_recombine_pass_init(fbl, psl, fx);
954  }
955 }
956 
957 static void dof_recursive_reduce(void *vedata, int UNUSED(level))
958 {
959  EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
960  EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl;
961  EEVEE_EffectsInfo *fx = ((EEVEE_Data *)vedata)->stl->effects;
962 
965 
967 }
968 
970 {
971  EEVEE_PassList *psl = vedata->psl;
972  EEVEE_TextureList *txl = vedata->txl;
973  EEVEE_FramebufferList *fbl = vedata->fbl;
974  EEVEE_StorageList *stl = vedata->stl;
975  EEVEE_EffectsInfo *effects = stl->effects; /* TODO(fclem): Because of silly SWAP_BUFFERS. */
976  EEVEE_EffectsInfo *fx = effects;
977 
978  /* Depth Of Field */
979  if ((effects->enabled_effects & EFFECT_DOF) != 0) {
980  DRW_stats_group_start("Depth of Field");
981 
982  if (fx->dof_bokeh_gather_lut_tx != NULL) {
984  DRW_draw_pass(psl->dof_bokeh);
985  }
986 
988  DRW_draw_pass(psl->dof_setup);
989 
992 
993  dof_dilate_tiles_pass_draw(fbl, psl, fx);
994 
997 
998  /* First step is just a copy. */
1001 
1002  /* First step is just a copy. */
1005 
1008 
1009  {
1010  /* Foreground convolution. */
1013 
1015  DRW_draw_pass(psl->dof_filter);
1016 
1019  }
1020 
1021  {
1022  /* Background convolution. */
1025 
1027  DRW_draw_pass(psl->dof_filter);
1028 
1031  }
1032 
1033  {
1034  /* Hole-fill convolution. */
1037 
1038  /* NOTE: do not filter the hole-fill pass as we use it as out filter input buffer. */
1039  }
1040 
1042  DRW_draw_pass(psl->dof_resolve);
1043 
1044  SWAP_BUFFERS();
1045 
1047  }
1048 }
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:242
float BKE_camera_object_dof_distance(struct Object *ob)
Definition: camera.c:227
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 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:38
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
@ SCE_EEVEE_DOF_HQ_SLIGHT_FOCUS
@ SCE_EEVEE_DOF_JITTER
@ DRW_STATE_BLEND_ADD_FULL
Definition: DRW_render.h:338
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
struct GPUFrameBuffer GPUFrameBuffer
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
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:33
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
int GPU_texture_width(const GPUTexture *tex)
Definition: gpu_texture.cc:527
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
Definition: gpu_texture.cc:590
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:250
@ GPU_RG16F
Definition: GPU_texture.h:104
@ GPU_R16F
Definition: GPU_texture.h:114
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:119
void GPU_texture_generate_mipmap(GPUTexture *tex)
Definition: gpu_texture.cc:447
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:702
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)
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()
#define DOF_TILE_DIVISOR
struct GPUShader * EEVEE_shaders_depth_of_field_bokeh_get(void)
#define TAA_MAX_SAMPLE
Definition: eevee_private.h:59
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)
#define sinf(x)
#define cosf(x)
#define ceilf(x)
#define atanf(x)
#define floorf(x)
#define fabsf(x)
#define sqrtf(x)
MINLINE uint divide_ceil_u(uint a, uint b)
#define T
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
Definition: rall1d.h:311
float clip_end
char sensor_fit
float sensor_y
float sensor_x
float clip_start
struct CameraDOFSettings dof
float ortho_scale
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct RegionView3D * rv3d
Definition: DRW_render.h:741
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
void * data
float viewcamtexcofac[4]
float bokeh_denoise_fac
float bokeh_overblur
float bokeh_threshold
float bokeh_neighbor_max
float bokeh_max_size
struct SceneEEVEE eevee
ccl_device_inline float2 floor(const float2 &a)