Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/workbench/workbench_effect_dof.c')
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c217
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..8aa37c6b9fc 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:
+ * - downsample the color buffer using a COC (Circle of Confusion) aware downsample algo.
+ * - 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();