Blender V4.3
eevee_raytrace.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include <fstream>
12#include <iostream>
13
14#include "BKE_global.hh"
15
16#include "eevee_instance.hh"
17
18#include "eevee_raytrace.hh"
19
20namespace blender::eevee {
21
22/* -------------------------------------------------------------------- */
28{
29 const SceneEEVEE &sce_eevee = inst_.scene->eevee;
30
31 ray_tracing_options_ = sce_eevee.ray_tracing_options;
32 if ((sce_eevee.flag & SCE_EEVEE_FAST_GI_ENABLED) == 0) {
33 ray_tracing_options_.trace_max_roughness = 1.0f;
34 }
35
36 tracing_method_ = RaytraceEEVEE_Method(sce_eevee.ray_tracing_method);
37 fast_gi_ray_count_ = sce_eevee.fast_gi_ray_count;
38 fast_gi_step_count_ = sce_eevee.fast_gi_step_count;
39 fast_gi_ao_only_ = (sce_eevee.fast_gi_method == FAST_GI_AO_ONLY);
40
41 float4 data(0.0f);
42 radiance_dummy_black_tx_.ensure_2d(
44}
45
47{
48 Texture &depth_tx = inst_.render_buffers.depth_tx;
49
50#define PASS_VARIATION(_pass_name, _index, _suffix) \
51 ((_index == 0) ? _pass_name##reflect##_suffix : \
52 (_index == 1) ? _pass_name##refract##_suffix : \
53 _pass_name##diffuse##_suffix)
54
55 /* Setup. */
56 {
57 PassSimple &pass = tile_classify_ps_;
58 pass.init();
59 pass.shader_set(inst_.shaders.static_shader_get(RAY_TILE_CLASSIFY));
60 pass.bind_image("tile_raytrace_denoise_img", &tile_raytrace_denoise_tx_);
61 pass.bind_image("tile_raytrace_tracing_img", &tile_raytrace_tracing_tx_);
62 pass.bind_image("tile_horizon_denoise_img", &tile_horizon_denoise_tx_);
63 pass.bind_image("tile_horizon_tracing_img", &tile_horizon_tracing_tx_);
64 pass.bind_resources(inst_.uniform_data);
65 pass.bind_resources(inst_.gbuffer);
66 pass.dispatch(&tile_classify_dispatch_size_);
68 }
69 {
70 PassSimple &pass = tile_compact_ps_;
72 pass.init();
73 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
74 pass.specialize_constant(sh, "resolution_scale", &data_.resolution_scale);
75 pass.shader_set(sh);
76 pass.bind_image("tile_raytrace_denoise_img", &tile_raytrace_denoise_tx_);
77 pass.bind_image("tile_raytrace_tracing_img", &tile_raytrace_tracing_tx_);
78 pass.bind_ssbo("raytrace_tracing_dispatch_buf", &raytrace_tracing_dispatch_buf_);
79 pass.bind_ssbo("raytrace_denoise_dispatch_buf", &raytrace_denoise_dispatch_buf_);
80 pass.bind_ssbo("raytrace_tracing_tiles_buf", &raytrace_tracing_tiles_buf_);
81 pass.bind_ssbo("raytrace_denoise_tiles_buf", &raytrace_denoise_tiles_buf_);
82 pass.bind_resources(inst_.uniform_data);
83 pass.dispatch(&tile_compact_dispatch_size_);
84 pass.barrier(GPU_BARRIER_SHADER_STORAGE);
85 }
86 {
87 PassSimple &pass = generate_ps_;
88 pass.init();
90 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
91 pass.shader_set(sh);
92 pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
93 pass.bind_image("out_ray_data_img", &ray_data_tx_);
94 pass.bind_ssbo("tiles_coord_buf", &raytrace_tracing_tiles_buf_);
95 pass.bind_resources(inst_.uniform_data);
96 pass.bind_resources(inst_.sampling);
97 pass.bind_resources(inst_.gbuffer);
98 pass.dispatch(raytrace_tracing_dispatch_buf_);
101 }
102 /* Tracing. */
103 {
104 PassSimple &pass = trace_planar_ps_;
105 pass.init();
107 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
108 pass.shader_set(sh);
109 pass.bind_ssbo("tiles_coord_buf", &raytrace_tracing_tiles_buf_);
110 pass.bind_image("ray_data_img", &ray_data_tx_);
111 pass.bind_image("ray_time_img", &ray_time_tx_);
112 pass.bind_image("ray_radiance_img", &ray_radiance_tx_);
113 pass.bind_texture("depth_tx", &depth_tx);
114 pass.bind_resources(inst_.uniform_data);
115 pass.bind_resources(inst_.sampling);
116 pass.bind_resources(inst_.planar_probes);
117 pass.bind_resources(inst_.volume_probes);
118 pass.bind_resources(inst_.sphere_probes);
119 pass.bind_resources(inst_.gbuffer);
120 /* TODO(@fclem): Use another dispatch with only tiles that touches planar captures. */
121 pass.dispatch(raytrace_tracing_dispatch_buf_);
123 }
124 {
125 PassSimple &pass = trace_screen_ps_;
126 pass.init();
128 pass.specialize_constant(
129 sh, "trace_refraction", reinterpret_cast<bool *>(&data_.trace_refraction));
130 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
131 pass.shader_set(sh);
132 pass.bind_ssbo("tiles_coord_buf", &raytrace_tracing_tiles_buf_);
133 pass.bind_image("ray_data_img", &ray_data_tx_);
134 pass.bind_image("ray_time_img", &ray_time_tx_);
135 pass.bind_texture("radiance_front_tx", &screen_radiance_front_tx_);
136 pass.bind_texture("radiance_back_tx", &screen_radiance_back_tx_);
137 pass.bind_texture("hiz_front_tx", &inst_.hiz_buffer.front.ref_tx_);
138 pass.bind_texture("hiz_back_tx", &inst_.hiz_buffer.back.ref_tx_);
139 /* Still bind front to hiz_tx for validation layers. */
140 pass.bind_resources(inst_.hiz_buffer.front);
141 pass.bind_texture("depth_tx", &depth_tx);
142 pass.bind_image("ray_radiance_img", &ray_radiance_tx_);
143 pass.bind_resources(inst_.uniform_data);
144 pass.bind_resources(inst_.sampling);
145 pass.bind_resources(inst_.volume_probes);
146 pass.bind_resources(inst_.sphere_probes);
147 pass.bind_resources(inst_.gbuffer);
148 pass.dispatch(raytrace_tracing_dispatch_buf_);
150 }
151 {
152 PassSimple &pass = trace_fallback_ps_;
153 pass.init();
155 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
156 pass.shader_set(sh);
157 pass.bind_ssbo("tiles_coord_buf", &raytrace_tracing_tiles_buf_);
158 pass.bind_image("ray_data_img", &ray_data_tx_);
159 pass.bind_image("ray_time_img", &ray_time_tx_);
160 pass.bind_image("ray_radiance_img", &ray_radiance_tx_);
161 pass.bind_texture("depth_tx", &depth_tx);
162 pass.bind_resources(inst_.uniform_data);
163 pass.bind_resources(inst_.volume_probes);
164 pass.bind_resources(inst_.sphere_probes);
165 pass.bind_resources(inst_.sampling);
166 pass.bind_resources(inst_.gbuffer);
167 pass.dispatch(raytrace_tracing_dispatch_buf_);
169 }
170 /* Denoise. */
171 {
172 PassSimple &pass = denoise_spatial_ps_;
174 pass.init();
175 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
176 pass.specialize_constant(sh, "raytrace_resolution_scale", &data_.resolution_scale);
177 pass.specialize_constant(sh, "skip_denoise", reinterpret_cast<bool *>(&data_.skip_denoise));
178 pass.shader_set(sh);
179 pass.bind_ssbo("tiles_coord_buf", &raytrace_denoise_tiles_buf_);
180 pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
181 pass.bind_texture("depth_tx", &depth_tx);
182 pass.bind_image("ray_data_img", &ray_data_tx_);
183 pass.bind_image("ray_time_img", &ray_time_tx_);
184 pass.bind_image("ray_radiance_img", &ray_radiance_tx_);
185 pass.bind_image("out_radiance_img", &denoised_spatial_tx_);
186 pass.bind_image("out_variance_img", &hit_variance_tx_);
187 pass.bind_image("out_hit_depth_img", &hit_depth_tx_);
188 pass.bind_image("tile_mask_img", &tile_raytrace_denoise_tx_);
189 pass.bind_resources(inst_.uniform_data);
190 pass.bind_resources(inst_.sampling);
191 pass.bind_resources(inst_.gbuffer);
192 pass.dispatch(raytrace_denoise_dispatch_buf_);
194 }
195 {
196 PassSimple &pass = denoise_temporal_ps_;
198 pass.init();
199 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
200 pass.shader_set(sh);
201 pass.bind_resources(inst_.uniform_data);
202 pass.bind_texture("radiance_history_tx", &radiance_history_tx_);
203 pass.bind_texture("variance_history_tx", &variance_history_tx_);
204 pass.bind_texture("tilemask_history_tx", &tilemask_history_tx_);
205 pass.bind_texture("depth_tx", &depth_tx);
206 pass.bind_image("hit_depth_img", &hit_depth_tx_);
207 pass.bind_image("in_radiance_img", &denoised_spatial_tx_);
208 pass.bind_image("out_radiance_img", &denoised_temporal_tx_);
209 pass.bind_image("in_variance_img", &hit_variance_tx_);
210 pass.bind_image("out_variance_img", &denoise_variance_tx_);
211 pass.bind_ssbo("tiles_coord_buf", &raytrace_denoise_tiles_buf_);
212 pass.bind_resources(inst_.sampling);
213 pass.dispatch(raytrace_denoise_dispatch_buf_);
215 }
216 {
217 PassSimple &pass = denoise_bilateral_ps_;
218 pass.init();
220 pass.specialize_constant(sh, "closure_index", &data_.closure_index);
221 pass.shader_set(sh);
222 pass.bind_texture("depth_tx", &depth_tx);
223 pass.bind_image("in_radiance_img", &denoised_temporal_tx_);
224 pass.bind_image("out_radiance_img", &denoised_bilateral_tx_);
225 pass.bind_image("in_variance_img", &denoise_variance_tx_);
226 pass.bind_image("tile_mask_img", &tile_raytrace_denoise_tx_);
227 pass.bind_ssbo("tiles_coord_buf", &raytrace_denoise_tiles_buf_);
228 pass.bind_resources(inst_.uniform_data);
229 pass.bind_resources(inst_.sampling);
230 pass.bind_resources(inst_.gbuffer);
231 pass.dispatch(raytrace_denoise_dispatch_buf_);
233 }
234 {
235 PassSimple &pass = horizon_schedule_ps_;
236 /* Reuse tile compaction shader but feed it with horizon scan specific buffers. */
238 pass.init();
239 pass.specialize_constant(sh, "closure_index", 0);
240 pass.specialize_constant(sh, "resolution_scale", &data_.horizon_resolution_scale);
241 pass.shader_set(sh);
242 pass.bind_image("tile_raytrace_denoise_img", &tile_horizon_denoise_tx_);
243 pass.bind_image("tile_raytrace_tracing_img", &tile_horizon_tracing_tx_);
244 pass.bind_ssbo("raytrace_tracing_dispatch_buf", &horizon_tracing_dispatch_buf_);
245 pass.bind_ssbo("raytrace_denoise_dispatch_buf", &horizon_denoise_dispatch_buf_);
246 pass.bind_ssbo("raytrace_tracing_tiles_buf", &horizon_tracing_tiles_buf_);
247 pass.bind_ssbo("raytrace_denoise_tiles_buf", &horizon_denoise_tiles_buf_);
248 pass.bind_resources(inst_.uniform_data);
249 pass.dispatch(&horizon_schedule_dispatch_size_);
250 pass.barrier(GPU_BARRIER_SHADER_STORAGE);
251 }
252 {
253 PassSimple &pass = horizon_setup_ps_;
254 pass.init();
255 pass.shader_set(inst_.shaders.static_shader_get(HORIZON_SETUP));
256 pass.bind_resources(inst_.uniform_data);
257 pass.bind_texture("depth_tx", &depth_tx);
258 pass.bind_texture(
259 "in_radiance_tx", &screen_radiance_front_tx_, GPUSamplerState::default_sampler());
260 pass.bind_image("out_radiance_img", &downsampled_in_radiance_tx_);
261 pass.bind_image("out_normal_img", &downsampled_in_normal_tx_);
262 pass.bind_resources(inst_.uniform_data);
263 pass.bind_resources(inst_.gbuffer);
264 pass.dispatch(&horizon_tracing_dispatch_size_);
266 }
267 {
268 PassSimple &pass = horizon_scan_ps_;
269 pass.init();
271 pass.specialize_constant(sh, "fast_gi_slice_count", fast_gi_ray_count_);
272 pass.specialize_constant(sh, "fast_gi_step_count", fast_gi_step_count_);
273 pass.specialize_constant(sh, "fast_gi_ao_only", fast_gi_ao_only_);
274 pass.shader_set(sh);
275 pass.bind_texture("screen_radiance_tx", &downsampled_in_radiance_tx_);
276 pass.bind_texture("screen_normal_tx", &downsampled_in_normal_tx_);
277 pass.bind_image("horizon_radiance_0_img", &horizon_radiance_tx_[0]);
278 pass.bind_image("horizon_radiance_1_img", &horizon_radiance_tx_[1]);
279 pass.bind_image("horizon_radiance_2_img", &horizon_radiance_tx_[2]);
280 pass.bind_image("horizon_radiance_3_img", &horizon_radiance_tx_[3]);
281 pass.bind_ssbo("tiles_coord_buf", &horizon_tracing_tiles_buf_);
282 pass.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx);
283 pass.bind_resources(inst_.uniform_data);
284 pass.bind_resources(inst_.hiz_buffer.front);
285 pass.bind_resources(inst_.sampling);
286 pass.bind_resources(inst_.gbuffer);
287 pass.dispatch(horizon_tracing_dispatch_buf_);
288 pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
289 }
290 {
291 PassSimple &pass = horizon_denoise_ps_;
292 pass.init();
294 pass.shader_set(sh);
295 pass.bind_texture("in_sh_0_tx", &horizon_radiance_tx_[0]);
296 pass.bind_texture("in_sh_1_tx", &horizon_radiance_tx_[1]);
297 pass.bind_texture("in_sh_2_tx", &horizon_radiance_tx_[2]);
298 pass.bind_texture("in_sh_3_tx", &horizon_radiance_tx_[3]);
299 pass.bind_texture("screen_normal_tx", &downsampled_in_normal_tx_);
300 pass.bind_image("out_sh_0_img", &horizon_radiance_denoised_tx_[0]);
301 pass.bind_image("out_sh_1_img", &horizon_radiance_denoised_tx_[1]);
302 pass.bind_image("out_sh_2_img", &horizon_radiance_denoised_tx_[2]);
303 pass.bind_image("out_sh_3_img", &horizon_radiance_denoised_tx_[3]);
304 pass.bind_ssbo("tiles_coord_buf", &horizon_tracing_tiles_buf_);
305 pass.bind_resources(inst_.uniform_data);
306 pass.bind_resources(inst_.sampling);
307 pass.bind_resources(inst_.hiz_buffer.front);
308 pass.dispatch(horizon_tracing_dispatch_buf_);
309 pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
310 }
311 {
312 PassSimple &pass = horizon_resolve_ps_;
313 pass.init();
315 pass.shader_set(sh);
316 pass.bind_texture("depth_tx", &depth_tx);
317 pass.bind_texture("horizon_radiance_0_tx", &horizon_radiance_denoised_tx_[0]);
318 pass.bind_texture("horizon_radiance_1_tx", &horizon_radiance_denoised_tx_[1]);
319 pass.bind_texture("horizon_radiance_2_tx", &horizon_radiance_denoised_tx_[2]);
320 pass.bind_texture("horizon_radiance_3_tx", &horizon_radiance_denoised_tx_[3]);
321 pass.bind_texture("screen_normal_tx", &downsampled_in_normal_tx_);
322 pass.bind_image("closure0_img", &horizon_scan_output_tx_[0]);
323 pass.bind_image("closure1_img", &horizon_scan_output_tx_[1]);
324 pass.bind_image("closure2_img", &horizon_scan_output_tx_[2]);
325 pass.bind_ssbo("tiles_coord_buf", &horizon_denoise_tiles_buf_);
326 pass.bind_resources(inst_.uniform_data);
327 pass.bind_resources(inst_.sampling);
328 pass.bind_resources(inst_.gbuffer);
329 pass.bind_resources(inst_.volume_probes);
330 pass.bind_resources(inst_.sphere_probes);
331 pass.dispatch(horizon_denoise_dispatch_buf_);
333 }
334}
335
337
338void RayTraceModule::debug_draw(View & /*view*/, GPUFrameBuffer * /*view_fb*/) {}
339
341 GPUTexture *screen_radiance_back_tx,
342 eClosureBits active_closures,
343 /* TODO(fclem): Maybe wrap these two in some other class. */
344 View &main_view,
345 View &render_view)
346{
347 using namespace blender::math;
348
349 screen_radiance_front_tx_ = rt_buffer.radiance_feedback_tx.is_valid() ?
350 rt_buffer.radiance_feedback_tx :
351 radiance_dummy_black_tx_;
352 screen_radiance_back_tx_ = screen_radiance_back_tx ? screen_radiance_back_tx :
353 screen_radiance_front_tx_;
354
355 RaytraceEEVEE options = ray_tracing_options_;
356
357 bool use_horizon_scan = options.trace_max_roughness < 1.0f;
358
359 const int resolution_scale = max_ii(1, power_of_2_max_i(options.resolution_scale));
360 const int horizon_resolution_scale = max_ii(
362
363 const int2 extent = inst_.film.render_extent_get();
364 const int2 tracing_res = math::divide_ceil(extent, int2(resolution_scale));
365 const int2 tracing_res_horizon = math::divide_ceil(extent, int2(horizon_resolution_scale));
366 const int2 dummy_extent(1, 1);
367 const int2 group_size(RAYTRACE_GROUP_SIZE);
368
369 const int2 denoise_tiles = divide_ceil(extent, group_size);
370 const int2 raytrace_tiles = divide_ceil(tracing_res, group_size);
371 const int2 raytrace_tiles_horizon = divide_ceil(tracing_res_horizon, group_size);
372 const int denoise_tile_count = denoise_tiles.x * denoise_tiles.y;
373 const int raytrace_tile_count = raytrace_tiles.x * raytrace_tiles.y;
374 const int raytrace_tile_count_horizon = raytrace_tiles_horizon.x * raytrace_tiles_horizon.y;
375 tile_classify_dispatch_size_ = int3(denoise_tiles, 1);
376 horizon_schedule_dispatch_size_ = int3(divide_ceil(raytrace_tiles_horizon, group_size), 1);
377 tile_compact_dispatch_size_ = int3(divide_ceil(raytrace_tiles, group_size), 1);
378 tracing_dispatch_size_ = int3(raytrace_tiles, 1);
379 horizon_tracing_dispatch_size_ = int3(raytrace_tiles_horizon, 1);
380
381 /* TODO(fclem): Use real max closure count from shader. */
382 const int closure_count = 3;
385 tile_raytrace_denoise_tx_.ensure_2d_array(format, denoise_tiles, closure_count, usage_rw);
386 tile_raytrace_tracing_tx_.ensure_2d_array(format, raytrace_tiles, closure_count, usage_rw);
387 /* Kept as 2D array for compatibility with the tile compaction shader. */
388 tile_horizon_denoise_tx_.ensure_2d_array(format, denoise_tiles, 1, usage_rw);
389 tile_horizon_tracing_tx_.ensure_2d_array(format, raytrace_tiles_horizon, 1, usage_rw);
390
391 tile_raytrace_denoise_tx_.clear(uint4(0u));
392 tile_raytrace_tracing_tx_.clear(uint4(0u));
393 tile_horizon_denoise_tx_.clear(uint4(0u));
394 tile_horizon_tracing_tx_.clear(uint4(0u));
395
396 horizon_tracing_tiles_buf_.resize(ceil_to_multiple_u(raytrace_tile_count_horizon, 512));
397 horizon_denoise_tiles_buf_.resize(ceil_to_multiple_u(denoise_tile_count, 512));
398 raytrace_tracing_tiles_buf_.resize(ceil_to_multiple_u(raytrace_tile_count, 512));
399 raytrace_denoise_tiles_buf_.resize(ceil_to_multiple_u(denoise_tile_count, 512));
400
401 /* Data for tile classification. */
402 float roughness_mask_start = options.trace_max_roughness;
403 float roughness_mask_fade = 0.2f;
404 data_.roughness_mask_scale = 1.0 / roughness_mask_fade;
405 data_.roughness_mask_bias = data_.roughness_mask_scale * roughness_mask_start;
406
407 /* Data for the radiance setup. */
408 data_.resolution_scale = resolution_scale;
409 data_.resolution_bias = int2(inst_.sampling.rng_2d_get(SAMPLING_RAYTRACE_V) * resolution_scale);
410 data_.radiance_persmat = render_view.persmat();
411 data_.full_resolution = extent;
412 data_.full_resolution_inv = 1.0f / float2(extent);
413
414 data_.horizon_resolution_scale = horizon_resolution_scale;
416 horizon_resolution_scale);
417 /* TODO(fclem): Eventually all uniform data is setup here. */
418
420
422
423 DRW_stats_group_start("Raytracing");
424
425 const bool has_active_closure = active_closures != CLOSURE_NONE;
426
427 if (has_active_closure) {
428 inst_.manager->submit(tile_classify_ps_);
429 }
430
431 data_.trace_refraction = screen_radiance_back_tx != nullptr;
432
433 for (int i = 0; i < 3; i++) {
434 result.closures[i] = trace(i, (closure_count > i), options, rt_buffer, main_view, render_view);
435 }
436
437 if (has_active_closure) {
438 if (use_horizon_scan) {
439 DRW_stats_group_start("Horizon Scan");
440
441 downsampled_in_radiance_tx_.acquire(tracing_res_horizon, RAYTRACE_RADIANCE_FORMAT, usage_rw);
442 downsampled_in_normal_tx_.acquire(tracing_res_horizon, GPU_RGB10_A2, usage_rw);
443
444 horizon_radiance_tx_[0].acquire(tracing_res_horizon, GPU_RGBA16F, usage_rw);
445 horizon_radiance_denoised_tx_[0].acquire(tracing_res_horizon, GPU_RGBA16F, usage_rw);
446 for (int i : IndexRange(1, 3)) {
447 horizon_radiance_tx_[i].acquire(tracing_res_horizon, GPU_RGBA8, usage_rw);
448 horizon_radiance_denoised_tx_[i].acquire(tracing_res_horizon, GPU_RGBA8, usage_rw);
449 }
450 for (int i : IndexRange(3)) {
451 horizon_scan_output_tx_[i] = result.closures[i];
452 }
453
454 horizon_tracing_dispatch_buf_.clear_to_zero();
455 horizon_denoise_dispatch_buf_.clear_to_zero();
456 inst_.manager->submit(horizon_schedule_ps_);
457
458 inst_.manager->submit(horizon_setup_ps_, render_view);
459 inst_.manager->submit(horizon_scan_ps_, render_view);
460 inst_.manager->submit(horizon_denoise_ps_, render_view);
461 inst_.manager->submit(horizon_resolve_ps_, render_view);
462
463 for (int i : IndexRange(4)) {
464 horizon_radiance_tx_[i].release();
465 horizon_radiance_denoised_tx_[i].release();
466 }
467 downsampled_in_radiance_tx_.release();
468 downsampled_in_normal_tx_.release();
469
471 }
472 }
473
475
476 rt_buffer.history_persmat = render_view.persmat();
477
478 return result;
479}
480
481RayTraceResultTexture RayTraceModule::trace(
482 int closure_index,
483 bool active_layer,
485 RayTraceBuffer &rt_buffer,
486 /* TODO(fclem): Maybe wrap these two in some other class. */
487 View &main_view,
488 View &render_view)
489{
490 RayTraceBuffer::DenoiseBuffer *denoise_buf = &rt_buffer.closures[closure_index];
491
492 if (!active_layer) {
493 /* Early out. Release persistent buffers. Still acquire one dummy resource for validation. */
495 denoise_buf->radiance_history_tx.free();
496 denoise_buf->variance_history_tx.free();
497 denoise_buf->tilemask_history_tx.free();
498 return {denoise_buf->denoised_spatial_tx};
499 }
500
501 const int resolution_scale = max_ii(1, power_of_2_max_i(options.resolution_scale));
502
503 const int2 extent = inst_.film.render_extent_get();
504 const int2 tracing_res = math::divide_ceil(extent, int2(resolution_scale));
505
506 renderbuf_depth_view_ = inst_.render_buffers.depth_tx;
507
508 const bool use_denoise = (options.flag & RAYTRACE_EEVEE_USE_DENOISE);
509 const bool use_spatial_denoise = (options.denoise_stages & RAYTRACE_EEVEE_DENOISE_SPATIAL) &&
510 use_denoise;
511 const bool use_temporal_denoise = (options.denoise_stages & RAYTRACE_EEVEE_DENOISE_TEMPORAL) &&
512 use_spatial_denoise;
513 const bool use_bilateral_denoise = (options.denoise_stages & RAYTRACE_EEVEE_DENOISE_BILATERAL) &&
514 use_temporal_denoise;
515
517
518 DRW_stats_group_start("Raytracing");
519
520 data_.thickness = options.screen_trace_thickness;
521 data_.quality = 1.0f - 0.95f * options.screen_trace_quality;
522
523 float roughness_mask_start = options.trace_max_roughness;
524 float roughness_mask_fade = 0.2f;
525 data_.roughness_mask_scale = 1.0 / roughness_mask_fade;
526 data_.roughness_mask_bias = data_.roughness_mask_scale * roughness_mask_start;
527
528 data_.resolution_scale = resolution_scale;
529 data_.resolution_bias = int2(inst_.sampling.rng_2d_get(SAMPLING_RAYTRACE_V) * resolution_scale);
530 data_.history_persmat = denoise_buf->history_persmat;
531 data_.radiance_persmat = render_view.persmat();
532 data_.full_resolution = extent;
533 data_.full_resolution_inv = 1.0f / float2(extent);
534 data_.skip_denoise = !use_spatial_denoise;
535 data_.closure_index = closure_index;
537
538 /* Ray setup. */
539 raytrace_tracing_dispatch_buf_.clear_to_zero();
540 raytrace_denoise_dispatch_buf_.clear_to_zero();
541 inst_.manager->submit(tile_compact_ps_);
542
543 {
544 /* Tracing rays. */
545 ray_data_tx_.acquire(tracing_res, GPU_RGBA16F);
546 ray_time_tx_.acquire(tracing_res, RAYTRACE_RAYTIME_FORMAT);
547 ray_radiance_tx_.acquire(tracing_res, RAYTRACE_RADIANCE_FORMAT);
548
549 inst_.manager->submit(generate_ps_, render_view);
550 if (tracing_method_ == RAYTRACE_EEVEE_METHOD_SCREEN) {
551 if (inst_.planar_probes.enabled()) {
552 inst_.manager->submit(trace_planar_ps_, render_view);
553 }
554 inst_.manager->submit(trace_screen_ps_, render_view);
555 }
556 else {
557 inst_.manager->submit(trace_fallback_ps_, render_view);
558 }
559 }
560
561 RayTraceResultTexture result;
562
563 /* Spatial denoise pass is required to resolve at least one ray per pixel. */
564 {
566 hit_variance_tx_.acquire(use_temporal_denoise ? extent : int2(1), RAYTRACE_VARIANCE_FORMAT);
567 hit_depth_tx_.acquire(use_temporal_denoise ? extent : int2(1), GPU_R32F);
568 denoised_spatial_tx_ = denoise_buf->denoised_spatial_tx;
569
570 inst_.manager->submit(denoise_spatial_ps_, render_view);
571
572 result = {denoise_buf->denoised_spatial_tx};
573 }
574
575 ray_data_tx_.release();
576 ray_time_tx_.release();
577 ray_radiance_tx_.release();
578
579 if (use_temporal_denoise) {
580 denoise_buf->denoised_temporal_tx.acquire(extent, RAYTRACE_RADIANCE_FORMAT, usage_rw);
581 denoise_variance_tx_.acquire(
582 use_bilateral_denoise ? extent : int2(1), RAYTRACE_VARIANCE_FORMAT, usage_rw);
583 denoise_buf->variance_history_tx.ensure_2d(
584 RAYTRACE_VARIANCE_FORMAT, use_bilateral_denoise ? extent : int2(1), usage_rw);
586 tile_raytrace_denoise_tx_.size().xy(),
587 tile_raytrace_denoise_tx_.size().z,
588 usage_rw);
589
590 if (denoise_buf->radiance_history_tx.ensure_2d(RAYTRACE_RADIANCE_FORMAT, extent, usage_rw) ||
591 denoise_buf->valid_history == false)
592 {
593 /* If viewport resolution changes, do not try to use history. */
594 denoise_buf->tilemask_history_tx.clear(uint4(0u));
595 }
596
597 radiance_history_tx_ = denoise_buf->radiance_history_tx;
598 variance_history_tx_ = denoise_buf->variance_history_tx;
599 tilemask_history_tx_ = denoise_buf->tilemask_history_tx;
600 denoised_temporal_tx_ = denoise_buf->denoised_temporal_tx;
601
602 inst_.manager->submit(denoise_temporal_ps_, render_view);
603
604 /* Save view-projection matrix for next reprojection. */
605 denoise_buf->history_persmat = main_view.persmat();
606 /* Radiance will be swapped with history in #RayTraceResult::release().
607 * Variance is swapped with history after bilateral denoise.
608 * It keeps data-flow easier to follow. */
609 result = {denoise_buf->denoised_temporal_tx, denoise_buf->radiance_history_tx};
610 /* Not referenced by result anymore. */
611 denoise_buf->denoised_spatial_tx.release();
612
613 GPU_texture_copy(denoise_buf->tilemask_history_tx, tile_raytrace_denoise_tx_);
614 }
615
616 /* Only use history buffer for the next frame if temporal denoise was used by the current one. */
617 denoise_buf->valid_history = use_temporal_denoise;
618
619 hit_variance_tx_.release();
620 hit_depth_tx_.release();
621
622 if (use_bilateral_denoise) {
623 denoise_buf->denoised_bilateral_tx.acquire(extent, RAYTRACE_RADIANCE_FORMAT, usage_rw);
624 denoised_bilateral_tx_ = denoise_buf->denoised_bilateral_tx;
625
626 inst_.manager->submit(denoise_bilateral_ps_, render_view);
627
628 /* Swap after last use. */
630 TextureFromPool::swap(denoise_variance_tx_, denoise_buf->variance_history_tx);
631
632 result = {denoise_buf->denoised_bilateral_tx};
633 /* Not referenced by result anymore. */
634 denoise_buf->denoised_temporal_tx.release();
635 }
636
637 denoise_variance_tx_.release();
638
640
641 return result;
642}
643
645{
646 const int2 extent = inst_.film.render_extent_get();
648
650 for (int i = 0; i < 3; i++) {
651 RayTraceBuffer::DenoiseBuffer *denoise_buf = &rt_buffer.closures[i];
652 denoise_buf->denoised_bilateral_tx.acquire(extent, RAYTRACE_RADIANCE_FORMAT, usage_rw);
653 result.closures[i] = {denoise_buf->denoised_bilateral_tx};
654 }
655 return result;
656}
657
659{
661
663 for (int i = 0; i < 3; i++) {
664 RayTraceBuffer::DenoiseBuffer *denoise_buf = &rt_buffer.closures[i];
666 result.closures[i] = {denoise_buf->denoised_bilateral_tx};
667 }
668 return result;
669}
672} // namespace blender::eevee
MINLINE uint ceil_to_multiple_u(uint a, uint b)
MINLINE int power_of_2_max_i(int n)
MINLINE int max_ii(int a, int b)
RaytraceEEVEE_Method
@ RAYTRACE_EEVEE_METHOD_SCREEN
@ RAYTRACE_EEVEE_USE_DENOISE
@ SCE_EEVEE_FAST_GI_ENABLED
@ FAST_GI_AO_ONLY
@ RAYTRACE_EEVEE_DENOISE_BILATERAL
@ RAYTRACE_EEVEE_DENOISE_SPATIAL
@ RAYTRACE_EEVEE_DENOISE_TEMPORAL
@ GPU_BARRIER_SHADER_STORAGE
Definition GPU_state.hh:48
@ GPU_BARRIER_TEXTURE_FETCH
Definition GPU_state.hh:37
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
Definition GPU_state.hh:35
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
eGPUTextureFormat
@ GPU_RGB10_A2
struct GPUShader GPUShader
void submit(PassSimple &pass, View &view)
static void swap(TextureFromPool &a, Texture &b)
void acquire(int2 extent, eGPUTextureFormat format, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL)
void clear(float4 values)
bool ensure_2d_array(eGPUTextureFormat format, int2 extent, int layers, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
bool ensure_2d(eGPUTextureFormat format, int2 extent, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
int3 size(int miplvl=0) const
const float4x4 persmat(int view_id=0) const
Definition draw_view.hh:158
int2 render_extent_get() const
struct blender::eevee::HiZBuffer::@195 front
struct blender::eevee::HiZBuffer::@195 back
VolumeProbeModule volume_probes
SphereProbeModule sphere_probes
PlanarProbeModule planar_probes
UniformDataModule uniform_data
RayTraceResult alloc_only(RayTraceBuffer &rt_buffer)
RayTraceResult render(RayTraceBuffer &rt_buffer, GPUTexture *screen_radiance_back_tx, eClosureBits active_closures, View &main_view, View &render_view)
void debug_draw(View &view, GPUFrameBuffer *view_fb)
RayTraceResult alloc_dummy(RayTraceBuffer &rt_buffer)
float2 rng_2d_get(eSamplingDimension starting_dimension) const
GPUShader * static_shader_get(eShaderType shader_type)
CCL_NAMESPACE_BEGIN struct Options options
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end()
#define RAYTRACE_VARIANCE_FORMAT
#define RBUFS_UTILITY_TEX_SLOT
#define RAYTRACE_GROUP_SIZE
#define RAYTRACE_RAYTIME_FORMAT
#define RAYTRACE_RADIANCE_FORMAT
#define RAYTRACE_TILEMASK_FORMAT
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
format
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< uint32_t, 4 > uint4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< int32_t, 3 > int3
static constexpr GPUSamplerState default_sampler()
struct RaytraceEEVEE ray_tracing_options
struct SceneEEVEE eevee
VecBase< T, 2 > xy() const