[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