Blender  V2.93
eevee_occlusion.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 2016, Blender Foundation.
17  */
18 
25 #include "DRW_render.h"
26 
27 #include "BLI_string_utils.h"
28 
29 #include "DEG_depsgraph_query.h"
30 
31 #include "BKE_global.h" /* for G.debug_value */
32 
33 #include "eevee_private.h"
34 
35 #include "GPU_capabilities.h"
36 #include "GPU_platform.h"
37 #include "GPU_state.h"
38 
39 static struct {
41 } e_data = {NULL}; /* Engine data */
42 
44 {
45  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
46  EEVEE_FramebufferList *fbl = vedata->fbl;
47  EEVEE_StorageList *stl = vedata->stl;
48  EEVEE_EffectsInfo *effects = stl->effects;
49 
50  const DRWContextState *draw_ctx = DRW_context_state_get();
51  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
52 
53  if (!e_data.dummy_horizon_tx) {
54  const float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
55  e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel);
56  }
57 
58  if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED ||
60  const float *viewport_size = DRW_viewport_size_get();
61  const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
62 
63  common_data->ao_dist = scene_eval->eevee.gtao_distance;
64  common_data->ao_factor = max_ff(1e-4f, scene_eval->eevee.gtao_factor);
65  common_data->ao_quality = scene_eval->eevee.gtao_quality;
66 
67  if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
68  common_data->ao_settings = 1.0f; /* USE_AO */
69  }
70  if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BENT_NORMALS) {
71  common_data->ao_settings += 2.0f; /* USE_BENT_NORMAL */
72  }
73  if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) {
74  common_data->ao_settings += 4.0f; /* USE_DENOISE */
75  }
76 
77  common_data->ao_bounce_fac = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_BOUNCE) ? 1.0f : 0.0f;
78 
81  GPU_framebuffer_ensure_config(
82  &fbl->gtao_fb,
83  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_renderpass)});
84 
85  if (G.debug_value == 6) {
88  GPU_framebuffer_ensure_config(
89  &fbl->gtao_debug_fb,
90  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(effects->gtao_horizons_debug)});
91  }
92  else {
93  effects->gtao_horizons_debug = NULL;
94  }
95 
96  effects->gtao_horizons = (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) ?
97  effects->gtao_horizons_renderpass :
98  e_data.dummy_horizon_tx;
99 
101  }
102 
103  /* Cleanup */
104  effects->gtao_horizons_renderpass = e_data.dummy_horizon_tx;
105  effects->gtao_horizons = e_data.dummy_horizon_tx;
107  common_data->ao_settings = 0.0f;
108 
109  return 0;
110 }
111 
113 {
114  EEVEE_FramebufferList *fbl = vedata->fbl;
115  EEVEE_TextureList *txl = vedata->txl;
116  EEVEE_StorageList *stl = vedata->stl;
117  EEVEE_PassList *psl = vedata->psl;
118  EEVEE_EffectsInfo *effects = stl->effects;
119 
120  const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
121 
123 
124  /* Should be enough precision for many samples. */
125  DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0);
126 
127  GPU_framebuffer_ensure_config(&fbl->ao_accum_fb,
128  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)});
129 
130  /* Accumulation pass */
134  psl->ao_accum_ps);
136  DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
137  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
138  DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
139  DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass);
140  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
141  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
143 }
144 
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;
152 
153  if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
168  psl->ao_horizon_search);
170  DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
171  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
172  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
174 
175  if (G.debug_value == 6) {
178  psl->ao_horizon_debug);
180  DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
181  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
182  DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
183  DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons_renderpass);
184  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
185  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
187  }
188  }
189 }
190 
192 {
193  EEVEE_PassList *psl = vedata->psl;
194  EEVEE_FramebufferList *fbl = vedata->fbl;
195  EEVEE_StorageList *stl = vedata->stl;
196  EEVEE_EffectsInfo *effects = stl->effects;
197  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
198 
199  if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
200  DRW_stats_group_start("GTAO Horizon Scan");
201 
204  if (common_data->ray_type != EEVEE_RAY_GLOSSY) {
205  const float *viewport_size = DRW_viewport_size_get();
206  GPU_framebuffer_viewport_set(fbl->gtao_fb, 0, 0, UNPACK2(viewport_size));
207  }
208 
210 
212 
213  if (common_data->ray_type != EEVEE_RAY_GLOSSY) {
215  }
216 
219  /* Fix dot corruption on intel HD5XX/HD6XX series. */
220  GPU_flush();
221  }
222 
223  /* Restore */
225 
227  }
228 }
229 
231 {
232  EEVEE_PassList *psl = vedata->psl;
233  EEVEE_FramebufferList *fbl = vedata->fbl;
234  EEVEE_StorageList *stl = vedata->stl;
235  EEVEE_EffectsInfo *effects = stl->effects;
236 
237  if (((effects->enabled_effects & EFFECT_GTAO) != 0) && (G.debug_value == 6)) {
238  DRW_stats_group_start("GTAO Debug");
239 
242 
243  /* Restore */
245 
247  }
248 }
249 
251 {
252  EEVEE_FramebufferList *fbl = vedata->fbl;
253  EEVEE_PassList *psl = vedata->psl;
254  EEVEE_EffectsInfo *effects = vedata->stl->effects;
255 
256  if (fbl->ao_accum_fb != NULL) {
258 
259  /* Update the min_max/horizon buffers so the refraction materials appear in it. */
260  EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
261  EEVEE_occlusion_compute(sldata, vedata);
262 
264 
265  /* Clear texture. */
266  if (effects->taa_current_sample == 1) {
267  const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
268  GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
269  }
270 
272 
273  /* Restore */
275  }
276 }
277 
279 {
280  DRW_TEXTURE_FREE_SAFE(e_data.dummy_horizon_tx);
281 }
MINLINE float max_ff(float a, float b)
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNPACK2(a)
#define UNUSED(x)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ EEVEE_RENDER_PASS_AO
@ SCE_EEVEE_GTAO_BOUNCE
@ SCE_EEVEE_GTAO_BENT_NORMALS
@ SCE_EEVEE_GTAO_ENABLED
@ DRW_TEX_WRAP
Definition: DRW_render.h:140
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_BLEND_ADD
Definition: DRW_render.h:336
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
bool GPU_mip_render_workaround(void)
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
@ GPU_DRIVER_ANY
Definition: GPU_platform.h:56
@ GPU_OS_WIN
Definition: GPU_platform.h:46
@ GPU_DEVICE_INTEL_UHD
Definition: GPU_platform.h:36
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver)
void GPU_flush(void)
Definition: gpu_state.cc:311
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_R32F
Definition: GPU_texture.h:111
@ GPU_R16F
Definition: GPU_texture.h:114
@ GPU_RGBA8
Definition: GPU_texture.h:88
GPUBatch * DRW_cache_fullscreen_quad_get(void)
Definition: draw_cache.c:358
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
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)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_draw_pass(DRWPass *pass)
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end(void)
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex, eGPUTextureFormat format, DRWTextureFlag flags)
GPUTexture * DRW_texture_create_2d(int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
GPUTexture * DRW_texture_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int layer)
DrawEngineType draw_engine_eevee_type
Definition: eevee_engine.c:622
struct GPUTexture * EEVEE_materials_get_util_tex(void)
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_occlusion_free(void)
struct GPUTexture * dummy_horizon_tx
void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
static struct @195 e_data
void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
#define EEVEE_RAY_GLOSSY
@ EFFECT_GTAO
@ EFFECT_NORMAL_BUFFER
struct GPUShader * EEVEE_shaders_effect_ambient_occlusion_debug_sh_get(void)
struct GPUShader * EEVEE_shaders_effect_ambient_occlusion_sh_get(void)
void GPU_framebuffer_viewport_reset(GPUFrameBuffer *gpu_fb)
void GPU_framebuffer_viewport_set(GPUFrameBuffer *gpu_fb, int x, int y, int width, int height)
static ulong state[N]
static void clear(Message *msg)
Definition: msgfmt.c:294
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct GPUTexture * depth
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUTexture * gtao_horizons_renderpass
struct GPUTexture * gtao_horizons
EEVEE_EffectsFlag enabled_effects
struct GPUTexture * gtao_horizons_debug
struct GPUTexture * ssr_normal_input
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * gtao_fb
struct GPUFrameBuffer * ao_accum_fb
struct GPUFrameBuffer * gtao_debug_fb
struct DRWPass * ao_accum_ps
struct DRWPass * ao_horizon_search
struct DRWPass * ao_horizon_debug
eViewLayerEEVEEPassType render_passes
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
struct GPUTexture * maxzbuffer
struct GPUTexture * ao_accum
struct EEVEE_CommonUniformBuffer common_data
struct GPUUniformBuf * combined
struct EEVEE_ViewLayerData::@202 renderpass_ubo
struct GPUUniformBuf * common_ubo
struct SceneEEVEE eevee
#define G(x, y, z)