Blender  V2.93
eevee_screen_raytrace.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_dynstr.h"
28 #include "BLI_string_utils.h"
29 
30 #include "DEG_depsgraph_query.h"
31 
32 #include "GPU_texture.h"
33 #include "eevee_private.h"
34 
36 {
37  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
38  EEVEE_StorageList *stl = vedata->stl;
39  EEVEE_FramebufferList *fbl = vedata->fbl;
40  EEVEE_EffectsInfo *effects = stl->effects;
41  const float *viewport_size = DRW_viewport_size_get();
42 
43  const DRWContextState *draw_ctx = DRW_context_state_get();
44  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
45 
46  if (scene_eval->eevee.flag & SCE_EEVEE_SSR_ENABLED) {
47  const bool use_refraction = (scene_eval->eevee.flag & SCE_EEVEE_SSR_REFRACTION) != 0;
48 
49  const bool is_persp = DRW_view_is_persp_get(NULL);
50  if (effects->ssr_was_persp != is_persp) {
51  effects->ssr_was_persp = is_persp;
54  stl->g_data->valid_double_buffer = false;
55  }
56 
57  if (!effects->ssr_was_valid_double_buffer) {
60  }
62 
63  effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0;
64  common_data->ssr_thickness = scene_eval->eevee.ssr_thickness;
65  common_data->ssr_border_fac = scene_eval->eevee.ssr_border_fade;
66  common_data->ssr_firefly_fac = scene_eval->eevee.ssr_firefly_fac;
67  common_data->ssr_max_roughness = scene_eval->eevee.ssr_max_roughness;
68  common_data->ssr_quality = 1.0f - 0.95f * scene_eval->eevee.ssr_quality;
69  common_data->ssr_brdf_bias = 0.1f + common_data->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */
70 
71  if (common_data->ssr_firefly_fac < 1e-8f) {
72  common_data->ssr_firefly_fac = FLT_MAX;
73  }
74 
75  void *owner = (void *)EEVEE_screen_raytrace_init;
76  const int divisor = (effects->reflection_trace_full) ? 1 : 2;
77  int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
78  const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
79  const bool high_qual_input = true; /* TODO dither low quality input */
80  const eGPUTextureFormat format = (high_qual_input) ? GPU_RGBA16F : GPU_RGBA8;
81 
82  tracing_res[0] = max_ii(1, tracing_res[0]);
83  tracing_res[1] = max_ii(1, tracing_res[1]);
84 
85  common_data->ssr_uv_scale[0] = size_fs[0] / ((float)tracing_res[0] * divisor);
86  common_data->ssr_uv_scale[1] = size_fs[1] / ((float)tracing_res[1] * divisor);
87 
88  /* MRT for the shading pass in order to output needed data for the SSR pass. */
89  effects->ssr_specrough_input = DRW_texture_pool_query_2d(UNPACK2(size_fs), format, owner);
90 
92 
93  /* Ray-tracing output. */
94  effects->ssr_hit_output = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_RGBA16F, owner);
95  effects->ssr_hit_depth = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_R16F, owner);
96 
97  GPU_framebuffer_ensure_config(&fbl->screen_tracing_fb,
98  {
99  GPU_ATTACHMENT_NONE,
100  GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output),
101  GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_depth),
102  });
103 
105  ((use_refraction) ? EFFECT_REFRACT : 0);
106  }
107 
108  /* Cleanup to release memory */
110  effects->ssr_specrough_input = NULL;
111  effects->ssr_hit_output = NULL;
112 
113  return 0;
114 }
115 
117 {
118  EEVEE_PassList *psl = vedata->psl;
119  EEVEE_StorageList *stl = vedata->stl;
120  EEVEE_TextureList *txl = vedata->txl;
121  EEVEE_EffectsInfo *effects = stl->effects;
122  LightCache *lcache = stl->g_data->light_cache;
123 
124  if ((effects->enabled_effects & EFFECT_SSR) != 0) {
127 
128  int hitbuf_size[3];
129  GPU_texture_get_mipmap_size(effects->ssr_hit_output, 0, hitbuf_size);
130 
145  DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace);
146  DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
147  DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
148  DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
149  DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
151  DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
152  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
153  DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
154  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
155  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
156  DRW_shgroup_uniform_vec2_copy(grp, "targetSize", (float[2]){hitbuf_size[0], hitbuf_size[1]});
158  grp, "randomScale", effects->reflection_trace_full ? 0.0f : 0.5f);
160 
162 
164  grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve);
165  DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
166  DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
167  DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
168  DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
169  DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
170  DRW_shgroup_uniform_texture_ref_ex(grp, "hitBuffer", &effects->ssr_hit_output, no_filter);
171  DRW_shgroup_uniform_texture_ref_ex(grp, "hitDepth", &effects->ssr_hit_depth, no_filter);
172  DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->filtered_radiance);
173  DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
174  DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
175  DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
177  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
178  DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
179  DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
180  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
181  DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
182  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
183  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
184  DRW_shgroup_uniform_int(grp, "samplePoolOffset", &effects->taa_current_sample, 1);
185  DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
187  }
188 }
189 
191 {
192  EEVEE_FramebufferList *fbl = vedata->fbl;
193  EEVEE_TextureList *txl = vedata->txl;
194  EEVEE_StorageList *stl = vedata->stl;
195  EEVEE_EffectsInfo *effects = stl->effects;
196 
197  if ((effects->enabled_effects & EFFECT_REFRACT) != 0) {
199 
200  /* Restore */
202  }
203 }
204 
206 {
207  EEVEE_PassList *psl = vedata->psl;
208  EEVEE_FramebufferList *fbl = vedata->fbl;
209  EEVEE_StorageList *stl = vedata->stl;
210  EEVEE_TextureList *txl = vedata->txl;
211  EEVEE_EffectsInfo *effects = stl->effects;
212 
213  if (((effects->enabled_effects & EFFECT_SSR) != 0) && stl->g_data->valid_double_buffer) {
214  DRW_stats_group_start("SSR");
215 
216  /* Raytrace. */
219 
221 
224 
225  /* Restore */
228  }
229 }
230 
232  EEVEE_Data *vedata,
233  uint tot_samples)
234 {
235  EEVEE_FramebufferList *fbl = vedata->fbl;
236  EEVEE_TextureList *txl = vedata->txl;
237 
238  /* Create FrameBuffer. */
239  const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F;
240  DRW_texture_ensure_fullscreen_2d(&txl->ssr_accum, texture_format, 0);
241 
242  GPU_framebuffer_ensure_config(&fbl->ssr_accum_fb,
243  {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ssr_accum)});
244 }
245 
247 {
248  EEVEE_FramebufferList *fbl = vedata->fbl;
249  EEVEE_PassList *psl = vedata->psl;
250  EEVEE_StorageList *stl = vedata->stl;
251  EEVEE_EffectsInfo *effects = vedata->stl->effects;
252 
253  if (stl->g_data->valid_double_buffer) {
255 
256  /* Clear texture. */
257  if (effects->taa_current_sample == 1) {
258  const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
259  GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear);
260  }
261 
263  }
264 }
typedef float(TangentPoint)[2]
A dynamically sized string ADT.
MINLINE int max_ii(int a, int 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)
@ SCE_EEVEE_SSR_ENABLED
@ SCE_EEVEE_SSR_REFRACTION
@ SCE_EEVEE_SSR_HALF_RESOLUTION
@ 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 GPU_FRAMEBUFFER_FREE_SAFE(fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
struct GPUShader GPUShader
Definition: GPU_shader.h:33
eGPUSamplerState
Definition: GPU_texture.h:40
@ GPU_SAMPLER_DEFAULT
Definition: GPU_texture.h:41
void GPU_texture_get_mipmap_size(GPUTexture *tex, int lvl, int *size)
Definition: gpu_texture.cc:590
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_R16F
Definition: GPU_texture.h:114
@ GPU_RGBA32F
Definition: GPU_texture.h:91
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_RGBA8
Definition: GPU_texture.h:88
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
void DRW_viewport_request_redraw(void)
Definition: draw_manager.c:707
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
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)
bool DRW_view_is_persp_get(const DRWView *view)
void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex, eGPUSamplerState sampler_state)
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_int(DRWShadingGroup *shgroup, const char *name, const int *value, int arraysize)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
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_pool_query_2d(int w, int h, eGPUTextureFormat format, DrawEngineType *engine_type)
void EEVEE_effects_downsample_radiance_buffer(EEVEE_Data *vedata, GPUTexture *texture_src)
struct GPUTexture * EEVEE_materials_get_util_tex(void)
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata)
struct GPUShader * EEVEE_shaders_effect_reflection_trace_sh_get(void)
struct GPUShader * EEVEE_shaders_effect_reflection_resolve_sh_get(void)
@ EFFECT_RADIANCE_BUFFER
@ EFFECT_DOUBLE_BUFFER
@ EFFECT_REFRACT
@ EFFECT_NORMAL_BUFFER
@ EFFECT_SSR
void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, uint tot_samples)
void EEVEE_refraction_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot, int mip)
format
Definition: logImageCore.h:47
static void clear(Message *msg)
Definition: msgfmt.c:294
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUTexture * gtao_horizons
struct GPUTexture * ssr_hit_output
bool ssr_was_valid_double_buffer
struct GPUTexture * ssr_specrough_input
EEVEE_EffectsFlag enabled_effects
struct GPUTexture * ssr_normal_input
struct GPUTexture * ssr_hit_depth
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * screen_tracing_fb
struct GPUFrameBuffer * main_color_fb
struct GPUFrameBuffer * ssr_accum_fb
struct DRWPass * ssr_resolve
struct DRWPass * ssr_raytrace
struct LightCache * light_cache
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
struct GPUTexture * filtered_radiance
struct GPUTexture * planar_depth
struct GPUTexture * color_double_buffer
struct GPUTexture * maxzbuffer
struct GPUTexture * planar_pool
struct GPUTexture * color
struct GPUTexture * ssr_accum
struct EEVEE_CommonUniformBuffer common_data
struct GPUTexture * shadow_cube_pool
struct GPUUniformBuf * combined
struct GPUUniformBuf * shadow_ubo
struct GPUUniformBuf * probe_ubo
struct GPUUniformBuf * grid_ubo
struct GPUUniformBuf * planar_ubo
struct EEVEE_ViewLayerData::@202 renderpass_ubo
struct GPUUniformBuf * common_ubo
struct GPUUniformBuf * light_ubo
struct GPUTexture * shadow_cascade_pool
struct GPUTexture * tex
LightCacheTexture cube_tx
float ssr_max_roughness
float ssr_border_fade
float ssr_firefly_fac
struct SceneEEVEE eevee