[Bf-blender-cvs] [4286b5d4246] greasepencil-object: Fix problems with VFX light modifer

Antonio Vazquez noreply at git.blender.org
Fri Dec 8 19:24:45 CET 2017


Commit: 4286b5d424686d393dd11aae2bb9c66c9ed7a03c
Author: Antonio Vazquez
Date:   Fri Dec 8 19:12:29 2017 +0100
Branches: greasepencil-object
https://developer.blender.org/rB4286b5d424686d393dd11aae2bb9c66c9ed7a03c

Fix problems with VFX light modifer

There was a problem with the conversion of coordinate system between screen space a camera space.

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

M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/draw/engines/gpencil/gpencil_vfx.c
M	source/blender/draw/engines/gpencil/shaders/gpencil_light_frag.glsl
M	source/blender/modifiers/intern/MOD_gpencillight.c

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

diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 13520e3f62b..5fb5202176d 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -103,7 +103,7 @@ typedef struct GPencilVFXFlip {
 } GPencilVFXFlip;
 
 typedef struct GPencilVFXLight {
-	float loc[3];
+	float loc[4];
 	float wsize[2];
 	float energy;
 	float ambient;
diff --git a/source/blender/draw/engines/gpencil/gpencil_vfx.c b/source/blender/draw/engines/gpencil/gpencil_vfx.c
index 1ff91c119e5..b54402eb3f8 100644
--- a/source/blender/draw/engines/gpencil/gpencil_vfx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_vfx.c
@@ -25,6 +25,7 @@
 
 #include "BKE_modifier.h"
 #include "BKE_global.h"
+#include "BKE_gpencil.h"
 
 #include "DRW_engine.h"
 #include "DRW_render.h"
@@ -385,6 +386,34 @@ static void DRW_gpencil_vfx_flip(
 	cache->end_vfx_flip_sh = vfx_shgrp;
 }
 
+/* get normal of draw using one stroke of visible layer 
+ * /param gpd        GP datablock
+ * /param r_point    Point on plane
+ * /param r_normal   Normal vector
+ */
+static bool get_normal_vector(bGPdata *gpd, float r_point[3], float r_normal[3])
+{
+	for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+		if (gpl->flag & GP_LAYER_HIDE)
+			continue;
+
+		/* get frame  */
+		bGPDframe *gpf = gpl->actframe;
+		if (gpf == NULL)
+			continue;
+		for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) {
+			if (gps->totpoints >= 3) {
+				bGPDspoint *pt = &gps->points[0];
+				BKE_gpencil_stroke_normal(gps, r_normal);
+				copy_v3_v3(r_point, &pt->x);
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 /* Light VFX */
 static void DRW_gpencil_vfx_light(
 	ModifierData *md, int ob_idx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
@@ -418,7 +447,22 @@ static void DRW_gpencil_vfx_light(
 
 	/* location of the light using obj location as origin */
 	copy_v3_v3(stl->vfx[ob_idx].vfx_light.loc, &mmd->object->loc[0]);
-	DRW_shgroup_uniform_vec3(vfx_shgrp, "loc", stl->vfx[ob_idx].vfx_light.loc, 1);
+
+	/* Calc distance to strokes plane 
+	 * The w component of location is used to transfer the distance to drawing plane
+	 */
+	float r_point[3], r_normal[3];
+	float r_plane[4];
+	bGPdata *gpd = (bGPdata *)ob->data;
+	if (!get_normal_vector(gpd, r_point, r_normal)) {
+		return;
+	}
+	mul_mat3_m4_v3(ob->obmat, r_normal); /* only rotation component */
+	plane_from_point_normal_v3(r_plane, r_point, r_normal);
+	float dt = dist_to_plane_v3(mmd->object->loc, r_plane);
+	stl->vfx[ob_idx].vfx_light.loc[3] = dt;
+
+	DRW_shgroup_uniform_vec4(vfx_shgrp, "loc", stl->vfx[ob_idx].vfx_light.loc, 1);
 
 	stl->vfx[ob_idx].vfx_light.energy = mmd->energy;
 	DRW_shgroup_uniform_float(vfx_shgrp, "energy", &stl->vfx[ob_idx].vfx_light.energy, 1);
@@ -426,6 +470,10 @@ static void DRW_gpencil_vfx_light(
 	stl->vfx[ob_idx].vfx_light.ambient = mmd->ambient;
 	DRW_shgroup_uniform_float(vfx_shgrp, "ambient", &stl->vfx[ob_idx].vfx_light.ambient, 1);
 
+	DRW_shgroup_uniform_float(vfx_shgrp, "pixsize", DRW_viewport_pixelsize_get(), 1);
+	DRW_shgroup_uniform_float(vfx_shgrp, "pixelsize", &U.pixelsize, 1);
+	DRW_shgroup_uniform_int(vfx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+
 	/* set first effect sh */
 	if (cache->init_vfx_light_sh == NULL) {
 		cache->init_vfx_light_sh = vfx_shgrp;
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_light_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_light_frag.glsl
index badb689b4ca..487f5648769 100644
--- a/source/blender/draw/engines/gpencil/shaders/gpencil_light_frag.glsl
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_light_frag.glsl
@@ -4,18 +4,23 @@ uniform mat4 ViewMatrix;
 uniform sampler2D strokeColor;
 uniform sampler2D strokeDepth;
 uniform vec2 Viewport;
-uniform vec3 loc;
+uniform vec4 loc;
 uniform float energy;
 uniform float ambient;
 
+uniform float pixsize;   /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform int pixfactor;
+
 out vec4 FragColor;
 
+float defaultpixsize = pixsize * pixelsize * float(pixfactor);
+
 /* project 3d point to 2d on screen space */
 vec2 toScreenSpace(vec4 vertex)
 {
-	vec3 ndc = vec3(vertex.x / vertex.w, 
-					vertex.y / vertex.w,
-					vertex.z / vertex.w);
+	/* need to calculate ndc because this is not done by vertex shader */
+	vec3 ndc = vec3(vertex).xyz / vertex.w;
 					
 	vec2 sc;
 	sc.x = ((ndc.x + 1.0) / 2.0) * Viewport.x;
@@ -28,10 +33,19 @@ void main()
 {
 	float stroke_depth;
 	vec4 objcolor;
-
-	vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc, 1.0); 
+	
+	vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0); 
 	vec2 light2d = toScreenSpace(light_loc);
-	vec3 light3d = vec3(light2d.x, light2d.y, 10.0); 
+
+	/* calc pixel scale */
+	float pxscale = (ProjectionMatrix[3][3] == 0.0) ? (10.0 / (light_loc.z * defaultpixsize)) : (10.0 / defaultpixsize);
+	pxscale = max(pxscale, 0.000001);
+
+	/* the height over plane is received in the w component of the loc 
+	 * and needs a factor to adapt to pixels
+	 */
+	float peak = loc.w * 10.0 * pxscale;
+	vec3 light3d = vec3(light2d.x, light2d.y, peak); 
 	
 	vec2 uv = vec2(gl_FragCoord.xy);
 	vec3 frag_loc = vec3(uv.x, uv.y, 0);
@@ -44,10 +58,10 @@ void main()
 	/* diffuse light */
 	vec3 lightdir = normalize(light3d - frag_loc);
 	float diff = max(dot(norm, lightdir), 0.0);
-	float dist  = length(light3d - frag_loc);
+	float dist  = length(light3d - frag_loc) / pxscale;
 	float factor = diff * (energy / (dist * dist));	
 	
-    vec3 result = factor * ambient * vec3(objcolor);
+    vec3 result = factor * max(ambient, 0.1) * vec3(objcolor);
 	
 	gl_FragDepth = stroke_depth;
 	FragColor = vec4(result.r, result.g, result.b, objcolor.a);
diff --git a/source/blender/modifiers/intern/MOD_gpencillight.c b/source/blender/modifiers/intern/MOD_gpencillight.c
index 434ef4a3793..008182947ab 100644
--- a/source/blender/modifiers/intern/MOD_gpencillight.c
+++ b/source/blender/modifiers/intern/MOD_gpencillight.c
@@ -48,8 +48,8 @@ static void initData(ModifierData *md)
 {
 	GpencilLightModifierData *gpmd = (GpencilLightModifierData *)md;
 	ARRAY_SET_ITEMS(gpmd->loc, 0.0f, 0.0f, 2.0f);
-	gpmd->energy = 600.0f;
-	gpmd->ambient = 100.0f;
+	gpmd->energy = 1000.0f;
+	gpmd->ambient = 5.0f;
 	gpmd->object = NULL;
 }



More information about the Bf-blender-cvs mailing list