Blender  V2.93
workbench_transparent.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2020, Blender Foundation.
17  */
18 
34 #include "DRW_render.h"
35 
36 #include "ED_view3d.h"
37 
38 #include "workbench_engine.h"
39 #include "workbench_private.h"
40 
42 {
43  WORKBENCH_FramebufferList *fbl = data->fbl;
44  WORKBENCH_PrivateData *wpd = data->stl->wpd;
47 
48  /* Reuse same format as opaque pipeline to reuse the textures. */
49  /* Note: Floating point texture is required for the reveal_tex as it is used for
50  * the alpha accumulation component (see accumulation shader for more explanation). */
51  const eGPUTextureFormat accum_tex_format = GPU_RGBA16F;
52  const eGPUTextureFormat reveal_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16F : GPU_RGBA32F;
53 
54  wpd->accum_buffer_tx = DRW_texture_pool_query_fullscreen(accum_tex_format, owner);
55  wpd->reveal_buffer_tx = DRW_texture_pool_query_fullscreen(reveal_tex_format, owner);
56 
57  GPU_framebuffer_ensure_config(&fbl->transp_accum_fb,
58  {
59  GPU_ATTACHMENT_TEXTURE(dtxl->depth),
60  GPU_ATTACHMENT_TEXTURE(wpd->accum_buffer_tx),
61  GPU_ATTACHMENT_TEXTURE(wpd->reveal_buffer_tx),
62  });
63 }
64 
66  DRWShadingGroup *grp)
67 {
68  DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
69  DRW_shgroup_uniform_bool_copy(grp, "forceShadowing", false);
70 
75  struct GPUTexture *diff_tx = wpd->studio_light->matcap_diffuse.gputexture;
76  struct GPUTexture *spec_tx = wpd->studio_light->matcap_specular.gputexture;
77  const bool use_spec = workbench_is_specular_highlight_enabled(wpd);
78  spec_tx = (use_spec && spec_tx) ? spec_tx : diff_tx;
79  DRW_shgroup_uniform_texture(grp, "matcapDiffuseImage", diff_tx);
80  DRW_shgroup_uniform_texture(grp, "matcapSpecularImage", spec_tx);
81  }
82 }
83 
85 {
86  WORKBENCH_PassList *psl = vedata->psl;
87  WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
88  struct GPUShader *sh;
89  DRWShadingGroup *grp;
90 
91  {
92  int transp = 1;
93  for (int infront = 0; infront < 2; infront++) {
95  wpd->cull_state | wpd->clip_state;
96 
97  DRWPass *pass;
98  if (infront) {
99  psl->transp_accum_infront_ps = pass = DRW_pass_create("transp_accum_infront", state);
102  }
103  else {
104  psl->transp_accum_ps = pass = DRW_pass_create("transp_accum", state);
106  }
107 
109  wpd->prepass[transp][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
110 
112 
113  wpd->prepass[transp][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
114  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
115  DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
117 
118  wpd->prepass[transp][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
119  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
120  DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
121 
123 
124  wpd->prepass[transp][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
125  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
126  DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
128 
130 
131  wpd->prepass[transp][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
132  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
133  DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
135  }
136  }
137  }
138  {
140 
142 
144 
145  grp = DRW_shgroup_create(sh, psl->transp_resolve_ps);
146  DRW_shgroup_uniform_texture(grp, "transparentAccum", wpd->accum_buffer_tx);
147  DRW_shgroup_uniform_texture(grp, "transparentRevealage", wpd->reveal_buffer_tx);
149  }
150 }
151 
152 /* Redraw the transparent passes but with depth test
153  * to output correct outline IDs and depth. */
155 {
156  WORKBENCH_PrivateData *wpd = data->stl->wpd;
157  WORKBENCH_FramebufferList *fbl = data->fbl;
158  WORKBENCH_PassList *psl = data->psl;
159 
160  const bool do_xray_depth_pass = !XRAY_FLAG_ENABLED(wpd) || XRAY_ALPHA(wpd) > 0.0f;
161  const bool do_transparent_depth_pass = psl->outline_ps || wpd->dof_enabled || do_xray_depth_pass;
162 
163  if (do_transparent_depth_pass) {
164 
165  if (!DRW_pass_is_empty(psl->transp_depth_ps)) {
167  /* TODO(fclem): Disable writing to first two buffers. Unnecessary waste of bandwidth. */
169  }
170 
173  /* TODO(fclem): Disable writing to first two buffers. Unnecessary waste of bandwidth. */
175  }
176  }
177 }
@ STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE
@ STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
Definition: studiolight.c:1539
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
#define DRW_PASS_INSTANCE_CREATE(pass, original, state)
Definition: DRW_render.h:594
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_BLEND_ALPHA
Definition: DRW_render.h:340
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_BLEND_OIT
Definition: DRW_render.h:344
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:323
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define XRAY_FLAG_ENABLED(v3d)
Definition: ED_view3d.h:709
#define XRAY_ALPHA(v3d)
Definition: ED_view3d.h:705
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
struct GPUShader GPUShader
Definition: GPU_shader.h:33
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_RG16F
Definition: GPU_texture.h:104
@ GPU_RGBA32F
Definition: GPU_texture.h:91
@ GPU_RGBA16F
Definition: GPU_texture.h:94
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:702
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob, uint tri_count)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
bool DRW_pass_is_empty(DRWPass *pass)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
DRWPass * DRW_pass_create(const char *name, DRWState state)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_draw_pass(DRWPass *pass)
GPUTexture * DRW_texture_pool_query_fullscreen(eGPUTextureFormat format, DrawEngineType *engine_type)
static ulong state[N]
struct GPUTexture * gputexture
StudioLightImage matcap_specular
StudioLightImage matcap_diffuse
WORKBENCH_PassList * psl
WORKBENCH_StorageList * stl
struct GPUFrameBuffer * opaque_fb
struct GPUFrameBuffer * transp_accum_fb
struct GPUFrameBuffer * opaque_infront_fb
struct DRWPass * transp_depth_infront_ps
struct DRWPass * transp_accum_ps
struct DRWPass * outline_ps
struct DRWPass * transp_depth_ps
struct DRWPass * transp_resolve_ps
struct DRWPass * transp_accum_infront_ps
struct DRWShadingGroup * vcol_shgrp
struct DRWShadingGroup * image_tiled_shgrp
struct DRWShadingGroup * common_shgrp
struct GHash * material_hash
struct DRWShadingGroup * image_shgrp
struct GPUUniformBuf * world_ubo
struct GPUUniformBuf * material_ubo_curr
struct GPUTexture * reveal_buffer_tx
WORKBENCH_Prepass prepass[2][2][WORKBENCH_DATATYPE_MAX]
struct GPUTexture * accum_buffer_tx
struct WORKBENCH_PrivateData * wpd
GPUShader * workbench_shader_transparent_resolve_get(WORKBENCH_PrivateData *wpd)
GPUShader * workbench_shader_transparent_image_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data, bool tiled)
#define NORMAL_ENCODING_ENABLED()
#define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)
eWORKBENCH_DataType
@ WORKBENCH_DATATYPE_MAX
GPUShader * workbench_shader_transparent_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data)
BLI_INLINE bool workbench_is_specular_highlight_enabled(WORKBENCH_PrivateData *wpd)
void workbench_transparent_engine_init(WORKBENCH_Data *data)
static void workbench_transparent_lighting_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
void workbench_transparent_cache_init(WORKBENCH_Data *vedata)
void workbench_transparent_draw_depth_pass(WORKBENCH_Data *data)