[Bf-blender-cvs] [8f9c04762e3] greasepencil-refactor: GPencil: Refactor: Blur Fx: Implement DoF option and fix radius world size

Clément Foucault noreply at git.blender.org
Fri Dec 20 01:53:51 CET 2019


Commit: 8f9c04762e3c1751e9247a7547781e5fda3e9842
Author: Clément Foucault
Date:   Fri Dec 20 01:51:20 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB8f9c04762e3c1751e9247a7547781e5fda3e9842

GPencil: Refactor: Blur Fx: Implement DoF option and fix radius world size

The size of the blur is now proportional to the distance to the camera
and the object scale (just like any other effects).

The Depth Of Field now works and always match the Circle of confusion of
cycles/EEVEE.

===================================================================

M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/gpencil_render.c
M	source/blender/draw/engines/gpencil/gpencil_shader_fx.c

===================================================================

diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 5249ccfdb8b..145fc65406e 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -29,11 +29,13 @@
 #include "BKE_paint.h"
 #include "BKE_shader_fx.h"
 
+#include "BKE_camera.h"
 #include "BKE_global.h" /* for G.debug */
 
 #include "BLI_link_utils.h"
 #include "BLI_memblock.h"
 
+#include "DNA_camera_types.h"
 #include "DNA_gpencil_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_view3d_types.h"
@@ -331,6 +333,13 @@ static void GPENCIL_engine_init_new(void *ved)
   DRW_view_viewmat_get(NULL, viewmatinv, true);
   copy_v3_v3(stl->pd->camera_z_axis, viewmatinv[2]);
   stl->pd->camera_z_offset = dot_v3v3(viewmatinv[3], viewmatinv[2]);
+
+  if (ctx && ctx->rv3d && ctx->v3d) {
+    stl->pd->camera = (ctx->rv3d->persp == RV3D_CAMOB) ? ctx->v3d->camera : NULL;
+  }
+  else {
+    stl->pd->camera = NULL;
+  }
 }
 
 void GPENCIL_engine_init(void *vedata)
@@ -460,6 +469,35 @@ static void GPENCIL_cache_init_new(void *ved)
     DRW_shgroup_uniform_bool(grp, "strokeOrder3d", &pd->is_stroke_order_3d, 1);
     DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
   }
+
+  Camera *cam = (pd->camera != NULL) ? pd->camera->data : NULL;
+
+  /* Pseudo DOF setup. */
+  if (cam && (cam->dof.flag & CAM_DOF_ENABLED)) {
+    const float *vp_size = DRW_viewport_size_get();
+    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(pd->camera);
+    float focal_len = cam->lens;
+
+    const float scale_camera = 0.001f;
+    /* we want radius here for the aperture number  */
+    float aperture = 0.5f * scale_camera * focal_len / fstop;
+    float focal_len_scaled = scale_camera * focal_len;
+    float sensor_scaled = scale_camera * sensor;
+
+    if (draw_ctx->rv3d != NULL) {
+      sensor_scaled *= draw_ctx->rv3d->viewcamtexcofac[0];
+    }
+
+    pd->dof_params[1] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled));
+    pd->dof_params[1] *= vp_size[0] / sensor_scaled;
+    pd->dof_params[0] = -focus_dist * pd->dof_params[1];
+  }
+  else {
+    /* Disable DoF blur scalling. */
+    pd->camera = NULL;
+  }
 }
 
 void GPENCIL_cache_init(void *vedata)
@@ -833,7 +871,6 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
     tgp_layer->do_masked_clear = true;
   }
 
-  GPUUniformBuffer *ubo_mat;
   gpencil_material_resources_get(iter->matpool, 0, NULL, NULL, &iter->ubo_mat);
 
   const bool is_stroke_order_3d = (gpd->draw_mode == GP_DRAWMODE_3D) || iter->pd->draw_depth_only;
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 82e46bd5a81..6df23de8dd6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -480,6 +480,10 @@ typedef struct GPENCIL_PrivateData {
   int is_stroke_order_3d;
   /* Used for computing object distance to camera. */
   float camera_z_axis[3], camera_z_offset;
+  /* Pseudo depth of field parameter. Used to scale blur radius. */
+  float dof_params[2];
+  /* Used for DoF Setup. */
+  Object *camera;
 } GPENCIL_PrivateData;
 
 /* flags for fast drawing support */
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 49b6bc9996c..d2e6f899cb6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -289,11 +289,13 @@ void GPENCIL_render_to_image(void *vedata,
   GPENCIL_render_init(vedata, engine, draw_ctx->depsgraph);
 
   GPENCIL_engine_init(vedata);
-  GPENCIL_cache_init(vedata);
 
   GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
   Object *camera = DEG_get_evaluated_object(draw_ctx->depsgraph, RE_GetCamera(engine->re));
   stl->storage->camera = camera; /* save current camera */
+  stl->pd->camera = camera;      /* save current camera */
+
+  GPENCIL_cache_init(vedata);
 
   GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
   if (fbl->main) {
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index 8d50d279a81..78a2a23a2b3 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -1102,21 +1102,41 @@ static DRWShadingGroup *gpencil_vfx_pass_create(const char *name,
   return grp;
 }
 
-static void gpencil_vfx_blur(BlurShaderFxData *fx, Object *UNUSED(ob), gpIterVfxData *iter)
+static void gpencil_vfx_blur(BlurShaderFxData *fx, Object *ob, gpIterVfxData *iter)
 {
   DRWShadingGroup *grp;
 
+  float winmat[4][4], persmat[4][4];
+  float blur_size[2] = {fx->radius[0], fx->radius[1]};
+
+  if ((fx->flag & FX_BLUR_DOF_MODE) && iter->pd->camera != NULL) {
+    /* Compute circle of confusion size. */
+    float coc = (iter->pd->dof_params[0] / -w) - iter->pd->dof_params[1];
+    copy_v2_fl(blur_size, fabsf(coc));
+  }
+  else {
+    /* Modify by distance to camera and object scale. */
+    DRW_view_winmat_get(NULL, winmat, false);
+    DRW_view_persmat_get(NULL, persmat, false);
+    const float *vp_size = DRW_viewport_size_get();
+    const float w = fabsf(mul_project_m4_v3_zfac(persmat, ob->obmat[3]));
+    float world_pixel_scale = 1.0f / 2000.0f;
+    float scale = mat4_to_scale(ob->obmat);
+    float distance_factor = world_pixel_scale * scale * winmat[1][1] * vp_size[1] / w;
+    mul_v2_fl(blur_size, distance_factor);
+  }
+
   GPUShader *sh = GPENCIL_shader_fx_blur_get(&en_data);
 
   DRWState state = DRW_STATE_WRITE_COLOR;
   grp = gpencil_vfx_pass_create("Fx Blur H", state, iter, sh);
-  DRW_shgroup_uniform_vec2_copy(grp, "offset", (float[2]){fx->radius[0], 0.0f});
-  DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, fx->radius[0])));
+  DRW_shgroup_uniform_vec2_copy(grp, "offset", (float[2]){blur_size[0], 0.0f});
+  DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, blur_size[0])));
   DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
 
   grp = gpencil_vfx_pass_create("Fx Blur V", state, iter, sh);
-  DRW_shgroup_uniform_vec2_copy(grp, "offset", (float[2]){0.0f, fx->radius[1]});
-  DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, fx->radius[1])));
+  DRW_shgroup_uniform_vec2_copy(grp, "offset", (float[2]){0.0f, blur_size[1]});
+  DRW_shgroup_uniform_int_copy(grp, "sampCount", max_ii(1, min_ii(fx->samples, blur_size[1])));
   DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
 }



More information about the Bf-blender-cvs mailing list