Blender V5.0
eevee_pipeline.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#pragma once
14
15#include "BLI_math_bits.h"
16
17#include "DRW_render.hh"
18
19#include "eevee_lut.hh"
20#include "eevee_material.hh"
21#include "eevee_raytrace.hh"
22#include "eevee_subsurface.hh"
24
25struct Camera;
26
27namespace blender::eevee {
28
29class Instance;
30struct RayTraceBuffer;
31
32/* -------------------------------------------------------------------- */
37
39 private:
40 Instance &inst_;
41
42 PassSimple clear_ps_ = {"World.Background.Clear"};
43 PassSimple world_ps_ = {"World.Background"};
44
45 public:
46 BackgroundPipeline(Instance &inst) : inst_(inst) {};
47
48 void sync(GPUMaterial *gpumat, float background_opacity, float background_blur);
49 void clear(View &view);
50 void render(View &view, Framebuffer &combined_fb);
51};
52
54
55/* -------------------------------------------------------------------- */
60
62 private:
63 Instance &inst_;
64
65 /* Dummy textures: required to reuse background shader and avoid another shader variation. */
66 Texture dummy_renderpass_tx_;
67 Texture dummy_cryptomatte_tx_;
68 Texture dummy_aov_color_tx_;
69 Texture dummy_aov_value_tx_;
70
71 PassSimple cubemap_face_ps_ = {"World.Probe"};
72
73 public:
74 WorldPipeline(Instance &inst) : inst_(inst) {};
75
76 void sync(GPUMaterial *gpumat);
77 void render(View &view);
78
79}; // namespace blender::eevee
80
82
83/* -------------------------------------------------------------------- */
87
89 private:
90 Instance &inst_;
91 bool is_valid_;
92
93 PassSimple world_ps_ = {"World.Volume"};
94
95 public:
96 WorldVolumePipeline(Instance &inst) : inst_(inst) {};
97
98 void sync(GPUMaterial *gpumat);
99 void render(View &view);
100};
101
103
104/* -------------------------------------------------------------------- */
108
110 private:
111 Instance &inst_;
112
113 /* Shadow update pass. */
114 PassMain render_ps_ = {"Shadow.Surface"};
115 /* Shadow surface render sub-passes. */
116 PassMain::Sub *surface_double_sided_ps_ = nullptr;
117 PassMain::Sub *surface_single_sided_ps_ = nullptr;
118
119 public:
120 ShadowPipeline(Instance &inst) : inst_(inst) {};
121
123
124 void sync();
125
126 void render(View &view);
127};
128
130
131/* -------------------------------------------------------------------- */
136
138 private:
139 Instance &inst_;
140
141 PassMain prepass_ps_ = {"Prepass"};
142 PassMain::Sub *prepass_single_sided_static_ps_ = nullptr;
143 PassMain::Sub *prepass_single_sided_moving_ps_ = nullptr;
144 PassMain::Sub *prepass_double_sided_static_ps_ = nullptr;
145 PassMain::Sub *prepass_double_sided_moving_ps_ = nullptr;
146
147 PassMain opaque_ps_ = {"Shading"};
148 PassMain::Sub *opaque_single_sided_ps_ = nullptr;
149 PassMain::Sub *opaque_double_sided_ps_ = nullptr;
150
151 PassSortable transparent_ps_ = {"Forward.Transparent"};
152 float3 camera_forward_;
153
154 bool has_opaque_ = false;
155 bool has_transparent_ = false;
156
157 public:
158 ForwardPipeline(Instance &inst) : inst_(inst) {};
159
160 void sync();
161
162 PassMain::Sub *prepass_opaque_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
164
166 ::Material *blender_mat,
167 GPUMaterial *gpumat);
169 ::Material *blender_mat,
170 GPUMaterial *gpumat);
171
172 void render(View &view, Framebuffer &prepass_fb, Framebuffer &combined_fb, int2 extent);
173};
174
176
177/* -------------------------------------------------------------------- */
180
182 PassMain prepass_ps_ = {"Prepass"};
187
188 PassMain gbuffer_ps_ = {"Shading"};
189 /* Shaders that use the ClosureToRGBA node needs to be rendered first.
190 * Consider they hybrid forward and deferred. */
195
196 /* Closures bits from the materials in this pass. */
198 /* Maximum closure count considering all material in this pass. */
200
201 /* Stencil values used during the deferred pipeline. */
202 enum class StencilBits : uint8_t {
203 /* Bits 0 to 1 are reserved for closure count [0..3]. */
204 CLOSURE_COUNT_0 = (1u << 0u),
205 CLOSURE_COUNT_1 = (1u << 1u),
206 /* Set for pixels have a transmission closure. */
207 TRANSMISSION = (1u << 2u),
210
211 /* Set for materials that uses the shadow amend pass. */
215 };
216
217 /* Return the amount of gbuffer layer needed. */
219 {
220 /* Default header. */
221 int count = 1;
222 /* SSS, light linking, shadow offset all require an additional layer to store the object ID.
223 * Since tracking these are not part of the closure bits and are rather common features,
224 * always require one layer for it. */
225 count += 1;
226 return count;
227 }
228
229 /* Return the amount of gbuffer layer needed. */
231 {
232 /* Always allocate 2 layer per closure for interleaved closure data packing in the gbuffer. */
234 }
235
236 /* Return the amount of gbuffer layer needed. */
238 {
239 /* TODO(fclem): We could count the number of different tangent frame in the shader and use
240 * min(tangent_frame_count, closure_count) once we have the normal reuse optimization.
241 * For now, allocate a custom normal layer for each Closure. */
243 /* Count the additional information layer needed by some closures. */
246 return count;
247 }
248
250 {
251 return closure_bits_;
252 }
253
254 void gbuffer_pass_sync(Instance &inst);
255};
256
257class DeferredPipeline;
258
260 friend DeferredPipeline;
261
262 private:
263 Instance &inst_;
264
265 static constexpr int max_lighting_tile_count_ = 128 * 128;
266
267 /* Evaluate all light objects contribution. */
268 PassSimple eval_light_ps_ = {"EvalLights"};
269 /* Combine direct and indirect light contributions and apply BSDF color. */
270 PassSimple combine_ps_ = {"Combine"};
271
281 TextureFromPool direct_radiance_txs_[3] = {
282 {"direct_radiance_1"}, {"direct_radiance_2"}, {"direct_radiance_3"}};
283 /* NOTE: Only used when `use_split_radiance` is true. */
284 TextureFromPool indirect_radiance_txs_[3] = {
285 {"indirect_radiance_1"}, {"indirect_radiance_2"}, {"indirect_radiance_3"}};
286 /* Used when there is no indirect radiance buffer. */
287 Texture dummy_black = {"dummy_black"};
288 /* Reference to ray-tracing results. */
289 gpu::Texture *radiance_feedback_tx_ = nullptr;
290
295 Texture tile_mask_tx_ = {"tile_mask_tx_"};
296
297 RayTraceResult indirect_result_;
298
299 bool use_split_radiance_ = true;
300 /* Output radiance from the combine shader instead of copy. Allow passing unclamped result. */
301 bool use_feedback_output_ = false;
302 bool use_raytracing_ = false;
303 bool use_screen_transmission_ = false;
304 bool use_screen_reflection_ = false;
305 bool use_clamp_direct_ = false;
306 bool use_clamp_indirect_ = false;
307
308 public:
309 DeferredLayer(Instance &inst) : inst_(inst)
310 {
311 float4 data(0.0f);
312 dummy_black.ensure_2d(gpu::TextureFormat::RAYTRACE_RADIANCE_FORMAT,
313 int2(1),
315 data);
316 }
317
318 void begin_sync();
319 void end_sync(bool is_first_pass, bool is_last_pass, bool next_layer_has_transmission);
320
321 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
322 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
323
324 bool is_empty() const
325 {
326 return closure_count_ == 0;
327 }
328
329 bool has_transmission() const
330 {
332 }
333
334 /* Do we compute indirect lighting inside the light eval pass. */
335 static bool do_merge_direct_indirect_eval(const Instance &inst);
336 /* Is the radiance split for the lighting pass. */
337 static bool do_split_direct_indirect_radiance(const Instance &inst);
338
339 /* Returns the radiance buffer to feed the next layer. */
340 gpu::Texture *render(View &main_view,
341 View &render_view,
342 Framebuffer &prepass_fb,
343 Framebuffer &combined_fb,
344 Framebuffer &gbuffer_fb,
345 int2 extent,
346 RayTraceBuffer &rt_buffer,
347 gpu::Texture *radiance_behind_tx);
348};
349
351 friend DeferredLayer;
352
353 private:
354 /* Gbuffer filling passes. We could have an arbitrary number of them but for now we just have
355 * a hardcoded number of them. */
356 DeferredLayer opaque_layer_;
357 DeferredLayer refraction_layer_;
358 DeferredLayer volumetric_layer_;
359
360 PassSimple debug_draw_ps_ = {"debug_gbuffer"};
361
362 bool use_combined_lightprobe_eval;
363
364 public:
366 : opaque_layer_(inst), refraction_layer_(inst), volumetric_layer_(inst) {};
367
368 void begin_sync();
369 void end_sync();
370
371 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
372 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
373
374 void render(View &main_view,
375 View &render_view,
376 Framebuffer &prepass_fb,
377 Framebuffer &combined_fb,
378 Framebuffer &gbuffer_fb,
379 int2 extent,
380 RayTraceBuffer &rt_buffer_opaque_layer,
381 RayTraceBuffer &rt_buffer_refract_layer);
382
383 /* Return the maximum amount of gbuffer layer needed. */
385 {
386 return max_ii(opaque_layer_.header_layer_count(), refraction_layer_.header_layer_count());
387 }
388
389 /* Return the maximum amount of gbuffer layer needed. */
391 {
392 return max_ii(opaque_layer_.closure_layer_count(), refraction_layer_.closure_layer_count());
393 }
394
395 /* Return the maximum amount of gbuffer layer needed. */
397 {
398 return max_ii(opaque_layer_.normal_layer_count(), refraction_layer_.normal_layer_count());
399 }
400
401 void debug_draw(draw::View &view, gpu::FrameBuffer *combined_fb);
402
403 bool is_empty() const
404 {
405 return opaque_layer_.is_empty() && refraction_layer_.is_empty();
406 }
407
409 {
410 return opaque_layer_.closure_bits_get() | refraction_layer_.closure_bits_get();
411 }
412
413 private:
414 void debug_pass_sync();
415};
416
418
419/* -------------------------------------------------------------------- */
423
425 /* Screen 2D bounds for layer intersection check. */
426 std::optional<Bounds<float2>> screen_bounds;
427 /* Combined bounds in Z. Allow tighter integration bounds. */
428 std::optional<Bounds<float>> z_range;
429
430 VolumeObjectBounds(const Camera &camera, Object *ob);
431};
432
437 public:
438 bool use_hit_list = false;
439 bool is_empty = true;
440 bool finalized = false;
441 bool has_scatter = false;
442 bool has_absorption = false;
443
444 private:
445 Instance &inst_;
446
447 PassMain volume_layer_ps_ = {"Volume.Layer"};
448 /* Sub-passes of volume_layer_ps. */
449 PassMain::Sub *occupancy_ps_;
450 PassMain::Sub *material_ps_;
451 /* List of bounds from all objects contained inside this pass. */
453 /* Combined bounds from object_bounds_. */
454 std::optional<Bounds<float2>> combined_screen_bounds_;
455
456 public:
457 VolumeLayer(Instance &inst) : inst_(inst)
458 {
459 this->sync();
460 }
461
463 const ::Material *blender_mat,
464 GPUMaterial *gpumat);
466 const ::Material *blender_mat,
467 GPUMaterial *gpumat);
468
469 /* Return true if the given bounds overlaps any of the contained object in this layer. */
470 bool bounds_overlaps(const VolumeObjectBounds &object_bounds) const;
471
472 void add_object_bound(const VolumeObjectBounds &object_bounds);
473
474 void sync();
475 void render(View &view, Texture &occupancy_tx);
476};
477
479 private:
480 Instance &inst_;
481
483
484 /* Combined bounds in Z. Allow tighter integration bounds. */
485 std::optional<Bounds<float>> object_integration_range_;
486 /* Aggregated properties of all volume objects. */
487 bool has_scatter_ = false;
488 bool has_absorption_ = false;
489
490 public:
491 VolumePipeline(Instance &inst) : inst_(inst) {};
492
493 void sync();
494 void render(View &view, Texture &occupancy_tx);
495
501
502 std::optional<Bounds<float>> object_integration_range() const;
503
504 bool has_scatter() const
505 {
506 for (const auto &layer : layers_) {
507 if (layer->has_scatter) {
508 return true;
509 }
510 }
511 return false;
512 }
513 bool has_absorption() const
514 {
515 for (const auto &layer : layers_) {
516 if (layer->has_absorption) {
517 return true;
518 }
519 }
520 return false;
521 }
522
523 /* Returns true if any volume layer uses the hist list. */
524 bool use_hit_list() const;
525};
526
528
529/* -------------------------------------------------------------------- */
532
534 private:
535 Instance &inst_;
536
537 DeferredLayerBase opaque_layer_;
538
539 PassSimple eval_light_ps_ = {"EvalLights"};
540
541 public:
542 DeferredProbePipeline(Instance &inst) : inst_(inst) {};
543
544 void begin_sync();
545 void end_sync();
546
547 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat);
548 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
549
550 void render(View &view,
551 Framebuffer &prepass_fb,
552 Framebuffer &combined_fb,
553 Framebuffer &gbuffer_fb,
554 int2 extent);
555
556 /* Return the maximum amount of gbuffer layer needed. */
558 {
559 return opaque_layer_.header_layer_count();
560 }
561
562 /* Return the maximum amount of gbuffer layer needed. */
564 {
565 return opaque_layer_.closure_layer_count();
566 }
567
568 /* Return the maximum amount of gbuffer layer needed. */
570 {
571 return opaque_layer_.normal_layer_count();
572 }
573};
574
576
577/* -------------------------------------------------------------------- */
580
582 private:
583 Instance &inst_;
584
585 PassSimple eval_light_ps_ = {"EvalLights"};
586
587 public:
588 PlanarProbePipeline(Instance &inst) : inst_(inst) {};
589
590 void begin_sync();
591 void end_sync();
592
593 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat);
594 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
595
596 void render(View &view,
597 gpu::Texture *depth_layer_tx,
598 Framebuffer &gbuffer,
599 Framebuffer &combined_fb,
600 int2 extent);
601};
602
604
605/* -------------------------------------------------------------------- */
609
611 private:
612 Instance &inst_;
613
614 PassMain surface_ps_ = {"Capture.Surface"};
615
616 public:
617 CapturePipeline(Instance &inst) : inst_(inst) {};
618
620
621 void sync();
622 void render(View &view);
623};
624
626
627/* -------------------------------------------------------------------- */
632
633class UtilityTexture : public Texture {
634 struct Layer {
636 };
637
638 static constexpr int lut_size = UTIL_TEX_SIZE;
639 static constexpr int lut_size_sqr = lut_size * lut_size;
640 static constexpr int layer_count = UTIL_BTDF_LAYER + UTIL_BTDF_LAYER_COUNT;
641
642 public:
644 : Texture("UtilityTx",
645 gpu::TextureFormat::SFLOAT_16_16_16_16,
647 int2(lut_size),
648 layer_count,
649 nullptr)
650 {
651 Vector<Layer> data(layer_count);
652 {
653 Layer &layer = data[UTIL_BLUE_NOISE_LAYER];
654 memcpy(layer.data, lut::blue_noise, sizeof(layer));
655 }
656 {
658 for (auto y : IndexRange(lut_size)) {
659 for (auto x : IndexRange(lut_size)) {
660 /* Repeatedly stored on every row for correct interpolation. */
661 layer.data[y][x][0] = lut::burley_sss_profile[x][0];
662 layer.data[y][x][1] = lut::random_walk_sss_profile[x][0];
663 layer.data[y][x][2] = 0.0f;
665 }
666 }
668 }
669 {
670 Layer &layer = data[UTIL_LTC_MAT_LAYER];
671 memcpy(layer.data, lut::ltc_mat_ggx, sizeof(layer));
672 }
673 {
674 Layer &layer = data[UTIL_BSDF_LAYER];
675 for (auto x : IndexRange(lut_size)) {
676 for (auto y : IndexRange(lut_size)) {
677 layer.data[y][x][0] = lut::brdf_ggx[y][x][0];
678 layer.data[y][x][1] = lut::brdf_ggx[y][x][1];
679 layer.data[y][x][2] = lut::brdf_ggx[y][x][2];
680 layer.data[y][x][3] = 0.0f;
681 }
682 }
683 }
684 {
685 for (auto layer_id : IndexRange(16)) {
686 Layer &layer = data[UTIL_BTDF_LAYER + layer_id];
687 for (auto x : IndexRange(lut_size)) {
688 for (auto y : IndexRange(lut_size)) {
689 layer.data[y][x][0] = lut::bsdf_ggx[layer_id][y][x][0];
690 layer.data[y][x][1] = lut::bsdf_ggx[layer_id][y][x][1];
691 layer.data[y][x][2] = lut::bsdf_ggx[layer_id][y][x][2];
692 layer.data[y][x][3] = lut::btdf_ggx[layer_id][y][x][0];
693 }
694 }
695 }
696 }
698 }
699
700 ~UtilityTexture() = default;
701};
702
704
705/* -------------------------------------------------------------------- */
710
712 public:
723
726
728 : background(inst),
729 world(inst),
730 world_volume(inst),
731 probe(inst),
732 planar(inst),
733 deferred(inst),
734 forward(inst),
735 shadow(inst),
736 volume(inst),
737 capture(inst),
738 data(data) {};
739
741 {
742 data.is_sphere_probe = false;
743 probe.begin_sync();
744 planar.begin_sync();
745 deferred.begin_sync();
746 forward.sync();
747 shadow.sync();
748 volume.sync();
749 capture.sync();
750 }
751
752 void end_sync()
753 {
754 probe.end_sync();
755 planar.end_sync();
756 deferred.end_sync();
757 }
758
759 PassMain::Sub *material_add(Object * /*ob*/ /* TODO remove. */,
760 ::Material *blender_mat,
761 GPUMaterial *gpumat,
762 eMaterialPipeline pipeline_type,
763 eMaterialProbe probe_capture)
764 {
765 if (probe_capture == MAT_PROBE_REFLECTION) {
766 switch (pipeline_type) {
768 return probe.prepass_add(blender_mat, gpumat);
770 return probe.material_add(blender_mat, gpumat);
771 default:
773 break;
774 }
775 }
776 if (probe_capture == MAT_PROBE_PLANAR) {
777 switch (pipeline_type) {
779 return planar.prepass_add(blender_mat, gpumat);
781 return planar.material_add(blender_mat, gpumat);
782 default:
784 break;
785 }
786 }
787
788 switch (pipeline_type) {
790 return deferred.prepass_add(blender_mat, gpumat, false);
792 return forward.prepass_opaque_add(blender_mat, gpumat, false);
794 BLI_assert_msg(0, "Overlap prepass should register to the forward pipeline directly.");
795 return nullptr;
796
798 return deferred.prepass_add(blender_mat, gpumat, true);
800 return forward.prepass_opaque_add(blender_mat, gpumat, true);
801
803 return deferred.material_add(blender_mat, gpumat);
804 case MAT_PIPE_FORWARD:
805 return forward.material_opaque_add(blender_mat, gpumat);
806 case MAT_PIPE_SHADOW:
807 return shadow.surface_material_add(blender_mat, gpumat);
808 case MAT_PIPE_CAPTURE:
809 return capture.surface_material_add(blender_mat, gpumat);
810
813 BLI_assert_msg(0, "Volume shaders must register to the volume pipeline directly.");
814 return nullptr;
815
817 /* Should be handled by the `probe_capture == MAT_PROBE_PLANAR` case. */
819 return nullptr;
820 }
821 return nullptr;
822 }
823};
824
826
827} // namespace blender::eevee
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE int max_ii(int a, int b)
MINLINE int count_bits_i(unsigned int n)
static AppView * view
void GPU_texture_update_mipmap(blender::gpu::Texture *texture, int mip_level, eGPUDataFormat data_format, const void *pixels)
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
BMesh const char void * data
Texture(const char *name="gpu::Texture")
detail::PassBase< command::DrawMultiBuf > Sub
Definition draw_pass.hh:499
void sync(GPUMaterial *gpumat, float background_opacity, float background_blur)
PassMain::Sub * surface_material_add(::Material *blender_mat, GPUMaterial *gpumat)
void end_sync(bool is_first_pass, bool is_last_pass, bool next_layer_has_transmission)
static bool do_merge_direct_indirect_eval(const Instance &inst)
static bool do_split_direct_indirect_radiance(const Instance &inst)
PassMain::Sub * prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion)
PassMain::Sub * material_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion)
eClosureBits closure_bits_get() const
void debug_draw(draw::View &view, gpu::FrameBuffer *combined_fb)
PassMain::Sub * material_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * material_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * prepass_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * prepass_opaque_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion)
PassMain::Sub * material_opaque_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * material_transparent_add(const Object *ob, ::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * prepass_transparent_add(const Object *ob, ::Material *blender_mat, GPUMaterial *gpumat)
A running instance of the engine.
PipelineModule(Instance &inst, PipelineInfoData &data)
PassMain::Sub * material_add(Object *, ::Material *blender_mat, GPUMaterial *gpumat, eMaterialPipeline pipeline_type, eMaterialProbe probe_capture)
PassMain::Sub * prepass_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * material_add(::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * surface_material_add(::Material *material, GPUMaterial *gpumat)
void add_object_bound(const VolumeObjectBounds &object_bounds)
bool bounds_overlaps(const VolumeObjectBounds &object_bounds) const
PassMain::Sub * occupancy_add(const Object *ob, const ::Material *blender_mat, GPUMaterial *gpumat)
PassMain::Sub * material_add(const Object *ob, const ::Material *blender_mat, GPUMaterial *gpumat)
std::optional< Bounds< float > > object_integration_range() const
VolumeLayer * register_and_get_layer(Object *ob)
void sync(GPUMaterial *gpumat)
#define UTIL_DISK_INTEGRAL_COMP
#define UTIL_BSDF_LAYER
#define UTIL_BTDF_LAYER
#define UTIL_DISK_INTEGRAL_LAYER
#define UTIL_BTDF_LAYER_COUNT
#define UTIL_LTC_MAT_LAYER
#define UTIL_SSS_TRANSMITTANCE_PROFILE_LAYER
#define UTIL_TEX_SIZE
#define UTIL_BLUE_NOISE_LAYER
int count
detail::Pass< command::DrawCommandBuf > PassSimple
detail::Pass< command::DrawMultiBuf > PassMain
const float ltc_mat_ggx[64][64][4]
Definition eevee_lut.cc:13
const float burley_sss_profile[64][1]
const float brdf_ggx[64][64][3]
const float random_walk_sss_profile[64][1]
const float ltc_disk_integral[64][64][1]
const float btdf_ggx[16][64][64][1]
const float bsdf_ggx[16][64][64][3]
const float blue_noise[64][64][4]
static int to_gbuffer_bin_count(const eClosureBits closure_bits)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 3 > float3
PassMain::Sub * gbuffer_double_sided_hybrid_ps_
PassMain::Sub * prepass_double_sided_static_ps_
PassMain::Sub * prepass_single_sided_static_ps_
void gbuffer_pass_sync(Instance &inst)
PassMain::Sub * prepass_double_sided_moving_ps_
eClosureBits closure_bits_get() const
PassMain::Sub * gbuffer_single_sided_hybrid_ps_
PassMain::Sub * prepass_single_sided_moving_ps_
std::optional< Bounds< float2 > > screen_bounds
VolumeObjectBounds(const Camera &camera, Object *ob)
std::optional< Bounds< float > > z_range