Blender V4.3
workbench_private.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "DNA_camera_types.h"
6#include "DRW_render.hh"
7#include "draw_manager.hh"
8#include "draw_pass.hh"
9
10#include "workbench_defines.hh"
11#include "workbench_enums.hh"
13
14#include "GPU_capabilities.hh"
15
17
18namespace blender::workbench {
19
20using namespace draw;
21
23 private:
24 std::string info_name_;
25 GPUShader *shader_ = nullptr;
26
27 public:
28 StaticShader(std::string info_name) : info_name_(info_name) {}
29
30 StaticShader() = default;
31 StaticShader(StaticShader &&other) = default;
32 StaticShader &operator=(StaticShader &&other) = default;
33
35 {
36 DRW_SHADER_FREE_SAFE(shader_);
37 }
38
40 {
41 if (!shader_) {
42 BLI_assert(!info_name_.empty());
43 shader_ = GPU_shader_create_from_info_name(info_name_.c_str());
44 }
45 return shader_;
46 }
47};
48
50 private:
51 static ShaderCache *static_cache;
52
54 [2 /*clip*/];
55 StaticShader resolve_[lighting_type_len][2 /*cavity*/][2 /*curvature*/][2 /*shadow*/];
56
57 StaticShader shadow_[2 /*depth_pass*/][2 /*manifold*/][2 /*cap*/];
58
59 StaticShader volume_[2 /*smoke*/][3 /*interpolation*/][2 /*coba*/][2 /*slice*/];
60
61 public:
62 static ShaderCache &get();
63 static void release();
64
66
68 ePipelineType pipeline_type,
69 eLightingType lighting_type,
70 eShaderType shader_type,
71 bool clip)
72 {
73 return prepass_[int(geometry_type)][int(pipeline_type)][int(lighting_type)][int(shader_type)]
74 [clip]
75 .get();
76 }
77
79 bool cavity = false,
80 bool curvature = false,
81 bool shadow = false)
82 {
83 return resolve_[int(lighting_type)][cavity][curvature][shadow].get();
84 }
85
86 GPUShader *shadow_get(bool depth_pass, bool manifold, bool cap = false)
87 {
88 return shadow_[depth_pass][manifold][cap].get();
89 }
90
91 GPUShader *volume_get(bool smoke, int interpolation, bool coba, bool slice)
92 {
93 return volume_[smoke][interpolation][coba][slice].get();
94 }
95
96 StaticShader extract_stencil = {"workbench_extract_stencil"};
97
98 /* Transparency */
99 StaticShader transparent_resolve = {"workbench_transparent_resolve"};
100 StaticShader merge_depth = {"workbench_merge_depth"};
101
102 /* ShadowView */
104 "workbench_shadow_visibility_compute_dynamic_pass_type"};
105 StaticShader shadow_visibility_static = {"workbench_shadow_visibility_compute_static_pass_type"};
106
107 /* Outline */
108 StaticShader outline = {"workbench_effect_outline"};
109
110 /* Dof */
111 StaticShader dof_prepare = {"workbench_effect_dof_prepare"};
112 StaticShader dof_downsample = {"workbench_effect_dof_downsample"};
113 StaticShader dof_blur1 = {"workbench_effect_dof_blur1"};
114 StaticShader dof_blur2 = {"workbench_effect_dof_blur2"};
115 StaticShader dof_resolve = {"workbench_effect_dof_resolve"};
116
117 /* AA */
118 StaticShader taa_accumulation = {"workbench_taa"};
119 StaticShader smaa_edge_detect = {"workbench_smaa_stage_0"};
120 StaticShader smaa_aa_weight = {"workbench_smaa_stage_1"};
121 StaticShader smaa_resolve = {"workbench_smaa_stage_2"};
122 StaticShader overlay_depth = {"workbench_overlay_depth"};
123};
124
125struct Material {
127 /* Packed data into a int. Decoded in the shader. */
129
132 Material(::Object &ob, bool random = false);
133 Material(::Material &mat);
134
135 static uint32_t pack_data(float metallic, float roughness, float alpha);
136
137 bool is_transparent();
138};
139
141
143 Scene *scene = nullptr;
144
146 Camera *camera = nullptr;
149
151
154 bool xray_mode = false;
155
158
160
161 bool draw_cavity = false;
162 bool draw_curvature = false;
163 bool draw_shadows = false;
164 bool draw_outline = false;
165 bool draw_dof = false;
166 bool draw_aa = false;
167
168 bool draw_object_id = false;
169
170 int sample = 0;
171 int samples_len = 0;
173 bool render_finished = false;
174
175 /* Used when material_type == eMaterialType::SINGLE */
177 /* When r == -1.0 the shader uses the vertex color */
179
180 void init(Object *camera_ob = nullptr);
181};
182
184 const char *name = nullptr;
187 bool premultiplied = false;
188 bool alpha_cutoff = false;
189
190 MaterialTexture() = default;
191 MaterialTexture(Object *ob, int material_index);
192 MaterialTexture(::Image *image, ImageUser *user = nullptr);
193};
194
195struct SceneResources;
196
207
209 private:
210 /* This value must be kept in sync with the one declared at
211 * workbench_composite_info.hh (cavity_samples) */
212 static const int max_samples_ = 512;
213
215
216 int sample_ = 0;
217 int sample_count_ = 0;
218 bool curvature_enabled_ = false;
219 bool cavity_enabled_ = false;
220
221 public:
222 void init(const SceneState &scene_state, SceneResources &resources);
223 void setup_resolve_pass(PassSimple &pass, SceneResources &resources);
224
225 private:
226 void load_samples_buf(int ssao_samples);
227};
228
229/* Used as a temporary workaround for the lack of texture views support on Windows ARM. */
231 private:
232 Texture stencil_copy_tx_ = "stencil_copy_tx";
233
234 public:
241 GPUTexture *extract(Manager &manager, Texture &stencil_src)
242 {
244 return stencil_src.stencil_view();
245 }
246
247 int2 extent = int2(stencil_src.width(), stencil_src.height());
248 stencil_copy_tx_.ensure_2d(
250
251 PassSimple ps("Stencil View Workaround");
252 ps.init();
253 ps.clear_color(float4(0));
255 ps.state_stencil(0x00, 0x00, 0xFF);
256 ps.shader_set(ShaderCache::get().extract_stencil.get());
258
260 fb.ensure(GPU_ATTACHMENT_TEXTURE(stencil_src), GPU_ATTACHMENT_TEXTURE(stencil_copy_tx_));
261 fb.bind();
262
263 manager.submit(ps);
264
265 return stencil_copy_tx_;
266 }
267};
268
305
306class MeshPass : public PassMain {
307 private:
308 using TextureSubPassKey = std::pair<GPUTexture *, eGeometryType>;
309
310 Map<TextureSubPassKey, PassMain::Sub *> texture_subpass_map_;
311
312 PassMain::Sub *passes_[geometry_type_len][shader_type_len] = {{nullptr}};
313
314 bool is_empty_ = false;
315
316 public:
317 MeshPass(const char *name);
318
319 /* TODO: Move to draw::Pass */
320 bool is_empty() const;
321
322 void init_pass(SceneResources &resources, DRWState state, int clip_planes);
323 void init_subpasses(ePipelineType pipeline, eLightingType lighting, bool clip);
324
326 const MaterialTexture *texture = nullptr);
327};
328
329enum class StencilBits : uint8_t {
331 OBJECT = 1u << 0,
333};
334
336 public:
337 TextureFromPool gbuffer_normal_tx = {"gbuffer_normal_tx"};
338 TextureFromPool gbuffer_material_tx = {"gbuffer_material_tx"};
339
340 Texture shadow_depth_stencil_tx = {"shadow_depth_stencil_tx"};
341 GPUTexture *deferred_ps_stencil_tx = nullptr;
342
343 MeshPass gbuffer_ps_ = {"Opaque.Gbuffer"};
344 MeshPass gbuffer_in_front_ps_ = {"Opaque.GbufferInFront"};
345 PassSimple deferred_ps_ = {"Opaque.Deferred"};
346
347 Framebuffer gbuffer_fb = {"Opaque.Gbuffer"};
348 Framebuffer gbuffer_in_front_fb = {"Opaque.GbufferInFront"};
349 Framebuffer deferred_fb = {"Opaque.Deferred"};
350 Framebuffer clear_fb = {"Opaque.Clear"};
351
352 void sync(const SceneState &scene_state, SceneResources &resources);
353 void draw(Manager &manager,
354 View &view,
355 SceneResources &resources,
356 int2 resolution,
357 class ShadowPass *shadow_pass);
358 bool is_empty() const;
359};
360
362 public:
363 TextureFromPool accumulation_tx = {"accumulation_accumulation_tx"};
364 TextureFromPool reveal_tx = {"accumulation_reveal_tx"};
366
367 MeshPass accumulation_ps_ = {"Transparent.Accumulation"};
368 MeshPass accumulation_in_front_ps_ = {"Transparent.AccumulationInFront"};
369 PassSimple resolve_ps_ = {"Transparent.Resolve"};
371
372 void sync(const SceneState &scene_state, SceneResources &resources);
373 void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
374 bool is_empty() const;
375};
376
378 public:
379 MeshPass main_ps_ = {"TransparentDepth.Main"};
380 Framebuffer main_fb = {"TransparentDepth.Main"};
381 MeshPass in_front_ps_ = {"TransparentDepth.InFront"};
382 Framebuffer in_front_fb = {"TransparentDepth.InFront"};
383 PassSimple merge_ps_ = {"TransparentDepth.Merge"};
384 Framebuffer merge_fb = {"TransparentDepth.Merge"};
385
386 void sync(const SceneState &scene_state, SceneResources &resources);
387 void draw(Manager &manager, View &view, SceneResources &resources);
388 bool is_empty() const;
389};
390
391#define DEBUG_SHADOW_VOLUME 0
392
394 private:
395 enum PassType { PASS = 0, FAIL, FORCED_FAIL, MAX };
396
397 class ShadowView : public View {
398 bool force_fail_method_ = false;
399 float3 light_direction_ = float3(0);
400 UniformBuffer<ExtrudedFrustum> extruded_frustum_ = {};
401 ShadowPass::PassType current_pass_type_ = PASS;
402
403 VisibilityBuf pass_visibility_buf_ = {};
404 VisibilityBuf fail_visibility_buf_ = {};
405
406 public:
407 ShadowView() : View("ShadowPass.View"){};
408
409 void setup(View &view, float3 light_direction, bool force_fail_method);
410 bool debug_object_culling(Object *ob);
411 void set_mode(PassType type);
412
413 protected:
414 virtual void compute_visibility(ObjectBoundsBuf &bounds,
415 ObjectInfosBuf &infos,
416 uint resource_len,
417 bool debug_freeze) override;
418 virtual VisibilityBuf &get_visibility_buffer() override;
419 } view_ = {};
420
421 bool enabled_;
422
423 UniformBuffer<ShadowPassData> pass_data_ = {};
424
425 /* Draws are added to both passes and the visibly compute shader selects one of them */
426 PassMain pass_ps_ = {"Shadow.Pass"};
427 PassMain fail_ps_ = {"Shadow.Fail"};
428
429 /* In some cases, we know beforehand that we need to use the fail technique */
430 PassMain forced_fail_ps_ = {"Shadow.ForcedFail"};
431
432 /* [PassType][Is Manifold][Is Cap] */
433 PassMain::Sub *passes_[PassType::MAX][2][2] = {{{nullptr}}};
434 PassMain::Sub *&get_pass_ptr(PassType type, bool manifold, bool cap = false);
435
436 TextureFromPool depth_tx_ = {};
437 Framebuffer fb_ = {};
438
439 public:
440 void init(const SceneState &scene_state, SceneResources &resources);
441 void update();
442 void sync();
443 void object_sync(SceneState &scene_state,
444 ObjectRef &ob_ref,
445 ResourceHandle handle,
446 const bool has_transp_mat);
447 void draw(Manager &manager,
448 View &view,
449 SceneResources &resources,
450 GPUTexture &depth_stencil_tx,
451 /* Needed when there are opaque "In Front" objects in the scene */
452 bool force_fail_method);
453
454 bool is_debug();
455};
456
458 bool active_ = true;
459
460 PassMain ps_ = {"Volume"};
461 Framebuffer fb_ = {"Volume"};
462
463 Texture dummy_shadow_tx_ = {"Volume.Dummy Shadow Tx"};
464 Texture dummy_volume_tx_ = {"Volume.Dummy Volume Tx"};
465 Texture dummy_coba_tx_ = {"Volume.Dummy Coba Tx"};
466
467 GPUTexture *stencil_tx_ = nullptr;
468
469 public:
470 void sync(SceneResources &resources);
471
472 void object_sync_volume(Manager &manager,
473 SceneResources &resources,
474 const SceneState &scene_state,
475 ObjectRef &ob_ref,
476 float3 color);
477
478 void object_sync_modifier(Manager &manager,
479 SceneResources &resources,
480 const SceneState &scene_state,
481 ObjectRef &ob_ref,
482 ModifierData *md);
483
484 void draw(Manager &manager, View &view, SceneResources &resources);
485
486 private:
487 void draw_slice_ps(Manager &manager,
488 PassMain::Sub &ps,
489 ObjectRef &ob_ref,
490 int slice_axis_enum,
491 float slice_depth);
492
493 void draw_volume_ps(Manager &manager,
494 PassMain::Sub &ps,
495 ObjectRef &ob_ref,
496 int taa_sample,
497 float3 slice_count,
498 float3 world_size);
499};
500
502 private:
503 bool enabled_ = false;
504
505 PassSimple ps_ = PassSimple("Workbench.Outline");
506 Framebuffer fb_ = Framebuffer("Workbench.Outline");
507
508 public:
509 void init(const SceneState &scene_state);
510 void sync(SceneResources &resources);
511 void draw(Manager &manager, SceneResources &resources);
512};
513
514class DofPass {
515 private:
516 static const int kernel_radius_ = 3;
517 static const int samples_len_ = (kernel_radius_ * 2 + 1) * (kernel_radius_ * 2 + 1);
518
519 bool enabled_ = false;
520
521 float offset_ = 0;
522
524
525 Texture source_tx_ = {};
526 Texture coc_halfres_tx_ = {};
527 TextureFromPool blur_tx_ = {};
528
529 Framebuffer downsample_fb_ = {};
530 Framebuffer blur1_fb_ = {};
531 Framebuffer blur2_fb_ = {};
532 Framebuffer resolve_fb_ = {};
533
534 PassSimple down_ps_ = {"Workbench.DoF.DownSample"};
535 PassSimple down2_ps_ = {"Workbench.DoF.DownSample2"};
536 PassSimple blur_ps_ = {"Workbench.DoF.Blur"};
537 PassSimple blur2_ps_ = {"Workbench.DoF.Blur2"};
538 PassSimple resolve_ps_ = {"Workbench.DoF.Resolve"};
539
540 float aperture_size_ = 0;
541 float distance_ = 0;
542 float invsensor_size_ = 0;
543 float near_ = 0;
544 float far_ = 0;
545 float blades_ = 0;
546 float rotation_ = 0;
547 float ratio_ = 0;
548
549 public:
550 void init(const SceneState &scene_state);
551 void sync(SceneResources &resources);
552 void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution);
553 bool is_enabled();
554
555 private:
556 void setup_samples();
557};
558
560 private:
561 bool enabled_ = false;
562 /* Weight accumulated. */
563 float weight_accum_ = 0;
564 /* Samples weight for this iteration. */
565 float weights_[9] = {0};
566 /* Sum of weights. */
567 float weights_sum_ = 0;
568
569 Texture sample0_depth_tx_ = {"sample0_depth_tx"};
570 Texture sample0_depth_in_front_tx_ = {"sample0_depth_in_front_tx"};
571
572 Texture taa_accumulation_tx_ = {"taa_accumulation_tx"};
573 Texture smaa_search_tx_ = {"smaa_search_tx"};
574 Texture smaa_area_tx_ = {"smaa_area_tx"};
575 TextureFromPool smaa_edge_tx_ = {"smaa_edge_tx"};
576 TextureFromPool smaa_weight_tx_ = {"smaa_weight_tx"};
577
578 Framebuffer taa_accumulation_fb_ = {"taa_accumulation_fb"};
579 Framebuffer smaa_edge_fb_ = {"smaa_edge_fb"};
580 Framebuffer smaa_weight_fb_ = {"smaa_weight_fb"};
581 Framebuffer smaa_resolve_fb_ = {"smaa_resolve_fb"};
582 Framebuffer overlay_depth_fb_ = {"overlay_depth_fb"};
583
584 float4 smaa_viewport_metrics_ = float4(0);
585 float smaa_mix_factor_ = 0;
586
587 PassSimple taa_accumulation_ps_ = {"TAA.Accumulation"};
588 PassSimple smaa_edge_detect_ps_ = {"SMAA.EdgeDetect"};
589 PassSimple smaa_aa_weight_ps_ = {"SMAA.BlendWeights"};
590 PassSimple smaa_resolve_ps_ = {"SMAA.Resolve"};
591 PassSimple overlay_depth_ps_ = {"Overlay Depth"};
592
593 public:
595
596 void init(const SceneState &scene_state);
597 void sync(const SceneState &scene_state, SceneResources &resources);
598 void setup_view(View &view, const SceneState &scene_state);
599 void draw(
600 Manager &manager,
601 View &view,
602 const SceneState &scene_state,
603 SceneResources &resources,
606 GPUTexture *depth_in_front_tx);
607};
608
609} // namespace blender::workbench
eContextObjectMode
@ CTX_MODE_OBJECT
#define BLI_assert(a)
Definition BLI_assert.h:50
unsigned int uint
struct Material Material
eV3DShadingColorType
@ V3D_SHADING_SINGLE_COLOR
#define DRW_SHADER_FREE_SAFE(shader)
static AppView * view
bool GPU_texture_view_support()
#define GPU_ATTACHMENT_TEXTURE(_texture)
@ GPU_PRIM_TRIS
GPUShader * GPU_shader_create_from_info_name(const char *info_name)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_R8UI
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a producing a negative Combine Generate a color from its and blue Hue Saturation Apply a color transformation in the HSV color model Specular Similar to the Principled BSDF node but uses the specular workflow instead of metallic
struct GPUShader GPUShader
void init()
NonCopyable(const NonCopyable &other)=delete
void submit(PassSimple &pass, View &view)
GPUTexture * stencil_view(bool cube_as_array=false)
View(const char *name, int view_len=1, bool procedural=false)
Definition draw_view.hh:59
virtual VisibilityBuf & get_visibility_buffer()
Definition draw_view.cc:304
void clear_color(float4 color)
Definition draw_pass.hh:911
void draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
Definition draw_pass.hh:833
void state_set(DRWState state, int clip_plane_count=0)
Definition draw_pass.hh:954
void state_stencil(uint8_t write_mask, uint8_t reference, uint8_t compare_mask)
Definition draw_pass.hh:966
void shader_set(GPUShader *shader)
Definition draw_pass.hh:971
detail::PassBase< command::DrawMultiBuf > Sub
Definition draw_pass.hh:462
void setup_view(View &view, const SceneState &scene_state)
void draw(Manager &manager, View &view, const SceneState &scene_state, SceneResources &resources, GPUTexture *depth_in_front_tx)
void sync(const SceneState &scene_state, SceneResources &resources)
void setup_resolve_pass(PassSimple &pass, SceneResources &resources)
void sync(SceneResources &resources)
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution)
PassMain::Sub & get_subpass(eGeometryType geometry_type, const MaterialTexture *texture=nullptr)
void init_pass(SceneResources &resources, DRWState state, int clip_planes)
void init_subpasses(ePipelineType pipeline, eLightingType lighting, bool clip)
void sync(const SceneState &scene_state, SceneResources &resources)
void draw(Manager &manager, SceneResources &resources)
void sync(SceneResources &resources)
GPUShader * volume_get(bool smoke, int interpolation, bool coba, bool slice)
GPUShader * resolve_get(eLightingType lighting_type, bool cavity=false, bool curvature=false, bool shadow=false)
GPUShader * shadow_get(bool depth_pass, bool manifold, bool cap=false)
GPUShader * prepass_get(eGeometryType geometry_type, ePipelineType pipeline_type, eLightingType lighting_type, eShaderType shader_type, bool clip)
void draw(Manager &manager, View &view, SceneResources &resources, GPUTexture &depth_stencil_tx, bool force_fail_method)
void object_sync(SceneState &scene_state, ObjectRef &ob_ref, ResourceHandle handle, const bool has_transp_mat)
StaticShader(StaticShader &&other)=default
StaticShader(std::string info_name)
StaticShader & operator=(StaticShader &&other)=default
GPUTexture * extract(Manager &manager, Texture &stencil_src)
void sync(const SceneState &scene_state, SceneResources &resources)
void sync(const SceneState &scene_state, SceneResources &resources)
void sync(SceneResources &resources)
void object_sync_volume(Manager &manager, SceneResources &resources, const SceneState &scene_state, ObjectRef &ob_ref, float3 color)
void draw(Manager &manager, View &view, SceneResources &resources)
void object_sync_modifier(Manager &manager, SceneResources &resources, const SceneState &scene_state, ObjectRef &ob_ref, ModifierData *md)
input_tx image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "preview_img") .compute_source("compositor_compute_preview.glsl") .do_static_compilation(true)
local_group_size(16, 16) .push_constant(Type texture
DRWState
Definition draw_state.hh:25
@ DRW_STATE_NO_DRAW
Definition draw_state.hh:27
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_STENCIL_NEQUAL
Definition draw_state.hh:48
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
IMETHOD void random(Vector &a)
addDelta operator for displacement rotational velocity.
Definition frames.inl:1282
BLI_INLINE float fb(float length, float L)
static ulong state[N]
detail::Pass< command::DrawCommandBuf > PassSimple
detail::Pass< command::DrawMultiBuf > PassMain
StorageArrayBuffer< ObjectBounds, 128 > ObjectBoundsBuf
Definition draw_view.hh:30
StorageArrayBuffer< ObjectInfos, 128 > ObjectInfosBuf
Definition draw_view.hh:31
StorageArrayBuffer< uint, 4, true > VisibilityBuf
Definition draw_view.hh:32
ImageGPUTextures get_material_texture(GPUSamplerState &sampler_state)
static constexpr int geometry_type_len
static constexpr int lighting_type_len
static constexpr int shader_type_len
static constexpr int pipeline_type_len
MatBase< float, 4, 4 > float4x4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< float, 3 > float3
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
static constexpr GPUSamplerState default_sampler()
static uint32_t pack_data(float metallic, float roughness, float alpha)
ObjectState(const SceneState &scene_state, const SceneResources &resources, Object *ob)
UniformBuffer< WorldData > world_buf
StorageVectorBuffer< Material > material_buf
UniformArrayBuffer< float4, 6 > clip_planes_buf
DrawEngineType draw_engine_workbench