[Bf-blender-cvs] [907e99d08df] greasepencil-refactor: GPencil: Refactor: Add other light types

Clément Foucault noreply at git.blender.org
Thu Dec 19 22:39:20 CET 2019


Commit: 907e99d08dfe900e230875cd33098887b37e0138
Author: Clément Foucault
Date:   Thu Dec 19 21:08:52 2019 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB907e99d08dfe900e230875cd33098887b37e0138

GPencil: Refactor: Add other light types

We approximate area lights using the same code used by spot lights.

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

M	source/blender/draw/engines/gpencil/gpencil_draw_data.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_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index c9bf6ff214a..b030ef3fbf1 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -232,9 +232,31 @@ void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
   }
 
   gpLight *gp_light = &lightpool->light_data[lightpool->light_used];
-  copy_v3_v3(gp_light->position, ob->obmat[3]);
+  float(*mat)[4] = (float(*)[4])gp_light->right;
+
+  if (la->type == LA_SPOT) {
+    copy_m4_m4(mat, ob->imat);
+    gp_light->type = GP_LIGHT_TYPE_SPOT;
+    gp_light->spotsize = cosf(la->spotsize * 0.5f);
+    gp_light->spotblend = (1.0f - gp_light->spotsize) * la->spotblend;
+  }
+  else if (la->type == LA_AREA) {
+    /* Simulate area lights using a spot light. */
+    normalize_m4_m4(mat, ob->obmat);
+    invert_m4(mat);
+    gp_light->type = GP_LIGHT_TYPE_SPOT;
+    gp_light->spotsize = cosf(M_PI * 0.5f);
+    gp_light->spotblend = (1.0f - gp_light->spotsize) * 1.0f;
+  }
+  else if (la->type == LA_SUN) {
+    gp_light->type = GP_LIGHT_TYPE_SUN;
+  }
+  else {
+    gp_light->type = GP_LIGHT_TYPE_POINT;
+  }
+  copy_v4_v4(gp_light->position, ob->obmat[3]);
   copy_v3_v3(gp_light->color, &la->r);
-  mul_v3_fl(gp_light->color, la->energy);
+  mul_v3_fl(gp_light->color, la->energy * M_1_PI);
 
   lightpool->light_used++;
 
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 846af2df9f4..d0556a92c1d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -91,10 +91,19 @@ typedef struct gpMaterial {
 
 /* UBO structure. Watch out for padding. Must match GLSL declaration. */
 typedef struct gpLight {
-  float color[4];
+  float color[3], type;
+  float right[3], spotsize;
+  float up[3], spotblend;
+  float forward[4];
   float position[4];
 } gpLight;
 
+/* gpLight->type */
+/* WATCH Keep in sync with GLSL declaration. */
+#define GP_LIGHT_TYPE_POINT 0.0
+#define GP_LIGHT_TYPE_SPOT 1.0
+#define GP_LIGHT_TYPE_SUN 2.0
+
 BLI_STATIC_ASSERT_ALIGN(gpMaterial, 16)
 BLI_STATIC_ASSERT_ALIGN(gpLight, 16)
 
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 206f7e34717..bf96eaab525 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl
@@ -14,13 +14,6 @@ struct gpMaterial {
   /* Please ensure 16 byte alignment (multiple of vec4). */
 };
 
-/* Must match C declaration. */
-struct gpLight {
-  vec4 color;
-  vec4 position;
-  /* Please ensure 16 byte alignment (multiple of vec4). */
-};
-
 /* flag */
 #define GP_STROKE_ALIGNMENT_STROKE 1
 #define GP_STROKE_ALIGNMENT_OBJECT 2
@@ -42,6 +35,23 @@ struct gpLight {
 
 #define GP_FLAG_TEST(flag, val) (((flag) & (val)) != 0)
 
+/* Must match C declaration. */
+struct gpLight {
+  vec4 color_type;
+  vec4 right;
+  vec4 up;
+  vec4 forward;
+  vec4 position;
+  /* Please ensure 16 byte alignment (multiple of vec4). */
+};
+
+#define spot_size right.w
+#define spot_blend up.w
+
+#define GP_LIGHT_TYPE_POINT 0.0
+#define GP_LIGHT_TYPE_SPOT 1.0
+#define GP_LIGHT_TYPE_SUN 2.0
+
 #ifdef GPENCIL_MATERIAL_BUFFER_LEN
 
 layout(std140) uniform gpMaterialBlock
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
index 9fc81c07c22..e57b6522527 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_frag.glsl
@@ -25,16 +25,30 @@ float length_squared(vec3 v)
 vec3 gpencil_lighting(void)
 {
   vec3 light_accum = vec3(0.0);
-
   for (int i = 0; i < GPENCIL_LIGHT_BUFFER_LEN; i++) {
-    if (lights[i].color.x == -1.0) {
+    if (lights[i].color_type.x == -1.0) {
       break;
     }
-    float len_sqr = length_squared(lights[i].position.xyz - finalPos);
-    light_accum += lights[i].color.rgb / len_sqr;
+    vec3 L = lights[i].position.xyz - finalPos;
+    float vis = 1.0;
+    /* Spot Attenuation. */
+    if (lights[i].color_type.w == GP_LIGHT_TYPE_SPOT) {
+      mat3 rot_scale = mat3(lights[i].right.xyz, lights[i].up.xyz, lights[i].forward.xyz);
+      vec3 local_L = rot_scale * L;
+      local_L /= abs(local_L.z);
+      float ellipse = inversesqrt(length_squared(local_L));
+      vis *= smoothstep(0.0, 1.0, (ellipse - lights[i].spot_size) / lights[i].spot_blend);
+      /* Also mask +Z cone. */
+      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);
+    }
+    light_accum += vis * lights[i].color_type.rgb;
   }
-
-  return light_accum;
+  /* Clamp to avoid NaNs. */
+  return clamp(light_accum, 0.0, 1e10);
 }
 
 void main()



More information about the Bf-blender-cvs mailing list