Blender V4.5
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_raytrace.hh"
21#include "eevee_subsurface.hh"
22
23struct Camera;
24
25namespace blender::eevee {
26
27class Instance;
28struct RayTraceBuffer;
29
30/* -------------------------------------------------------------------- */
35
37 private:
38 Instance &inst_;
39
40 PassSimple clear_ps_ = {"World.Background.Clear"};
41 PassSimple world_ps_ = {"World.Background"};
42
43 public:
44 BackgroundPipeline(Instance &inst) : inst_(inst){};
45
46 void sync(GPUMaterial *gpumat, float background_opacity, float background_blur);
47 void clear(View &view);
48 void render(View &view, Framebuffer &combined_fb);
49};
50
52
53/* -------------------------------------------------------------------- */
58
60 private:
61 Instance &inst_;
62
63 /* Dummy textures: required to reuse background shader and avoid another shader variation. */
64 Texture dummy_renderpass_tx_;
65 Texture dummy_cryptomatte_tx_;
66 Texture dummy_aov_color_tx_;
67 Texture dummy_aov_value_tx_;
68
69 PassSimple cubemap_face_ps_ = {"World.Probe"};
70
71 public:
72 WorldPipeline(Instance &inst) : inst_(inst){};
73
74 void sync(GPUMaterial *gpumat);
75 void render(View &view);
76
77}; // namespace blender::eevee
78
80
81/* -------------------------------------------------------------------- */
85
87 private:
88 Instance &inst_;
89 bool is_valid_;
90
91 PassSimple world_ps_ = {"World.Volume"};
92
93 public:
94 WorldVolumePipeline(Instance &inst) : inst_(inst){};
95
96 void sync(GPUMaterial *gpumat);
97 void render(View &view);
98};
99
101
102/* -------------------------------------------------------------------- */
106
108 private:
109 Instance &inst_;
110
111 /* Shadow update pass. */
112 PassMain render_ps_ = {"Shadow.Surface"};
113 /* Shadow surface render sub-passes. */
114 PassMain::Sub *surface_double_sided_ps_ = nullptr;
115 PassMain::Sub *surface_single_sided_ps_ = nullptr;
116
117 public:
118 ShadowPipeline(Instance &inst) : inst_(inst){};
119
121
122 void sync();
123
124 void render(View &view);
125};
126
128
129/* -------------------------------------------------------------------- */
134
136 private:
137 Instance &inst_;
138
139 PassMain prepass_ps_ = {"Prepass"};
140 PassMain::Sub *prepass_single_sided_static_ps_ = nullptr;
141 PassMain::Sub *prepass_single_sided_moving_ps_ = nullptr;
142 PassMain::Sub *prepass_double_sided_static_ps_ = nullptr;
143 PassMain::Sub *prepass_double_sided_moving_ps_ = nullptr;
144
145 PassMain opaque_ps_ = {"Shading"};
146 PassMain::Sub *opaque_single_sided_ps_ = nullptr;
147 PassMain::Sub *opaque_double_sided_ps_ = nullptr;
148
149 PassSortable transparent_ps_ = {"Forward.Transparent"};
150 float3 camera_forward_;
151
152 bool has_opaque_ = false;
153 bool has_transparent_ = false;
154
155 public:
156 ForwardPipeline(Instance &inst) : inst_(inst){};
157
158 void sync();
159
160 PassMain::Sub *prepass_opaque_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
162
164 ::Material *blender_mat,
165 GPUMaterial *gpumat);
167 ::Material *blender_mat,
168 GPUMaterial *gpumat);
169
170 void render(View &view, Framebuffer &prepass_fb, Framebuffer &combined_fb, int2 extent);
171};
172
174
175/* -------------------------------------------------------------------- */
178
180 PassMain prepass_ps_ = {"Prepass"};
185
186 PassMain gbuffer_ps_ = {"Shading"};
187 /* Shaders that use the ClosureToRGBA node needs to be rendered first.
188 * Consider they hybrid forward and deferred. */
193
194 /* Closures bits from the materials in this pass. */
196 /* Maximum closure count considering all material in this pass. */
198
199 /* Stencil values used during the deferred pipeline. */
200 enum class StencilBits : uint8_t {
201 /* Bits 0 to 1 are reserved for closure count [0..3]. */
202 CLOSURE_COUNT_0 = (1u << 0u),
203 CLOSURE_COUNT_1 = (1u << 1u),
204 /* Set for pixels have a transmission closure. */
205 TRANSMISSION = (1u << 2u),
208
209 /* Set for materials that uses the shadow amend pass. */
213 };
214
215 /* Return the amount of gbuffer layer needed. */
217 {
218 /* Default header. */
219 int count = 1;
220 /* SSS, light linking, shadow offset all require an additional layer to store the object ID.
221 * Since tracking these are not part of the closure bits and are rather common features,
222 * always require one layer for it. */
223 count += 1;
224 return count;
225 }
226
227 /* Return the amount of gbuffer layer needed. */
229 {
230 /* Diffuse and translucent require only one layer. */
232 /* SSS require an additional layer compared to diffuse. */
234 /* Reflection and refraction can have at most two layers. */
237 return count;
238 }
239
240 /* Return the amount of gbuffer layer needed. */
242 {
243 /* TODO(fclem): We could count the number of different tangent frame in the shader and use
244 * min(tangent_frame_count, closure_count) once we have the normal reuse optimization.
245 * For now, allocate a split normal layer for each Closure. */
249 /* Count the additional information layer needed by some closures. */
252 return count;
253 }
254
256 {
257 return closure_bits_;
258 }
259
260 void gbuffer_pass_sync(Instance &inst);
261};
262
263class DeferredPipeline;
264
266 friend DeferredPipeline;
267
268 private:
269 Instance &inst_;
270
271 static constexpr int max_lighting_tile_count_ = 128 * 128;
272
273 /* Evaluate all light objects contribution. */
274 PassSimple eval_light_ps_ = {"EvalLights"};
275 /* Combine direct and indirect light contributions and apply BSDF color. */
276 PassSimple combine_ps_ = {"Combine"};
277
287 TextureFromPool direct_radiance_txs_[3] = {
288 {"direct_radiance_1"}, {"direct_radiance_2"}, {"direct_radiance_3"}};
289 /* NOTE: Only used when `use_split_radiance` is true. */
290 TextureFromPool indirect_radiance_txs_[3] = {
291 {"indirect_radiance_1"}, {"indirect_radiance_2"}, {"indirect_radiance_3"}};
292 /* Used when there is no indirect radiance buffer. */
293 Texture dummy_black = {"dummy_black"};
294 /* Reference to ray-tracing results. */
295 GPUTexture *radiance_feedback_tx_ = nullptr;
296
301 Texture tile_mask_tx_ = {"tile_mask_tx_"};
302
303 RayTraceResult indirect_result_;
304
305 bool use_split_radiance_ = true;
306 /* Output radiance from the combine shader instead of copy. Allow passing unclamped result. */
307 bool use_feedback_output_ = false;
308 bool use_raytracing_ = false;
309 bool use_screen_transmission_ = false;
310 bool use_screen_reflection_ = false;
311 bool use_clamp_direct_ = false;
312 bool use_clamp_indirect_ = false;
313
314 public:
315 DeferredLayer(Instance &inst) : inst_(inst)
316 {
317 float4 data(0.0f);
318 dummy_black.ensure_2d(RAYTRACE_RADIANCE_FORMAT,
319 int2(1),
321 data);
322 }
323
324 void begin_sync();
325 void end_sync(bool is_first_pass, bool is_last_pass, bool next_layer_has_transmission);
326
327 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
328 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
329
330 bool is_empty() const
331 {
332 return closure_count_ == 0;
333 }
334
335 bool has_transmission() const
336 {
338 }
339
340 /* Do we compute indirect lighting inside the light eval pass. */
341 static bool do_merge_direct_indirect_eval(const Instance &inst);
342 /* Is the radiance split for the lighting pass. */
343 static bool do_split_direct_indirect_radiance(const Instance &inst);
344
345 /* Returns the radiance buffer to feed the next layer. */
346 GPUTexture *render(View &main_view,
347 View &render_view,
348 Framebuffer &prepass_fb,
349 Framebuffer &combined_fb,
350 Framebuffer &gbuffer_fb,
351 int2 extent,
352 RayTraceBuffer &rt_buffer,
353 GPUTexture *radiance_behind_tx);
354};
355
357 friend DeferredLayer;
358
359 private:
360 /* Gbuffer filling passes. We could have an arbitrary number of them but for now we just have
361 * a hardcoded number of them. */
362 DeferredLayer opaque_layer_;
363 DeferredLayer refraction_layer_;
364 DeferredLayer volumetric_layer_;
365
366 PassSimple debug_draw_ps_ = {"debug_gbuffer"};
367
368 bool use_combined_lightprobe_eval;
369
370 public:
372 : opaque_layer_(inst), refraction_layer_(inst), volumetric_layer_(inst){};
373
374 void begin_sync();
375 void end_sync();
376
377 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat, bool has_motion);
378 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
379
380 void render(View &main_view,
381 View &render_view,
382 Framebuffer &prepass_fb,
383 Framebuffer &combined_fb,
384 Framebuffer &gbuffer_fb,
385 int2 extent,
386 RayTraceBuffer &rt_buffer_opaque_layer,
387 RayTraceBuffer &rt_buffer_refract_layer);
388
389 /* Return the maximum amount of gbuffer layer needed. */
391 {
392 return max_ii(opaque_layer_.header_layer_count(), refraction_layer_.header_layer_count());
393 }
394
395 /* Return the maximum amount of gbuffer layer needed. */
397 {
398 return max_ii(opaque_layer_.closure_layer_count(), refraction_layer_.closure_layer_count());
399 }
400
401 /* Return the maximum amount of gbuffer layer needed. */
403 {
404 return max_ii(opaque_layer_.normal_layer_count(), refraction_layer_.normal_layer_count());
405 }
406
407 void debug_draw(draw::View &view, GPUFrameBuffer *combined_fb);
408
409 bool is_empty() const
410 {
411 return opaque_layer_.is_empty() && refraction_layer_.is_empty();
412 }
413
415 {
416 return opaque_layer_.closure_bits_get() | refraction_layer_.closure_bits_get();
417 }
418
419 private:
420 void debug_pass_sync();
421};
422
424
425/* -------------------------------------------------------------------- */
429
431 /* Screen 2D bounds for layer intersection check. */
432 std::optional<Bounds<float2>> screen_bounds;
433 /* Combined bounds in Z. Allow tighter integration bounds. */
434 std::optional<Bounds<float>> z_range;
435
436 VolumeObjectBounds(const Camera &camera, Object *ob);
437};
438
443 public:
444 bool use_hit_list = false;
445 bool is_empty = true;
446 bool finalized = false;
447 bool has_scatter = false;
448 bool has_absorption = false;
449
450 private:
451 Instance &inst_;
452
453 PassMain volume_layer_ps_ = {"Volume.Layer"};
454 /* Sub-passes of volume_layer_ps. */
455 PassMain::Sub *occupancy_ps_;
456 PassMain::Sub *material_ps_;
457 /* List of bounds from all objects contained inside this pass. */
459 /* Combined bounds from object_bounds_. */
460 std::optional<Bounds<float2>> combined_screen_bounds_;
461
462 public:
463 VolumeLayer(Instance &inst) : inst_(inst)
464 {
465 this->sync();
466 }
467
469 const ::Material *blender_mat,
470 GPUMaterial *gpumat);
472 const ::Material *blender_mat,
473 GPUMaterial *gpumat);
474
475 /* Return true if the given bounds overlaps any of the contained object in this layer. */
476 bool bounds_overlaps(const VolumeObjectBounds &object_bounds) const;
477
478 void add_object_bound(const VolumeObjectBounds &object_bounds);
479
480 void sync();
481 void render(View &view, Texture &occupancy_tx);
482};
483
485 private:
486 Instance &inst_;
487
489
490 /* Combined bounds in Z. Allow tighter integration bounds. */
491 std::optional<Bounds<float>> object_integration_range_;
492 /* Aggregated properties of all volume objects. */
493 bool has_scatter_ = false;
494 bool has_absorption_ = false;
495
496 public:
497 VolumePipeline(Instance &inst) : inst_(inst){};
498
499 void sync();
500 void render(View &view, Texture &occupancy_tx);
501
507
508 std::optional<Bounds<float>> object_integration_range() const;
509
510 bool has_scatter() const
511 {
512 for (const auto &layer : layers_) {
513 if (layer->has_scatter) {
514 return true;
515 }
516 }
517 return false;
518 }
519 bool has_absorption() const
520 {
521 for (const auto &layer : layers_) {
522 if (layer->has_absorption) {
523 return true;
524 }
525 }
526 return false;
527 }
528
529 /* Returns true if any volume layer uses the hist list. */
530 bool use_hit_list() const;
531};
532
534
535/* -------------------------------------------------------------------- */
538
540 private:
541 Instance &inst_;
542
543 DeferredLayerBase opaque_layer_;
544
545 PassSimple eval_light_ps_ = {"EvalLights"};
546
547 public:
548 DeferredProbePipeline(Instance &inst) : inst_(inst){};
549
550 void begin_sync();
551 void end_sync();
552
553 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat);
554 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
555
556 void render(View &view,
557 Framebuffer &prepass_fb,
558 Framebuffer &combined_fb,
559 Framebuffer &gbuffer_fb,
560 int2 extent);
561
562 /* Return the maximum amount of gbuffer layer needed. */
564 {
565 return opaque_layer_.header_layer_count();
566 }
567
568 /* Return the maximum amount of gbuffer layer needed. */
570 {
571 return opaque_layer_.closure_layer_count();
572 }
573
574 /* Return the maximum amount of gbuffer layer needed. */
576 {
577 return opaque_layer_.normal_layer_count();
578 }
579};
580
582
583/* -------------------------------------------------------------------- */
586
588 private:
589 Instance &inst_;
590
591 PassSimple eval_light_ps_ = {"EvalLights"};
592
593 public:
594 PlanarProbePipeline(Instance &inst) : inst_(inst){};
595
596 void begin_sync();
597 void end_sync();
598
599 PassMain::Sub *prepass_add(::Material *blender_mat, GPUMaterial *gpumat);
600 PassMain::Sub *material_add(::Material *blender_mat, GPUMaterial *gpumat);
601
602 void render(View &view,
603 GPUTexture *depth_layer_tx,
604 Framebuffer &gbuffer,
605 Framebuffer &combined_fb,
606 int2 extent);
607};
608
610
611/* -------------------------------------------------------------------- */
615
617 private:
618 Instance &inst_;
619
620 PassMain surface_ps_ = {"Capture.Surface"};
621
622 public:
623 CapturePipeline(Instance &inst) : inst_(inst){};
624
626
627 void sync();
628 void render(View &view);
629};
630
632
633/* -------------------------------------------------------------------- */
638
639class UtilityTexture : public Texture {
640 struct Layer {
642 };
643
644 static constexpr int lut_size = UTIL_TEX_SIZE;
645 static constexpr int lut_size_sqr = lut_size * lut_size;
646 static constexpr int layer_count = UTIL_BTDF_LAYER + UTIL_BTDF_LAYER_COUNT;
647
648 public:
650 : Texture("UtilityTx",
653 int2(lut_size),
654 layer_count,
655 nullptr)
656 {
657 Vector<Layer> data(layer_count);
658 {
659 Layer &layer = data[UTIL_BLUE_NOISE_LAYER];
660 memcpy(layer.data, lut::blue_noise, sizeof(layer));
661 }
662 {
664 for (auto y : IndexRange(lut_size)) {
665 for (auto x : IndexRange(lut_size)) {
666 /* Repeatedly stored on every row for correct interpolation. */
667 layer.data[y][x][0] = lut::burley_sss_profile[x][0];
668 layer.data[y][x][1] = lut::random_walk_sss_profile[x][0];
669 layer.data[y][x][2] = 0.0f;
671 }
672 }
674 }
675 {
676 Layer &layer = data[UTIL_LTC_MAT_LAYER];
677 memcpy(layer.data, lut::ltc_mat_ggx, sizeof(layer));
678 }
679 {
680 Layer &layer = data[UTIL_BSDF_LAYER];
681 for (auto x : IndexRange(lut_size)) {
682 for (auto y : IndexRange(lut_size)) {
683 layer.data[y][x][0] = lut::brdf_ggx[y][x][0];
684 layer.data[y][x][1] = lut::brdf_ggx[y][x][1];
685 layer.data[y][x][2] = lut::brdf_ggx[y][x][2];
686 layer.data[y][x][3] = 0.0f;
687 }
688 }
689 }
690 {
691 for (auto layer_id : IndexRange(16)) {
692 Layer &layer = data[UTIL_BTDF_LAYER + layer_id];
693 for (auto x : IndexRange(lut_size)) {
694 for (auto y : IndexRange(lut_size)) {
695 layer.data[y][x][0] = lut::bsdf_ggx[layer_id][y][x][0];
696 layer.data[y][x][1] = lut::bsdf_ggx[layer_id][y][x][1];
697 layer.data[y][x][2] = lut::bsdf_ggx[layer_id][y][x][2];
698 layer.data[y][x][3] = lut::btdf_ggx[layer_id][y][x][0];
699 }
700 }
701 }
702 }
704 }
705
706 ~UtilityTexture() = default;
707};
708
710
711/* -------------------------------------------------------------------- */
716
718 public:
729
732
734 : background(inst),
735 world(inst),
736 world_volume(inst),
737 probe(inst),
738 planar(inst),
739 deferred(inst),
740 forward(inst),
741 shadow(inst),
742 volume(inst),
743 capture(inst),
744 data(data){};
745
747 {
748 data.is_sphere_probe = false;
749 probe.begin_sync();
750 planar.begin_sync();
751 deferred.begin_sync();
752 forward.sync();
753 shadow.sync();
754 volume.sync();
755 capture.sync();
756 }
757
758 void end_sync()
759 {
760 probe.end_sync();
761 planar.end_sync();
762 deferred.end_sync();
763 }
764
765 PassMain::Sub *material_add(Object * /*ob*/ /* TODO remove. */,
766 ::Material *blender_mat,
767 GPUMaterial *gpumat,
768 eMaterialPipeline pipeline_type,
769 eMaterialProbe probe_capture)
770 {
771 if (probe_capture == MAT_PROBE_REFLECTION) {
772 switch (pipeline_type) {
774 return probe.prepass_add(blender_mat, gpumat);
776 return probe.material_add(blender_mat, gpumat);
777 default:
779 break;
780 }
781 }
782 if (probe_capture == MAT_PROBE_PLANAR) {
783 switch (pipeline_type) {
785 return planar.prepass_add(blender_mat, gpumat);
787 return planar.material_add(blender_mat, gpumat);
788 default:
790 break;
791 }
792 }
793
794 switch (pipeline_type) {
796 return deferred.prepass_add(blender_mat, gpumat, false);
798 return forward.prepass_opaque_add(blender_mat, gpumat, false);
800 BLI_assert_msg(0, "Overlap prepass should register to the forward pipeline directly.");
801 return nullptr;
802
804 return deferred.prepass_add(blender_mat, gpumat, true);
806 return forward.prepass_opaque_add(blender_mat, gpumat, true);
807
809 return deferred.material_add(blender_mat, gpumat);
810 case MAT_PIPE_FORWARD:
811 return forward.material_opaque_add(blender_mat, gpumat);
812 case MAT_PIPE_SHADOW:
813 return shadow.surface_material_add(blender_mat, gpumat);
814 case MAT_PIPE_CAPTURE:
815 return capture.surface_material_add(blender_mat, gpumat);
816
819 BLI_assert_msg(0, "Volume shaders must register to the volume pipeline directly.");
820 return nullptr;
821
823 /* Should be handled by the `probe_capture == MAT_PROBE_PLANAR` case. */
825 return nullptr;
826 }
827 return nullptr;
828 }
829};
830
832
833} // 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
@ GPU_DATA_FLOAT
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
void GPU_texture_update_mipmap(GPUTexture *texture, int mip_level, eGPUDataFormat data_format, const void *pixels)
@ GPU_RGBA16F
BMesh const char void * data
Texture(const char *name="gpu::Texture")
detail::PassBase< command::DrawMultiBuf > Sub
Definition draw_pass.hh:490
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, GPUFrameBuffer *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 RAYTRACE_RADIANCE_FORMAT
#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]
@ MAT_PIPE_PREPASS_FORWARD_VELOCITY
@ MAT_PIPE_PREPASS_DEFERRED_VELOCITY
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