Fix T62874: Crash Texture shading+Transparency
[blender.git] / source / blender / draw / engines / workbench / workbench_private.h
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 2016, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw_engine
21  */
22
23 #ifndef __WORKBENCH_PRIVATE_H__
24 #define __WORKBENCH_PRIVATE_H__
25
26
27 #include "BKE_studiolight.h"
28
29 #include "DNA_image_types.h"
30 #include "DNA_view3d_types.h"
31 #include "DNA_world_types.h"
32 #include "DNA_userdef_types.h"
33
34 #include "DRW_render.h"
35
36 #include "workbench_engine.h"
37
38 #define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
39 #define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
40 #define MAX_COMPOSITE_SHADERS (1 << 6)
41 #define MAX_PREPASS_SHADERS (1 << 6)
42 #define MAX_ACCUM_SHADERS (1 << 5)
43 #define MAX_CAVITY_SHADERS (1 << 3)
44
45 #define TEXTURE_DRAWING_ENABLED(wpd) (wpd->shading.color_type == V3D_SHADING_TEXTURE_COLOR)
46 #define FLAT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_FLAT)
47 #define STUDIOLIGHT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_STUDIO)
48 #define MATCAP_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_MATCAP)
49 #define USE_WORLD_ORIENTATION(wpd) ((wpd->shading.flag & V3D_SHADING_WORLD_ORIENTATION) != 0)
50 #define STUDIOLIGHT_TYPE_WORLD_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_WORLD))
51 #define STUDIOLIGHT_TYPE_STUDIO_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_STUDIO))
52 #define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd) (MATCAP_ENABLED(wpd) && (wpd->studio_light->flag & STUDIOLIGHT_TYPE_MATCAP))
53 #define SSAO_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_SSAO) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
54 #define CURVATURE_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_CAVITY) && ((wpd->shading.cavity_type == V3D_SHADING_CAVITY_CURVATURE) || (wpd->shading.cavity_type == V3D_SHADING_CAVITY_BOTH)))
55 #define CAVITY_ENABLED(wpd) (CURVATURE_ENABLED(wpd) || SSAO_ENABLED(wpd))
56 #define SHADOW_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_SHADOW)
57 #define GHOST_ENABLED(psl) (!DRW_pass_is_empty(psl->ghost_prepass_pass) || !DRW_pass_is_empty(psl->ghost_prepass_hair_pass))
58 #define CULL_BACKFACE_ENABLED(wpd) ((wpd->shading.flag & V3D_SHADING_BACKFACE_CULLING) != 0)
59 #define OIT_ENABLED(wpd) (ELEM(wpd->shading.color_type, V3D_SHADING_MATERIAL_COLOR, V3D_SHADING_OBJECT_COLOR, V3D_SHADING_TEXTURE_COLOR))
60
61 #define IS_NAVIGATING(wpd) ((DRW_context_state_get()->rv3d) && (DRW_context_state_get()->rv3d->rflag & RV3D_NAVIGATING))
62 #define FXAA_ENABLED(wpd) ((!DRW_state_is_opengl_render()) && \
63                             (IN_RANGE(wpd->preferences->gpu_viewport_quality, GPU_VIEWPORT_QUALITY_FXAA, GPU_VIEWPORT_QUALITY_TAA8) || \
64                              ((IS_NAVIGATING(wpd) || wpd->is_playback) && (wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8))))
65 #define TAA_ENABLED(wpd) ((DRW_state_is_image_render() && DRW_context_state_get()->scene->r.mode & R_OSA) || \
66                           (!DRW_state_is_image_render() && wpd->preferences->gpu_viewport_quality >= GPU_VIEWPORT_QUALITY_TAA8 && !IS_NAVIGATING(wpd) && !wpd->is_playback))
67 #define SPECULAR_HIGHLIGHT_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)))
68 #define OBJECT_OUTLINE_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
69 #define OBJECT_ID_PASS_ENABLED(wpd) (OBJECT_OUTLINE_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
70 #define MATDATA_PASS_ENABLED(wpd) (wpd->shading.color_type != V3D_SHADING_SINGLE_COLOR || MATCAP_ENABLED(wpd))
71 #define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd))
72 #define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) || SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
73 #define NORMAL_ENCODING_ENABLED() (true)
74 #define WORLD_CLIPPING_ENABLED(wpd) (wpd->world_clip_planes != NULL)
75
76
77 struct RenderEngine;
78 struct RenderLayer;
79 struct rcti;
80
81
82 typedef struct WORKBENCH_FramebufferList {
83         /* Deferred render buffers */
84         struct GPUFrameBuffer *prepass_fb;
85         struct GPUFrameBuffer *ghost_prepass_fb;
86         struct GPUFrameBuffer *cavity_fb;
87         struct GPUFrameBuffer *composite_fb;
88         struct GPUFrameBuffer *id_clear_fb;
89
90         struct GPUFrameBuffer *effect_fb;
91         struct GPUFrameBuffer *effect_taa_fb;
92         struct GPUFrameBuffer *depth_buffer_fb;
93         struct GPUFrameBuffer *color_only_fb;
94
95         struct GPUFrameBuffer *dof_downsample_fb;
96         struct GPUFrameBuffer *dof_coc_tile_h_fb;
97         struct GPUFrameBuffer *dof_coc_tile_v_fb;
98         struct GPUFrameBuffer *dof_coc_dilate_fb;
99         struct GPUFrameBuffer *dof_blur1_fb;
100         struct GPUFrameBuffer *dof_blur2_fb;
101
102         /* Forward render buffers */
103         struct GPUFrameBuffer *object_outline_fb;
104         struct GPUFrameBuffer *transparent_accum_fb;
105         struct GPUFrameBuffer *transparent_revealage_fb;
106 } WORKBENCH_FramebufferList;
107
108 typedef struct WORKBENCH_TextureList {
109         struct GPUTexture *dof_source_tx;
110         struct GPUTexture *coc_halfres_tx;
111         struct GPUTexture *history_buffer_tx;
112         struct GPUTexture *depth_buffer_tx;
113 } WORKBENCH_TextureList;
114
115 typedef struct WORKBENCH_StorageList {
116         struct WORKBENCH_PrivateData *g_data;
117         struct WORKBENCH_EffectInfo *effects;
118         float *dof_ubo_data;
119 } WORKBENCH_StorageList;
120
121 typedef struct WORKBENCH_PassList {
122         /* deferred rendering */
123         struct DRWPass *prepass_pass;
124         struct DRWPass *prepass_hair_pass;
125         struct DRWPass *ghost_prepass_pass;
126         struct DRWPass *ghost_prepass_hair_pass;
127         struct DRWPass *cavity_pass;
128         struct DRWPass *shadow_depth_pass_pass;
129         struct DRWPass *shadow_depth_pass_mani_pass;
130         struct DRWPass *shadow_depth_fail_pass;
131         struct DRWPass *shadow_depth_fail_mani_pass;
132         struct DRWPass *shadow_depth_fail_caps_pass;
133         struct DRWPass *shadow_depth_fail_caps_mani_pass;
134         struct DRWPass *composite_pass;
135         struct DRWPass *composite_shadow_pass;
136         struct DRWPass *oit_composite_pass;
137         struct DRWPass *background_pass;
138         struct DRWPass *background_pass_clip;
139         struct DRWPass *ghost_resolve_pass;
140         struct DRWPass *effect_aa_pass;
141         struct DRWPass *dof_down_ps;
142         struct DRWPass *dof_down2_ps;
143         struct DRWPass *dof_flatten_v_ps;
144         struct DRWPass *dof_flatten_h_ps;
145         struct DRWPass *dof_dilate_h_ps;
146         struct DRWPass *dof_dilate_v_ps;
147         struct DRWPass *dof_blur1_ps;
148         struct DRWPass *dof_blur2_ps;
149         struct DRWPass *dof_resolve_ps;
150         struct DRWPass *volume_pass;
151
152         /* forward rendering */
153         struct DRWPass *transparent_accum_pass;
154         struct DRWPass *object_outline_pass;
155         struct DRWPass *depth_pass;
156         struct DRWPass *checker_depth_pass;
157 } WORKBENCH_PassList;
158
159 typedef struct WORKBENCH_Data {
160         void *engine_type;
161         WORKBENCH_FramebufferList *fbl;
162         WORKBENCH_TextureList *txl;
163         WORKBENCH_PassList *psl;
164         WORKBENCH_StorageList *stl;
165 } WORKBENCH_Data;
166
167 typedef struct WORKBENCH_UBO_Light {
168         float light_direction[4];
169         float specular_color[3], pad;
170         float diffuse_color[3], wrapped;
171 } WORKBENCH_UBO_Light;
172
173 typedef struct WORKBENCH_UBO_World {
174         float background_color_low[4];
175         float background_color_high[4];
176         float object_outline_color[4];
177         float shadow_direction_vs[4];
178         WORKBENCH_UBO_Light lights[4];
179         float ambient_color[4];
180         int num_lights;
181         int matcap_orientation;
182         float background_alpha;
183         float curvature_ridge;
184         float curvature_valley;
185         int pad[3];
186 } WORKBENCH_UBO_World;
187 BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16)
188
189
190 typedef struct WORKBENCH_PrivateData {
191         struct GHash *material_hash;
192         struct GHash *material_transp_hash;
193         struct GPUShader *prepass_solid_sh;
194         struct GPUShader *prepass_solid_hair_sh;
195         struct GPUShader *prepass_texture_sh;
196         struct GPUShader *prepass_texture_hair_sh;
197         struct GPUShader *composite_sh;
198         struct GPUShader *background_sh;
199         struct GPUShader *transparent_accum_sh;
200         struct GPUShader *transparent_accum_hair_sh;
201         struct GPUShader *transparent_accum_texture_sh;
202         struct GPUShader *transparent_accum_texture_hair_sh;
203         View3DShading shading;
204         StudioLight *studio_light;
205         const UserDef *preferences;
206         struct GPUUniformBuffer *world_ubo;
207         struct DRWShadingGroup *shadow_shgrp;
208         struct DRWShadingGroup *depth_shgrp;
209         WORKBENCH_UBO_World world_data;
210         float shadow_multiplier;
211         float shadow_shift;
212         float shadow_focus;
213         float cached_shadow_direction[3];
214         float shadow_mat[4][4];
215         float shadow_inv[4][4];
216         /* Far plane of the view frustum. */
217         float shadow_far_plane[4];
218         /* Near plane corners in shadow space. */
219         float shadow_near_corners[4][3];
220         /* min and max of shadow_near_corners. allow fast test */
221         float shadow_near_min[3];
222         float shadow_near_max[3];
223         /* This is a parallelogram, so only 2 normal and distance to the edges. */
224         float shadow_near_sides[2][4];
225         bool shadow_changed;
226         bool is_playback;
227
228         float (*world_clip_planes)[4];
229         struct GPUBatch *world_clip_planes_batch;
230         float world_clip_planes_color[4];
231
232         /* Volumes */
233         bool volumes_do;
234         ListBase smoke_domains;
235
236         /* Ssao */
237         float winmat[4][4];
238         float viewvecs[3][4];
239         float ssao_params[4];
240         float ssao_settings[4];
241
242         /* Dof */
243         struct GPUTexture *dof_blur_tx;
244         struct GPUTexture *coc_temp_tx;
245         struct GPUTexture *coc_tiles_tx[2];
246         struct GPUUniformBuffer *dof_ubo;
247         float dof_aperturesize;
248         float dof_distance;
249         float dof_invsensorsize;
250         float dof_near_far[2];
251         float dof_blades;
252         float dof_rotation;
253         float dof_ratio;
254         bool dof_enabled;
255
256         /* Color Management */
257         bool use_color_management;
258         bool use_color_render_settings;
259 } WORKBENCH_PrivateData; /* Transient data */
260
261 typedef struct WORKBENCH_EffectInfo {
262         float override_persmat[4][4];
263         float override_persinv[4][4];
264         float override_winmat[4][4];
265         float override_wininv[4][4];
266         float last_mat[4][4];
267         float curr_mat[4][4];
268         int jitter_index;
269         float taa_mix_factor;
270         bool view_updated;
271 } WORKBENCH_EffectInfo;
272
273 typedef struct WORKBENCH_MaterialData {
274         float base_color[3];
275         float diffuse_color[3];
276         float specular_color[3];
277         float metallic;
278         float roughness;
279         int object_id;
280         int color_type;
281         int interp;
282         Image *ima;
283         ImageUser *iuser;
284
285         /* Linked shgroup for drawing */
286         DRWShadingGroup *shgrp;
287         /* forward rendering */
288         DRWShadingGroup *shgrp_object_outline;
289 } WORKBENCH_MaterialData;
290
291 typedef struct WORKBENCH_ObjectData {
292         DrawData dd;
293
294         /* Shadow direction in local object space. */
295         float shadow_dir[3], shadow_depth;
296         /* Min, max in shadow space */
297         float shadow_min[3], shadow_max[3];
298         BoundBox shadow_bbox;
299         bool shadow_bbox_dirty;
300
301         int object_id;
302 } WORKBENCH_ObjectData;
303
304 /* workbench_deferred.c */
305 void workbench_deferred_engine_init(WORKBENCH_Data *vedata);
306 void workbench_deferred_engine_free(void);
307 void workbench_deferred_draw_background(WORKBENCH_Data *vedata);
308 void workbench_deferred_draw_scene(WORKBENCH_Data *vedata);
309 void workbench_deferred_draw_finish(WORKBENCH_Data *vedata);
310 void workbench_deferred_cache_init(WORKBENCH_Data *vedata);
311 void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob);
312 void workbench_deferred_cache_finish(WORKBENCH_Data *vedata);
313
314 /* workbench_forward.c */
315 void workbench_forward_engine_init(WORKBENCH_Data *vedata);
316 void workbench_forward_engine_free(void);
317 void workbench_forward_draw_background(WORKBENCH_Data *vedata);
318 void workbench_forward_draw_scene(WORKBENCH_Data *vedata);
319 void workbench_forward_draw_finish(WORKBENCH_Data *vedata);
320 void workbench_forward_cache_init(WORKBENCH_Data *vedata);
321 void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob);
322 void workbench_forward_cache_finish(WORKBENCH_Data *vedata);
323
324 /* For OIT in deferred */
325 void workbench_forward_outline_shaders_ensure(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg);
326 void workbench_forward_choose_shaders(WORKBENCH_PrivateData *wpd, eGPUShaderConfig sh_cfg);
327 WORKBENCH_MaterialData *workbench_forward_get_or_create_material_data(
328         WORKBENCH_Data *vedata, Object *ob, Material *mat, Image *ima, ImageUser *iuser, int color_type, int interp);
329
330 /* workbench_effect_aa.c */
331 void workbench_aa_create_pass(WORKBENCH_Data *vedata, GPUTexture **tx);
332 void workbench_aa_draw_pass(WORKBENCH_Data *vedata, GPUTexture *tx);
333
334 /* workbench_effect_fxaa.c */
335 void workbench_fxaa_engine_init(void);
336 void workbench_fxaa_engine_free(void);
337 DRWPass *workbench_fxaa_create_pass(GPUTexture **color_buffer_tx);
338
339 /* workbench_effect_taa.c */
340 void workbench_taa_engine_init(WORKBENCH_Data *vedata);
341 void workbench_taa_engine_free(void);
342 DRWPass *workbench_taa_create_pass(WORKBENCH_Data *vedata, GPUTexture **color_buffer_tx);
343 void workbench_taa_draw_scene_start(WORKBENCH_Data *vedata);
344 void workbench_taa_draw_scene_end(WORKBENCH_Data *vedata);
345 void workbench_taa_view_updated(WORKBENCH_Data *vedata);
346 int workbench_taa_calculate_num_iterations(WORKBENCH_Data *vedata);
347
348 /* workbench_effect_dof.c */
349 void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera);
350 void workbench_dof_engine_free(void);
351 void workbench_dof_create_pass(WORKBENCH_Data *vedata, GPUTexture **dof_input, GPUTexture *noise_tex);
352 void workbench_dof_draw_pass(WORKBENCH_Data *vedata);
353
354 /* workbench_materials.c */
355 int workbench_material_determine_color_type(WORKBENCH_PrivateData *wpd, Image *ima, Object *ob);
356 void workbench_material_get_image_and_mat(Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp, Material **r_mat);
357 char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
358 void workbench_material_update_data(WORKBENCH_PrivateData *wpd, Object *ob, Material *mat, WORKBENCH_MaterialData *data);
359 uint workbench_material_get_hash(WORKBENCH_MaterialData *material_template, bool is_ghost);
360 int workbench_material_get_composite_shader_index(WORKBENCH_PrivateData *wpd);
361 int workbench_material_get_prepass_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
362 int workbench_material_get_accum_shader_index(WORKBENCH_PrivateData *wpd, bool use_textures, bool is_hair);
363 void workbench_material_shgroup_uniform(
364         WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp, WORKBENCH_MaterialData *material, Object *ob,
365         const bool use_metallic, const bool deferred, const int interp);
366 void workbench_material_copy(WORKBENCH_MaterialData *dest_material, const WORKBENCH_MaterialData *source_material);
367
368 /* workbench_studiolight.c */
369 void studiolight_update_world(WORKBENCH_PrivateData *wpd, StudioLight *sl, WORKBENCH_UBO_World *wd);
370 void studiolight_update_light(WORKBENCH_PrivateData *wpd, const float light_direction[3]);
371 bool studiolight_object_cast_visible_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
372 float studiolight_object_shadow_distance(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
373 bool studiolight_camera_in_object_shadow(WORKBENCH_PrivateData *wpd, Object *ob, WORKBENCH_ObjectData *oed);
374
375 /* workbench_data.c */
376 void workbench_effect_info_init(WORKBENCH_EffectInfo *effect_info);
377 void workbench_private_data_init(WORKBENCH_PrivateData *wpd);
378 void workbench_private_data_free(WORKBENCH_PrivateData *wpd);
379 void workbench_private_data_get_light_direction(WORKBENCH_PrivateData *wpd, float r_light_direction[3]);
380
381 /* workbench_volume.c */
382 void workbench_volume_engine_init(void);
383 void workbench_volume_engine_free(void);
384 void workbench_volume_cache_init(WORKBENCH_Data *vedata);
385 void workbench_volume_cache_populate(WORKBENCH_Data *vedata, Scene *scene, Object *ob, struct ModifierData *md);
386 void workbench_volume_smoke_textures_free(WORKBENCH_PrivateData *wpd);
387
388 /* workbench_render.c */
389 void workbench_render(WORKBENCH_Data *vedata, struct RenderEngine *engine, struct RenderLayer *render_layer, const struct rcti *rect);
390 void workbench_render_update_passes(struct RenderEngine *engine, struct Scene *scene, struct ViewLayer *view_layer);
391
392 #endif