Rename any instance of scene layer or render layer in code with view layer
[blender.git] / source / blender / draw / engines / eevee / eevee_occlusion.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file eevee_occlusion.c
23  *  \ingroup draw_engine
24  *
25  * Implementation of the screen space Ground Truth Ambient Occlusion.
26  */
27
28 #include "DRW_render.h"
29
30 #include "BLI_dynstr.h"
31
32 #include "DNA_anim_types.h"
33
34 #include "BKE_global.h" /* for G.debug_value */
35
36 #include "eevee_private.h"
37
38 static struct {
39         /* Ground Truth Ambient Occlusion */
40         struct GPUShader *gtao_sh;
41         struct GPUShader *gtao_debug_sh;
42 } e_data = {NULL}; /* Engine data */
43
44 extern char datatoc_ambient_occlusion_lib_glsl[];
45 extern char datatoc_bsdf_common_lib_glsl[];
46 extern char datatoc_effect_gtao_frag_glsl[];
47
48 static void eevee_create_shader_occlusion(void)
49 {
50         DynStr *ds_frag = BLI_dynstr_new();
51         BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
52         BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
53         BLI_dynstr_append(ds_frag, datatoc_effect_gtao_frag_glsl);
54         char *frag_str = BLI_dynstr_get_cstring(ds_frag);
55         BLI_dynstr_free(ds_frag);
56
57         e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL);
58         e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n");
59
60         MEM_freeN(frag_str);
61 }
62
63 int EEVEE_occlusion_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
64 {
65         EEVEE_StorageList *stl = vedata->stl;
66         EEVEE_FramebufferList *fbl = vedata->fbl;
67         EEVEE_TextureList *txl = vedata->txl;
68         EEVEE_EffectsInfo *effects = stl->effects;
69
70         const DRWContextState *draw_ctx = DRW_context_state_get();
71         ViewLayer *view_layer = draw_ctx->view_layer;
72         IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
73
74         if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) {
75                 const float *viewport_size = DRW_viewport_size_get();
76
77                 /* Shaders */
78                 if (!e_data.gtao_sh) {
79                         eevee_create_shader_occlusion();
80                 }
81
82                 effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
83                 effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
84                 effects->ao_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "gtao_quality");
85                 effects->ao_samples = BKE_collection_engine_property_value_get_int(props, "gtao_samples");
86                 effects->ao_samples_inv = 1.0f / effects->ao_samples;
87
88                 effects->ao_settings = 1.0; /* USE_AO */
89                 if (BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals")) {
90                         effects->ao_settings += 2.0; /* USE_BENT_NORMAL */
91                 }
92                 if (BKE_collection_engine_property_value_get_bool(props, "gtao_denoise")) {
93                         effects->ao_settings += 4.0; /* USE_DENOISE */
94                 }
95
96                 effects->ao_bounce_fac = (float)BKE_collection_engine_property_value_get_bool(props, "gtao_bounce");
97
98                 effects->ao_texsize[0] = ((int)viewport_size[0]);
99                 effects->ao_texsize[1] = ((int)viewport_size[1]);
100
101                 /* Round up to multiple of 2 */
102                 if ((effects->ao_texsize[0] & 0x1) != 0) {
103                         effects->ao_texsize[0] += 1;
104                 }
105                 if ((effects->ao_texsize[1] & 0x1) != 0) {
106                         effects->ao_texsize[1] += 1;
107                 }
108
109                 CLAMP(effects->ao_samples, 1, 32);
110
111                 if (effects->hori_tex_layers != effects->ao_samples) {
112                         DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
113                 }
114
115                 if (txl->gtao_horizons == NULL) {
116                         effects->hori_tex_layers = effects->ao_samples;
117                         txl->gtao_horizons = DRW_texture_create_2D_array((int)viewport_size[0], (int)viewport_size[1], effects->hori_tex_layers, DRW_TEX_RG_8, 0, NULL);
118                 }
119
120                 DRWFboTexture tex = {&txl->gtao_horizons, DRW_TEX_RG_8, 0};
121
122                 DRW_framebuffer_init(&fbl->gtao_fb, &draw_engine_eevee_type,
123                                     effects->ao_texsize[0], effects->ao_texsize[1],
124                                     &tex, 1);
125
126                 if (G.debug_value == 6) {
127                         DRWFboTexture tex_debug = {&stl->g_data->gtao_horizons_debug, DRW_TEX_RGBA_8, DRW_TEX_TEMP};
128
129                         DRW_framebuffer_init(&fbl->gtao_debug_fb, &draw_engine_eevee_type,
130                                             (int)viewport_size[0], (int)viewport_size[1],
131                                             &tex_debug, 1);
132                 }
133
134                 return EFFECT_GTAO | EFFECT_NORMAL_BUFFER;
135         }
136
137         /* Cleanup */
138         DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
139         DRW_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
140         effects->ao_settings = 0.0f;
141
142         return 0;
143 }
144
145 void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
146 {
147         EEVEE_PassList *psl = vedata->psl;
148         EEVEE_StorageList *stl = vedata->stl;
149         EEVEE_TextureList *txl = vedata->txl;
150         EEVEE_EffectsInfo *effects = stl->effects;
151         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
152
153         struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
154
155         if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
156                 /**  Occlusion algorithm overview
157                  *
158                  *  We separate the computation into 2 steps.
159                  *
160                  * - First we scan the neighborhood pixels to find the maximum horizon angle.
161                  *   We save this angle in a RG8 array texture.
162                  *
163                  * - Then we use this angle to compute occlusion with the shading normal at
164                  *   the shading stage. This let us do correct shadowing for each diffuse / specular
165                  *   lobe present in the shader using the correct normal.
166                  **/
167                 psl->ao_horizon_search = DRW_pass_create("GTAO Horizon Search", DRW_STATE_WRITE_COLOR);
168                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_sh, psl->ao_horizon_search);
169                 DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
170                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
171                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
172                 DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
173                 DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
174                 DRW_shgroup_uniform_float(grp, "sampleNbr", &stl->effects->ao_sample_nbr, 1);
175                 DRW_shgroup_uniform_ivec2(grp, "aoHorizonTexSize", (int *)stl->effects->ao_texsize, 1);
176                 DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
177                 DRW_shgroup_call_add(grp, quad, NULL);
178
179                 if (G.debug_value == 6) {
180                         psl->ao_horizon_debug = DRW_pass_create("GTAO Horizon Debug", DRW_STATE_WRITE_COLOR);
181                         grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_horizon_debug);
182                         DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
183                         DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth);
184                         DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
185                         DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &txl->gtao_horizons);
186                         DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
187                         DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
188                         DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
189                         DRW_shgroup_uniform_ivec2(grp, "aoHorizonTexSize", (int *)stl->effects->ao_texsize, 1);
190                         DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
191                         DRW_shgroup_call_add(grp, quad, NULL);
192                 }
193         }
194 }
195
196 void EEVEE_occlusion_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
197 {
198         EEVEE_PassList *psl = vedata->psl;
199         EEVEE_TextureList *txl = vedata->txl;
200         EEVEE_FramebufferList *fbl = vedata->fbl;
201         EEVEE_StorageList *stl = vedata->stl;
202         EEVEE_EffectsInfo *effects = stl->effects;
203
204         if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
205                 DRW_stats_group_start("GTAO Horizon Scan");
206                 for (effects->ao_sample_nbr = 0.0;
207                      effects->ao_sample_nbr < effects->ao_samples;
208                      ++effects->ao_sample_nbr)
209                 {
210                         DRW_framebuffer_texture_detach(txl->gtao_horizons);
211                         DRW_framebuffer_texture_layer_attach(fbl->gtao_fb, txl->gtao_horizons, 0, (int)effects->ao_sample_nbr, 0);
212                         DRW_framebuffer_bind(fbl->gtao_fb);
213
214                         DRW_draw_pass(psl->ao_horizon_search);
215                 }
216
217                 /* Restore */
218                 DRW_framebuffer_bind(fbl->main);
219
220                 DRW_stats_group_end();
221         }
222 }
223
224 void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
225 {
226         EEVEE_PassList *psl = vedata->psl;
227         EEVEE_FramebufferList *fbl = vedata->fbl;
228         EEVEE_StorageList *stl = vedata->stl;
229         EEVEE_EffectsInfo *effects = stl->effects;
230
231         if (((effects->enabled_effects & EFFECT_GTAO) != 0) && (G.debug_value == 6)) {
232                 DRW_stats_group_start("GTAO Debug");
233
234                 DRW_framebuffer_texture_attach(fbl->gtao_debug_fb, stl->g_data->gtao_horizons_debug, 0, 0);
235                 DRW_framebuffer_bind(fbl->gtao_debug_fb);
236
237                 DRW_draw_pass(psl->ao_horizon_debug);
238
239                 /* Restore */
240                 DRW_framebuffer_texture_detach(stl->g_data->gtao_horizons_debug);
241                 DRW_framebuffer_bind(fbl->main);
242
243                 DRW_stats_group_end();
244         }
245 }
246
247 void EEVEE_occlusion_free(void)
248 {
249         DRW_SHADER_FREE_SAFE(e_data.gtao_sh);
250         DRW_SHADER_FREE_SAFE(e_data.gtao_debug_sh);
251 }