Blender V4.3
workbench_mesh_passes.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
6
7namespace blender::workbench {
8
9/* -------------------------------------------------------------------- */
13MeshPass::MeshPass(const char *name) : PassMain(name){};
14
16{
17 /* TODO: Move to #draw::Pass. */
18
19 return is_empty_;
20}
21
22void MeshPass::init_pass(SceneResources &resources, DRWState state, int clip_planes)
23{
24 use_custom_ids = true;
25 is_empty_ = true;
27 state_set(state, clip_planes);
34 if (clip_planes > 0) {
36 }
37}
38
39void MeshPass::init_subpasses(ePipelineType pipeline, eLightingType lighting, bool clip)
40{
41 texture_subpass_map_.clear();
42
43 static std::string pass_names[geometry_type_len][shader_type_len] = {};
44
45 for (auto geom : IndexRange(geometry_type_len)) {
46 for (auto shader : IndexRange(shader_type_len)) {
47 eGeometryType geom_type = static_cast<eGeometryType>(geom);
48 eShaderType shader_type = static_cast<eShaderType>(shader);
49 if (pass_names[geom][shader].empty()) {
50 pass_names[geom][shader] = std::string(get_name(geom_type)) +
51 std::string(get_name(shader_type));
52 }
53 PassMain::Sub *pass = &sub(pass_names[geom][shader].c_str());
54 pass->shader_set(
55 ShaderCache::get().prepass_get(geom_type, pipeline, lighting, shader_type, clip));
56 passes_[geom][shader] = pass;
57 }
58 }
59}
60
62 const MaterialTexture *texture /* = nullptr */)
63{
64 is_empty_ = false;
65
66 if (texture && texture->gpu.texture) {
67 auto add_cb = [&] {
68 PassMain::Sub *sub_pass = passes_[int(geometry_type)][int(eShaderType::TEXTURE)];
69 sub_pass = &sub_pass->sub(texture->name);
70 if (texture->gpu.tile_mapping) {
71 sub_pass->bind_texture(WB_TILE_ARRAY_SLOT, texture->gpu.texture, texture->sampler_state);
72 sub_pass->bind_texture(WB_TILE_DATA_SLOT, texture->gpu.tile_mapping);
73 }
74 else {
75 sub_pass->bind_texture(WB_TEXTURE_SLOT, texture->gpu.texture, texture->sampler_state);
76 }
77 sub_pass->push_constant("isImageTile", texture->gpu.tile_mapping != nullptr);
78 sub_pass->push_constant("imagePremult", texture->premultiplied);
79 /* TODO(@pragma37): This setting should be exposed on the user side,
80 * either as a global parameter (and set it here)
81 * or by reading the Material Clipping Threshold (and set it per material) */
82 float alpha_cutoff = texture->alpha_cutoff ? 0.1f : -FLT_MAX;
83 sub_pass->push_constant("imageTransparencyCutoff", alpha_cutoff);
84 return sub_pass;
85 };
86
87 return *texture_subpass_map_.lookup_or_add_cb(
88 TextureSubPassKey(texture->gpu.texture, geometry_type), add_cb);
89 }
90
91 return *passes_[int(geometry_type)][int(eShaderType::MATERIAL)];
92}
93
96/* -------------------------------------------------------------------- */
100void OpaquePass::sync(const SceneState &scene_state, SceneResources &resources)
101{
104
105 bool clip = scene_state.clip_planes.size() > 0;
106
107 DRWState in_front_state = state | DRW_STATE_STENCIL_ALWAYS;
108 gbuffer_in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size());
111
113 gbuffer_ps_.init_pass(resources, state, scene_state.clip_planes.size());
117
120 deferred_ps_.shader_set(ShaderCache::get().resolve_get(scene_state.lighting_type,
121 scene_state.draw_cavity,
122 scene_state.draw_curvature,
123 scene_state.draw_shadows));
124 deferred_ps_.push_constant("forceShadowing", false);
129 deferred_ps_.bind_texture("depth_tx", &resources.depth_tx);
131 resources.cavity.setup_resolve_pass(deferred_ps_, resources);
133}
134
136 View &view,
137 SceneResources &resources,
138 int2 resolution,
139 ShadowPass *shadow_pass)
140{
141 if (is_empty()) {
142 return;
143 }
148
149 GPUAttachment object_id_attachment = GPU_ATTACHMENT_NONE;
150 if (resources.object_id_tx.is_valid()) {
151 object_id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx);
152 }
153
158 object_id_attachment);
160
161 manager.submit(gbuffer_in_front_ps_, view);
162
163 if (resources.depth_in_front_tx.is_valid()) {
164 GPU_texture_copy(resources.depth_in_front_tx, resources.depth_tx);
165 }
166 }
167
168 if (!gbuffer_ps_.is_empty()) {
172 object_id_attachment);
174
175 manager.submit(gbuffer_ps_, view);
176 }
177
178 if (shadow_pass) {
180 resolution,
184
187 clear_fb.bind();
189
190 shadow_pass->draw(
191 manager, view, resources, **&shadow_depth_stencil_tx, !gbuffer_in_front_ps_.is_empty());
193 }
194 else {
196 deferred_ps_stencil_tx = nullptr;
197 }
198
199 if (!shadow_pass || !shadow_pass->is_debug()) {
203 manager.submit(deferred_ps_, view);
204 }
205
208}
209
214
217/* -------------------------------------------------------------------- */
247
285
290
293/* -------------------------------------------------------------------- */
324
325void TransparentDepthPass::draw(Manager &manager, View &view, SceneResources &resources)
326{
327 if (is_empty()) {
328 return;
329 }
330
331 GPUAttachment object_id_attachment = GPU_ATTACHMENT_NONE;
332 if (resources.object_id_tx.is_valid()) {
333 object_id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx);
334 }
335
336 if (!in_front_ps_.is_empty()) {
340 object_id_attachment);
342 manager.submit(in_front_ps_, view);
343
345 merge_fb.bind();
346 manager.submit(merge_ps_, view);
347 }
348
349 if (!main_ps_.is_empty()) {
353 object_id_attachment);
354 main_fb.bind();
355 manager.submit(main_ps_, view);
356 }
357}
358
360{
362}
363
366} // namespace blender::workbench
#define GPU_ATTACHMENT_TEXTURE(_texture)
void GPU_framebuffer_clear_stencil(GPUFrameBuffer *fb, uint clear_stencil)
#define GPU_ATTACHMENT_NONE
@ GPU_PRIM_TRIS
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_FORMAT_VIEW
@ GPU_DEPTH24_STENCIL8
void ensure(GPUAttachment depth=GPU_ATTACHMENT_NONE, GPUAttachment color1=GPU_ATTACHMENT_NONE, GPUAttachment color2=GPU_ATTACHMENT_NONE, GPUAttachment color3=GPU_ATTACHMENT_NONE, GPUAttachment color4=GPU_ATTACHMENT_NONE, GPUAttachment color5=GPU_ATTACHMENT_NONE, GPUAttachment color6=GPU_ATTACHMENT_NONE, GPUAttachment color7=GPU_ATTACHMENT_NONE, GPUAttachment color8=GPU_ATTACHMENT_NONE)
void submit(PassSimple &pass, View &view)
void acquire(int2 extent, eGPUTextureFormat format, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL)
bool ensure_2d(eGPUTextureFormat format, int2 extent, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
void bind_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
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
PassBase< command::DrawMultiBuf > & sub(const char *name)
Definition draw_pass.hh:616
void state_set(DRWState state, int clip_plane_count=0)
Definition draw_pass.hh:954
void bind_ubo(const char *name, GPUUniformBuf *buffer)
void state_stencil(uint8_t write_mask, uint8_t reference, uint8_t compare_mask)
Definition draw_pass.hh:966
void push_constant(const char *name, const float &data)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
Definition draw_pass.hh:971
void setup_resolve_pass(PassSimple &pass, SceneResources &resources)
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, View &view, SceneResources &resources, int2 resolution, class ShadowPass *shadow_pass)
void draw(Manager &manager, View &view, SceneResources &resources, GPUTexture &depth_stencil_tx, bool force_fail_method)
GPUTexture * extract(Manager &manager, Texture &stencil_src)
void draw(Manager &manager, View &view, SceneResources &resources)
void sync(const SceneState &scene_state, SceneResources &resources)
void sync(const SceneState &scene_state, SceneResources &resources)
void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution)
#define DRW_CLIPPING_UBO_SLOT
DRWState
Definition draw_state.hh:25
@ DRW_STATE_STENCIL_EQUAL
Definition draw_state.hh:47
@ DRW_STATE_BLEND_ALPHA
Definition draw_state.hh:55
@ DRW_STATE_STENCIL_ALWAYS
Definition draw_state.hh:46
@ DRW_STATE_DEPTH_LESS
Definition draw_state.hh:37
@ DRW_STATE_WRITE_DEPTH
Definition draw_state.hh:29
@ DRW_STATE_BLEND_OIT
Definition draw_state.hh:59
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition draw_state.hh:38
@ DRW_STATE_STENCIL_NEQUAL
Definition draw_state.hh:48
@ DRW_STATE_WRITE_STENCIL
Definition draw_state.hh:32
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
static ulong state[N]
static constexpr int geometry_type_len
static constexpr int shader_type_len
static const char * get_name(eGeometryType type)
VecBase< float, 4 > float4
#define FLT_MAX
Definition stdcycles.h:14
unsigned char uint8_t
Definition stdint.h:78
UniformBuffer< WorldData > world_buf
StorageVectorBuffer< Material > material_buf
UniformArrayBuffer< float4, 6 > clip_planes_buf
#define WB_TEXTURE_SLOT
#define WB_MATCAP_SLOT
#define WB_TILE_DATA_SLOT
#define WB_MATERIAL_SLOT
#define WB_WORLD_SLOT
#define WB_TILE_ARRAY_SLOT