diff options
author | Julian Eisel <julian@blender.org> | 2020-03-12 17:58:03 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-03-12 17:58:03 +0300 |
commit | b86be9b2145458037fd0b17433b7af0efa7b6472 (patch) | |
tree | f333625555402992ebb35d258f93eda1130389e6 /source/blender/draw/engines/workbench/workbench_effect_dof.c | |
parent | 00f83ec125207e90bf180b3eb7752d8cb6482a86 (diff) | |
parent | cb6cec904fa14ce0ab10a2a53af5c936d56376cf (diff) |
Merge branch 'temp-openxr-ghostxr' into temp-openxr-blenderside
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_effect_dof.c')
-rw-r--r-- | source/blender/draw/engines/workbench/workbench_effect_dof.c | 217 |
1 files changed, 96 insertions, 121 deletions
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c index ae3e2218463..9716ccd4b44 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_dof.c +++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c @@ -18,6 +18,17 @@ /** \file * \ingroup draw_engine + * + * Depth of Field Effect: + * + * We use a gather approach by sampling a lowres version of the color buffer. + * The process can be summarized like this: + * - down-sample the color buffer using a COC (Circle of Confusion) aware down-sample algorithm. + * - do a gather pass using the COC computed in the previous pass. + * - do a median filter to reduce noise amount. + * - composite on top of main color buffer. + * + * This is done after all passes and affects every surfaces. */ #include "workbench_private.h" @@ -27,24 +38,6 @@ #include "DNA_camera_types.h" -/* *********** STATIC *********** */ -static struct { - struct GPUShader *effect_dof_prepare_sh; - struct GPUShader *effect_dof_downsample_sh; - struct GPUShader *effect_dof_flatten_v_sh; - struct GPUShader *effect_dof_flatten_h_sh; - struct GPUShader *effect_dof_dilate_v_sh; - struct GPUShader *effect_dof_dilate_h_sh; - struct GPUShader *effect_dof_blur1_sh; - struct GPUShader *effect_dof_blur2_sh; - struct GPUShader *effect_dof_resolve_sh; -} e_data = {NULL}; - -/* Shaders */ -extern char datatoc_workbench_effect_dof_frag_glsl[]; - -/* *********** Functions *********** */ - /** * Transform [-1..1] square to unit circle. */ @@ -130,52 +123,40 @@ static void workbench_dof_setup_samples(struct GPUUniformBuffer **ubo, DRW_uniformbuffer_update(*ubo, *data); } -void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera) +void workbench_dof_engine_init(WORKBENCH_Data *vedata) { WORKBENCH_TextureList *txl = vedata->txl; WORKBENCH_StorageList *stl = vedata->stl; - WORKBENCH_PrivateData *wpd = stl->g_data; + WORKBENCH_PrivateData *wpd = stl->wpd; WORKBENCH_FramebufferList *fbl = vedata->fbl; + const DRWContextState *draw_ctx = DRW_context_state_get(); + RegionView3D *rv3d = draw_ctx->rv3d; + View3D *v3d = draw_ctx->v3d; + Scene *scene = draw_ctx->scene; + Object *camera; + + if (v3d && rv3d) { + camera = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL; + } + else { + camera = scene->camera; + } + Camera *cam = camera != NULL ? camera->data : NULL; if ((wpd->shading.flag & V3D_SHADING_DEPTH_OF_FIELD) == 0 || (cam == NULL) || ((cam->dof.flag & CAM_DOF_ENABLED) == 0)) { wpd->dof_enabled = false; - return; - } - - if (e_data.effect_dof_prepare_sh == NULL) { - e_data.effect_dof_prepare_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define PREPARE\n"); - - e_data.effect_dof_downsample_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define DOWNSAMPLE\n"); - - e_data.effect_dof_flatten_v_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define FLATTEN_VERTICAL\n"); - - e_data.effect_dof_flatten_h_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define FLATTEN_HORIZONTAL\n"); - - e_data.effect_dof_dilate_v_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define DILATE_VERTICAL\n"); - - e_data.effect_dof_dilate_h_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define DILATE_HORIZONTAL\n"); - e_data.effect_dof_blur1_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define BLUR1\n"); - - e_data.effect_dof_blur2_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define BLUR2\n"); - - e_data.effect_dof_resolve_sh = DRW_shader_create_fullscreen( - datatoc_workbench_effect_dof_frag_glsl, "#define RESOLVE\n"); + /* Cleanup. */ + DRW_TEXTURE_FREE_SAFE(txl->dof_source_tx); + DRW_TEXTURE_FREE_SAFE(txl->coc_halfres_tx); + return; } const float *full_size = DRW_viewport_size_get(); int size[2] = {max_ii(1, (int)full_size[0] / 2), max_ii(1, (int)full_size[1] / 2)}; -#if 0 +#if 0 /* TODO(fclem) finish COC min_max optimisation */ /* NOTE: We Ceil here in order to not miss any edge texel if using a NPO2 texture. */ int shrink_h_size[2] = {ceilf(size[0] / 8.0f), size[1]}; int shrink_w_size[2] = {shrink_h_size[0], ceilf(size[1] / 8.0f)}; @@ -186,14 +167,14 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera) DRW_texture_ensure_2d( &txl->coc_halfres_tx, size[0], size[1], GPU_RG8, DRW_TEX_FILTER | DRW_TEX_MIPMAP); wpd->dof_blur_tx = DRW_texture_pool_query_2d( - size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid); -#if 0 + size[0], size[1], GPU_RGBA16F, &draw_engine_workbench); +#if 0 /* TODO(fclem) finish COC min_max optimisation */ wpd->coc_temp_tx = DRW_texture_pool_query_2d( - shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench_solid); + shrink_h_size[0], shrink_h_size[1], GPU_RG8, &draw_engine_workbench); wpd->coc_tiles_tx[0] = DRW_texture_pool_query_2d( - shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid); + shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench); wpd->coc_tiles_tx[1] = DRW_texture_pool_query_2d( - shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench_solid); + shrink_w_size[0], shrink_w_size[1], GPU_RG8, &draw_engine_workbench); #endif GPU_framebuffer_ensure_config(&fbl->dof_downsample_fb, @@ -202,7 +183,7 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera) GPU_ATTACHMENT_TEXTURE(txl->dof_source_tx), GPU_ATTACHMENT_TEXTURE(txl->coc_halfres_tx), }); -#if 0 +#if 0 /* TODO(fclem) finish COC min_max optimisation */ GPU_framebuffer_ensure_config(&fbl->dof_coc_tile_h_fb, { GPU_ATTACHMENT_NONE, @@ -231,11 +212,7 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera) }); { - const DRWContextState *draw_ctx = DRW_context_state_get(); - RegionView3D *rv3d = draw_ctx->rv3d; - /* Parameters */ - /* TODO UI Options */ float fstop = cam->dof.aperture_fstop; float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y); float focus_dist = BKE_camera_object_dof_distance(camera); @@ -263,128 +240,125 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata, Object *camera) float rotation = cam->dof.aperture_rotation; float ratio = 1.0f / cam->dof.aperture_ratio; - if (wpd->dof_ubo == NULL || blades != wpd->dof_blades || rotation != wpd->dof_rotation || - ratio != wpd->dof_ratio) { + if (wpd->vldata->dof_sample_ubo == NULL || blades != wpd->dof_blades || + rotation != wpd->dof_rotation || ratio != wpd->dof_ratio) { wpd->dof_blades = blades; wpd->dof_rotation = rotation; wpd->dof_ratio = ratio; - workbench_dof_setup_samples(&wpd->dof_ubo, &stl->dof_ubo_data, blades, rotation, ratio); + workbench_dof_setup_samples( + &wpd->vldata->dof_sample_ubo, &stl->dof_ubo_data, blades, rotation, ratio); } } wpd->dof_enabled = true; } -void workbench_dof_create_pass(WORKBENCH_Data *vedata, - GPUTexture **dof_input, - GPUTexture *noise_tex) +void workbench_dof_cache_init(WORKBENCH_Data *vedata) { WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_TextureList *txl = vedata->txl; WORKBENCH_StorageList *stl = vedata->stl; - WORKBENCH_PrivateData *wpd = stl->g_data; - struct GPUBatch *quad = DRW_cache_fullscreen_quad_get(); + WORKBENCH_PrivateData *wpd = stl->wpd; if (!wpd->dof_enabled) { return; } - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + GPUShader *prepare_sh, *downsample_sh, *blur1_sh, *blur2_sh, *resolve_sh; + workbench_shader_depth_of_field_get( + &prepare_sh, &downsample_sh, &blur1_sh, &blur2_sh, &resolve_sh); - psl->dof_down_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR); - psl->dof_down2_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR); - psl->dof_flatten_h_ps = DRW_pass_create("DoF Flatten Coc H", DRW_STATE_WRITE_COLOR); - psl->dof_flatten_v_ps = DRW_pass_create("DoF Flatten Coc V", DRW_STATE_WRITE_COLOR); - psl->dof_dilate_h_ps = DRW_pass_create("DoF Dilate Coc H", DRW_STATE_WRITE_COLOR); - psl->dof_dilate_v_ps = DRW_pass_create("DoF Dilate Coc V", DRW_STATE_WRITE_COLOR); - psl->dof_blur1_ps = DRW_pass_create("DoF Blur 1", DRW_STATE_WRITE_COLOR); - psl->dof_blur2_ps = DRW_pass_create("DoF Blur 2", DRW_STATE_WRITE_COLOR); - psl->dof_resolve_ps = DRW_pass_create("DoF Resolve", - DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_prepare_sh, psl->dof_down_ps); - DRW_shgroup_uniform_texture_ref(grp, "sceneColorTex", dof_input); + psl->dof_down_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(prepare_sh, psl->dof_down_ps); + DRW_shgroup_uniform_texture(grp, "sceneColorTex", dtxl->color); DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1); DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_downsample_sh, psl->dof_down2_ps); + psl->dof_down2_ps = DRW_pass_create("DoF DownSample", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(downsample_sh, psl->dof_down2_ps); DRW_shgroup_uniform_texture(grp, "sceneColorTex", txl->dof_source_tx); DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } -#if 0 +#if 0 /* TODO(fclem) finish COC min_max optimization */ { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_h_sh, - psl->dof_flatten_h_ps); + psl->dof_flatten_h_ps = DRW_pass_create("DoF Flatten Coc H", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(flatten_h_sh, psl->dof_flatten_h_ps); DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_flatten_v_sh, - psl->dof_flatten_v_ps); + psl->dof_flatten_v_ps = DRW_pass_create("DoF Flatten Coc V", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(flatten_v_sh, psl->dof_flatten_v_ps); DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_temp_tx); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_v_sh, psl->dof_dilate_v_ps); + psl->dof_dilate_h_ps = DRW_pass_create("DoF Dilate Coc H", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(dilate_v_sh, psl->dof_dilate_v_ps); DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[0]); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_dilate_h_sh, psl->dof_dilate_h_ps); + psl->dof_dilate_v_ps = DRW_pass_create("DoF Dilate Coc V", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(dilate_h_sh, psl->dof_dilate_h_ps); DRW_shgroup_uniform_texture(grp, "inputCocTex", wpd->coc_tiles_tx[1]); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } #endif { - float offset = stl->effects->jitter_index / - (float)workbench_taa_calculate_num_iterations(vedata); - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur1_sh, psl->dof_blur1_ps); - DRW_shgroup_uniform_block(grp, "dofSamplesBlock", wpd->dof_ubo); - DRW_shgroup_uniform_texture(grp, "noiseTex", noise_tex); + psl->dof_blur1_ps = DRW_pass_create("DoF Blur 1", DRW_STATE_WRITE_COLOR); + + /* We reuse the same noise texture. Ensure it is up to date. */ + workbench_cavity_samples_ubo_ensure(wpd); + + float offset = wpd->taa_sample / wpd->taa_sample_len; + DRWShadingGroup *grp = DRW_shgroup_create(blur1_sh, psl->dof_blur1_ps); + DRW_shgroup_uniform_block(grp, "dofSamplesBlock", wpd->vldata->dof_sample_ubo); + DRW_shgroup_uniform_texture(grp, "noiseTex", wpd->vldata->cavity_jitter_tx); DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx); DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); DRW_shgroup_uniform_float_copy(grp, "noiseOffset", offset); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_blur2_sh, psl->dof_blur2_ps); + psl->dof_blur2_ps = DRW_pass_create("DoF Blur 2", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(blur2_sh, psl->dof_blur2_ps); DRW_shgroup_uniform_texture(grp, "inputCocTex", txl->coc_halfres_tx); DRW_shgroup_uniform_texture(grp, "blurTex", wpd->dof_blur_tx); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } { - DRWShadingGroup *grp = DRW_shgroup_create(e_data.effect_dof_resolve_sh, psl->dof_resolve_ps); + psl->dof_resolve_ps = DRW_pass_create("DoF Resolve", + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM); + + DRWShadingGroup *grp = DRW_shgroup_create(resolve_sh, psl->dof_resolve_ps); DRW_shgroup_uniform_texture(grp, "halfResColorTex", txl->dof_source_tx); DRW_shgroup_uniform_texture(grp, "sceneDepthTex", dtxl->depth); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); DRW_shgroup_uniform_vec3(grp, "dofParams", &wpd->dof_aperturesize, 1); DRW_shgroup_uniform_vec2(grp, "nearFar", wpd->dof_near_far, 1); - DRW_shgroup_call(grp, quad, NULL); + DRW_shgroup_call_procedural_triangles(grp, NULL, 1); } } -void workbench_dof_engine_free(void) -{ - DRW_SHADER_FREE_SAFE(e_data.effect_dof_prepare_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_downsample_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_v_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_flatten_h_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_v_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_dilate_h_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_blur1_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_blur2_sh); - DRW_SHADER_FREE_SAFE(e_data.effect_dof_resolve_sh); -} - static void workbench_dof_downsample_level(void *userData, int UNUSED(level)) { WORKBENCH_PassList *psl = (WORKBENCH_PassList *)userData; @@ -396,7 +370,8 @@ void workbench_dof_draw_pass(WORKBENCH_Data *vedata) WORKBENCH_FramebufferList *fbl = vedata->fbl; WORKBENCH_StorageList *stl = vedata->stl; WORKBENCH_PassList *psl = vedata->psl; - WORKBENCH_PrivateData *wpd = stl->g_data; + WORKBENCH_PrivateData *wpd = stl->wpd; + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); if (!wpd->dof_enabled) { return; @@ -410,7 +385,7 @@ void workbench_dof_draw_pass(WORKBENCH_Data *vedata) GPU_framebuffer_recursive_downsample( fbl->dof_downsample_fb, 2, workbench_dof_downsample_level, psl); -#if 0 +#if 0 /* TODO(fclem) finish COC min_max optimization */ GPU_framebuffer_bind(fbl->dof_coc_tile_h_fb); DRW_draw_pass(psl->dof_flatten_h_ps); @@ -430,7 +405,7 @@ void workbench_dof_draw_pass(WORKBENCH_Data *vedata) GPU_framebuffer_bind(fbl->dof_blur2_fb); DRW_draw_pass(psl->dof_blur2_ps); - GPU_framebuffer_bind(fbl->color_only_fb); + GPU_framebuffer_bind(dfbl->color_only_fb); DRW_draw_pass(psl->dof_resolve_ps); DRW_stats_group_end(); |