[Bf-blender-cvs] [685c94eacb3] greasepencil-refactor: GPencil: Refactor: Use normal approximation for lighting

Clément Foucault noreply at git.blender.org
Sat Dec 21 01:21:48 CET 2019


Commit: 685c94eacb3453758066759ea8aab32956c11c5b
Author: Clément Foucault
Date:   Sat Dec 21 01:18:04 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB685c94eacb3453758066759ea8aab32956c11c5b

GPencil: Refactor: Use normal approximation for lighting

We compute the normal using the bounding box size and the view vector to
the center of the bounding box. We then scale the normal w.r.t. the BBox
size and transform it back to world space. This gives us a flat normal
for objects without depth and a rotating normal for object that are
not.

This will also be used for correct depth mixing.

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

M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_draw_data.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
M	source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 22a235ddfb4..ad67168dd25 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -53,6 +53,42 @@ GPENCIL_tObject *gpencil_object_cache_add_new(GPENCIL_PrivateData *pd, Object *o
   tgp_ob->camera_z = dot_v3v3(pd->camera_z_axis, ob->obmat[3]);
   tgp_ob->is_drawmode3d = (gpd->draw_mode == GP_DRAWMODE_3D);
 
+  /* Find the normal most likely to represent the gpObject. */
+  /* TODO: This does not work quite well if you use
+   * strokes not aligned with the object axes. Maybe we could try to
+   * compute the minimum axis of all strokes. But this would be more
+   * computationaly heavy and should go into the GPData evaluation. */
+  BoundBox *bbox = BKE_object_boundbox_get(ob);
+  /* Convert bbox to matrix */
+  float mat[4][4], size[3], center[3];
+  BKE_boundbox_calc_size_aabb(bbox, size);
+  BKE_boundbox_calc_center_aabb(bbox, center);
+  unit_m4(mat);
+  copy_v3_v3(mat[3], center);
+  /* Avoid division by 0.0 later. */
+  add_v3_fl(size, 1e-8f);
+  rescale_m4(mat, size);
+  /* BBox space to World. */
+  mul_m4_m4m4(mat, ob->obmat, mat);
+  if (DRW_view_is_persp_get(NULL)) {
+    /* BBox center to camera vector. */
+    sub_v3_v3v3(tgp_ob->plane_normal, pd->camera_pos, mat[3]);
+  }
+  else {
+    copy_v3_v3(tgp_ob->plane_normal, pd->camera_z_axis);
+  }
+  /* World to BBox space. */
+  invert_m4(mat);
+  /* Normalize the vector in BBox space. */
+  mul_mat3_m4_v3(mat, tgp_ob->plane_normal);
+  normalize_v3(tgp_ob->plane_normal);
+
+  transpose_m4(mat);
+  /* mat is now a "normal" matrix which will transform
+   * BBox space normal to world space.  */
+  mul_mat3_m4_v3(mat, tgp_ob->plane_normal);
+  normalize_v3(tgp_ob->plane_normal);
+
   BLI_LINKS_APPEND(&pd->tobjects, tgp_ob);
 
   return tgp_ob;
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index e4d45d7ad21..a236c05128d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -229,7 +229,7 @@ void gpencil_light_ambient_add(GPENCIL_LightPool *lightpool, const float color[3
   }
 
   gpLight *gp_light = &lightpool->light_data[lightpool->light_used];
-  gp_light->type = GP_LIGHT_TYPE_SUN;
+  gp_light->type = GP_LIGHT_TYPE_AMBIENT;
   copy_v3_v3(gp_light->color, color);
   lightpool->light_used++;
 
@@ -265,6 +265,7 @@ void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
     gp_light->spotblend = (1.0f - gp_light->spotsize) * 1.0f;
   }
   else if (la->type == LA_SUN) {
+    copy_v4_v4(gp_light->forward, ob->obmat[2]);
     gp_light->type = GP_LIGHT_TYPE_SUN;
   }
   else {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 5c29ba085a9..c4ee154904d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -897,6 +897,7 @@ static void gp_layer_cache_populate(bGPDlayer *gpl,
   DRW_shgroup_uniform_vec4_copy(iter->grp, "gpModelMatrix[1]", iter->ob->obmat[1]);
   DRW_shgroup_uniform_vec4_copy(iter->grp, "gpModelMatrix[2]", iter->ob->obmat[2]);
   DRW_shgroup_uniform_vec4_copy(iter->grp, "gpModelMatrix[3]", iter->ob->obmat[3]);
+  DRW_shgroup_uniform_vec3_copy(iter->grp, "gpNormal", iter->tgp_ob->plane_normal);
   DRW_shgroup_uniform_vec2_copy(iter->grp, "sizeViewportInv", DRW_viewport_invert_size_get());
   DRW_shgroup_uniform_vec2_copy(iter->grp, "sizeViewport", DRW_viewport_size_get());
   DRW_shgroup_uniform_float_copy(iter->grp, "thicknessScale", object_scale);
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 6df23de8dd6..bdf4b4db906 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -103,6 +103,7 @@ typedef struct gpLight {
 #define GP_LIGHT_TYPE_POINT 0.0
 #define GP_LIGHT_TYPE_SPOT 1.0
 #define GP_LIGHT_TYPE_SUN 2.0
+#define GP_LIGHT_TYPE_AMBIENT 3.0
 
 BLI_STATIC_ASSERT_ALIGN(gpMaterial, 16)
 BLI_STATIC_ASSERT_ALIGN(gpLight, 16)
@@ -233,6 +234,8 @@ typedef struct GPENCIL_tObject {
 
   /* Distance to camera. Used for sorting. */
   float camera_z;
+  /* Normal used for shading. Based on view angle. */
+  float plane_normal[3];
 
   bool is_drawmode3d;
 } GPENCIL_tObject;
@@ -480,6 +483,7 @@ typedef struct GPENCIL_PrivateData {
   int is_stroke_order_3d;
   /* Used for computing object distance to camera. */
   float camera_z_axis[3], camera_z_offset;
+  float camera_pos[3];
   /* Pseudo depth of field parameter. Used to scale blur radius. */
   float dof_params[2];
   /* Used for DoF Setup. */
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
index bf96eaab525..4981f4f7f56 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -51,6 +51,7 @@ struct gpLight {
 #define GP_LIGHT_TYPE_POINT 0.0
 #define GP_LIGHT_TYPE_SPOT 1.0
 #define GP_LIGHT_TYPE_SUN 2.0
+#define GP_LIGHT_TYPE_AMBIENT 3.0
 
 #ifdef GPENCIL_MATERIAL_BUFFER_LEN
 
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
index 034a2132052..8b5371164ee 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
@@ -2,6 +2,7 @@
 uniform sampler2D gpFillTexture;
 uniform sampler2D gpStrokeTexture;
 uniform sampler2D gpSceneDepthTexture;
+uniform vec3 gpNormal;
 
 in vec4 finalColorMul;
 in vec4 finalColorAdd;
@@ -42,8 +43,18 @@ vec3 gpencil_lighting(void)
       vis *= step(0.0, local_L.z);
     }
     /* Inverse square decay. Skip for suns. */
-    if (lights[i].color_type.w != GP_LIGHT_TYPE_SUN) {
-      vis /= length_squared(L);
+    float L_len_sqr = length_squared(L);
+    if (lights[i].color_type.w < GP_LIGHT_TYPE_SUN) {
+      vis /= L_len_sqr;
+    }
+    else {
+      L = lights[i].forward.xyz;
+      L_len_sqr = 1.0;
+    }
+    /* Lambertian falloff */
+    if (lights[i].color_type.w != GP_LIGHT_TYPE_AMBIENT) {
+      L /= sqrt(L_len_sqr);
+      vis *= clamp(dot(gpNormal, L), 0.0, 1.0);
     }
     light_accum += vis * lights[i].color_type.rgb;
   }



More information about the Bf-blender-cvs mailing list