void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_StorageList *stl = vedata->stl; EEVEE_TextureList *txl = vedata->txl; EEVEE_EffectsInfo *effects = stl->effects; if (((effects->enabled_effects & EFFECT_SSR) != 0) && stl->g_data->valid_double_buffer) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); e_data.depth_src = dtxl->depth; DRW_stats_group_start("SSR"); /* Raytrace. */ GPU_framebuffer_bind(fbl->screen_tracing_fb); DRW_draw_pass(psl->ssr_raytrace); EEVEE_downsample_buffer(vedata, txl->color_double_buffer, 9); /* Resolve at fullres */ int sample = (DRW_state_is_image_render()) ? effects->taa_render_sample : effects->taa_current_sample; /* Doing a neighbor shift only after a few iteration. * We wait for a prime number of cycles to avoid noise correlation. * This reduces variance faster. */ effects->ssr_neighbor_ofs = ((sample / 5) % 8) * 4; switch ((sample / 11) % 4) { case 0: effects->ssr_halfres_ofs[0] = 0; effects->ssr_halfres_ofs[1] = 0; break; case 1: effects->ssr_halfres_ofs[0] = 0; effects->ssr_halfres_ofs[1] = 1; break; case 2: effects->ssr_halfres_ofs[0] = 1; effects->ssr_halfres_ofs[1] = 0; break; case 4: effects->ssr_halfres_ofs[0] = 1; effects->ssr_halfres_ofs[1] = 1; break; } GPU_framebuffer_bind(fbl->main_color_fb); DRW_draw_pass(psl->ssr_resolve); /* Restore */ GPU_framebuffer_bind(fbl->main_fb); DRW_stats_group_end(); } }
void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_PassList *psl = vedata->psl; if (fbl->ao_accum_fb != NULL) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); /* Update the min_max/horizon buffers so the refracion materials appear in it. */ EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); GPU_framebuffer_bind(fbl->ao_accum_fb); DRW_draw_pass(psl->ao_accum_ps); /* Restore */ GPU_framebuffer_bind(fbl->main_fb); } }
void EEVEE_occlusion_draw_debug(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) { EEVEE_PassList *psl = vedata->psl; EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; if (((effects->enabled_effects & EFFECT_GTAO) != 0) && (G.debug_value == 6)) { DRW_stats_group_start("GTAO Debug"); GPU_framebuffer_bind(fbl->gtao_debug_fb); DRW_draw_pass(psl->ao_horizon_debug); /* Restore */ GPU_framebuffer_bind(fbl->main_fb); DRW_stats_group_end(); } }
void EEVEE_occlusion_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer) { EEVEE_PassList *psl = vedata->psl; EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; if ((effects->enabled_effects & EFFECT_GTAO) != 0) { DRW_stats_group_start("GTAO Horizon Scan"); effects->ao_src_depth = depth_src; effects->ao_depth_layer = layer; GPU_framebuffer_bind(fbl->gtao_fb); if (layer >= 0) { DRW_draw_pass(psl->ao_horizon_search_layer); } else { DRW_draw_pass(psl->ao_horizon_search); } if (GPU_mip_render_workaround() || GPU_type_matches(GPU_DEVICE_INTEL_UHD, GPU_OS_WIN, GPU_DRIVER_ANY)) { /* Fix dot corruption on intel HD5XX/HD6XX series. */ GPU_flush(); } /* Restore */ GPU_framebuffer_bind(fbl->main_fb); DRW_stats_group_end(); } }
void EEVEE_refraction_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; if ((effects->enabled_effects & EFFECT_REFRACT) != 0) { GPU_framebuffer_blit(fbl->main_fb, 0, fbl->refract_fb, 0, GPU_COLOR_BIT); EEVEE_downsample_buffer(vedata, txl->refract_color, 9); /* Restore */ GPU_framebuffer_bind(fbl->main_fb); } }
/* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow. * Calling this function should be avoided during interactive drawing. */ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void *data) { DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport); GPUFrameBuffer *tmp_fb = GPU_framebuffer_create(); GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0); GPU_framebuffer_bind(tmp_fb); glReadPixels(rect->xmin, rect->ymin, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect), GL_DEPTH_COMPONENT, GL_FLOAT, data); GPU_framebuffer_restore(); GPU_framebuffer_free(tmp_fb); }
void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_StorageList *stl = vedata->stl; EEVEE_PassList *psl = vedata->psl; EEVEE_EffectsInfo *effects = stl->effects; const DRWContextState *draw_ctx = DRW_context_state_get(); const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) { DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f}; DRW_texture_ensure_fullscreen_2d( &txl->ao_accum, GPU_R32F, 0); /* Should be enough precision for many samples. */ GPU_framebuffer_ensure_config(&fbl->ao_accum_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)}); /* Clear texture. */ GPU_framebuffer_bind(fbl->ao_accum_fb); GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear); /* Accumulation pass */ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE; psl->ao_accum_ps = DRW_pass_create("AO Accum", state); DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_accum_ps); DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex()); DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer); DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth); DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input); DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL); } else { /* Cleanup to release memory */ DRW_TEXTURE_FREE_SAFE(txl->ao_accum); GPU_FRAMEBUFFER_FREE_SAFE(fbl->ao_accum_fb); } }
static void eevee_lightbake_render_world_sample(void *ved, void *user_data) { EEVEE_Data *vedata = (EEVEE_Data *)ved; EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); EEVEE_LightBake *lbake = (EEVEE_LightBake *)user_data; Scene *scene_eval = DEG_get_evaluated_scene(lbake->depsgraph); LightCache *lcache = scene_eval->eevee.light_cache; float clamp = scene_eval->eevee.gi_glossy_clamp; float filter_quality = scene_eval->eevee.gi_filter_quality; /* TODO do this once for the whole bake when we have independent DRWManagers. */ eevee_lightbake_cache_create(vedata, lbake); sldata->common_data.ray_type = EEVEE_RAY_GLOSSY; sldata->common_data.ray_depth = 1; DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb); EEVEE_lightbake_filter_glossy(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f, lcache->mips_len, filter_quality, clamp); sldata->common_data.ray_type = EEVEE_RAY_DIFFUSE; sldata->common_data.ray_depth = 1; DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); EEVEE_lightbake_render_world(sldata, vedata, lbake->rt_fb); EEVEE_lightbake_filter_diffuse(sldata, vedata, lbake->rt_color, lbake->store_fb, 0, 1.0f); /* Clear the cache to avoid white values in the grid. */ GPU_framebuffer_texture_attach(lbake->store_fb, lbake->grid_prev, 0, 0); GPU_framebuffer_bind(lbake->store_fb); /* Clear to 1.0f for visibility. */ GPU_framebuffer_clear_color(lbake->store_fb, ((float[4]){1.0f, 1.0f, 1.0f, 1.0f}));