GP: implement Shadow FX (wip)
Initial implementation of effect to create a drop shadow of the strokes
This commit is contained in:
parent
d9f6fdae4b
commit
f1afa6f6a7
|
@ -100,6 +100,28 @@ class DATA_PT_shader_fx(ShaderFxButtonsPanel, Panel):
|
|||
layout.prop(fx, "blur")
|
||||
layout.prop(fx, "samples")
|
||||
|
||||
def FX_SHADOW(self, layout, fx):
|
||||
layout.prop(fx, "offset", text="Offset")
|
||||
|
||||
layout.prop(fx, "shadow_color")
|
||||
layout.prop(fx, "scale")
|
||||
layout.prop(fx, "rotation")
|
||||
|
||||
layout.separator()
|
||||
layout.prop(fx, "use_object", text="Use object as pivot")
|
||||
if fx.use_object:
|
||||
row = layout.row()
|
||||
row.prop(fx, "object", text="Object")
|
||||
|
||||
layout.separator()
|
||||
layout.prop(fx, "use_wave", text="Use Wave effect")
|
||||
if fx.use_wave is True:
|
||||
row = layout.row(align=True)
|
||||
row.prop(fx, "orientation", expand=True)
|
||||
layout.prop(fx, "amplitude")
|
||||
layout.prop(fx, "period")
|
||||
layout.prop(fx, "phase")
|
||||
|
||||
def FX_SWIRL(self, layout, fx):
|
||||
layout.prop(fx, "object", text="Object")
|
||||
|
||||
|
|
|
@ -340,6 +340,8 @@ data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl SRC)
|
|||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_shadow_prepare_frag.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_shadow_resolve_frag.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl SRC)
|
||||
data_to_c_simple(engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl SRC)
|
||||
|
||||
|
|
|
@ -141,17 +141,17 @@ static void GPENCIL_create_framebuffers(void *vedata)
|
|||
GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_b)
|
||||
});
|
||||
|
||||
/* used for rim FX effect */
|
||||
e_data.temp_depth_tx_rim = DRW_texture_pool_query_2D(
|
||||
/* used for rim and shadow FX effects */
|
||||
e_data.temp_depth_tx_fx = DRW_texture_pool_query_2D(
|
||||
size[0], size[1], GPU_DEPTH24_STENCIL8,
|
||||
&draw_engine_gpencil_type);
|
||||
e_data.temp_color_tx_rim = DRW_texture_pool_query_2D(
|
||||
e_data.temp_color_tx_fx = DRW_texture_pool_query_2D(
|
||||
size[0], size[1], fb_format,
|
||||
&draw_engine_gpencil_type);
|
||||
GPU_framebuffer_ensure_config(
|
||||
&fbl->temp_fb_rim, {
|
||||
GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_rim),
|
||||
GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_rim),
|
||||
&fbl->temp_fb_fx, {
|
||||
GPU_ATTACHMENT_TEXTURE(e_data.temp_depth_tx_fx),
|
||||
GPU_ATTACHMENT_TEXTURE(e_data.temp_color_tx_fx),
|
||||
});
|
||||
|
||||
/* background framebuffer to speed up drawing process (always 16 bits) */
|
||||
|
|
|
@ -72,6 +72,7 @@ typedef struct tGPencilObjectCache {
|
|||
DRWShadingGroup *fx_colorize_sh;
|
||||
DRWShadingGroup *fx_pixel_sh;
|
||||
DRWShadingGroup *fx_rim_sh;
|
||||
DRWShadingGroup *fx_shadow_sh;
|
||||
DRWShadingGroup *fx_swirl_sh;
|
||||
DRWShadingGroup *fx_flip_sh;
|
||||
DRWShadingGroup *fx_light_sh;
|
||||
|
@ -160,7 +161,7 @@ typedef struct GPENCIL_FramebufferList {
|
|||
struct GPUFrameBuffer *main;
|
||||
struct GPUFrameBuffer *temp_fb_a;
|
||||
struct GPUFrameBuffer *temp_fb_b;
|
||||
struct GPUFrameBuffer *temp_fb_rim;
|
||||
struct GPUFrameBuffer *temp_fb_fx;
|
||||
struct GPUFrameBuffer *background_fb;
|
||||
|
||||
struct GPUFrameBuffer *multisample_fb;
|
||||
|
@ -234,6 +235,8 @@ typedef struct GPENCIL_e_data {
|
|||
struct GPUShader *gpencil_fx_pixel_sh;
|
||||
struct GPUShader *gpencil_fx_rim_prepare_sh;
|
||||
struct GPUShader *gpencil_fx_rim_resolve_sh;
|
||||
struct GPUShader *gpencil_fx_shadow_prepare_sh;
|
||||
struct GPUShader *gpencil_fx_shadow_resolve_sh;
|
||||
struct GPUShader *gpencil_fx_swirl_sh;
|
||||
struct GPUShader *gpencil_fx_wave_sh;
|
||||
|
||||
|
@ -254,8 +257,8 @@ typedef struct GPENCIL_e_data {
|
|||
struct GPUTexture *temp_color_tx_b;
|
||||
struct GPUTexture *temp_depth_tx_b;
|
||||
|
||||
struct GPUTexture *temp_color_tx_rim;
|
||||
struct GPUTexture *temp_depth_tx_rim;
|
||||
struct GPUTexture *temp_color_tx_fx;
|
||||
struct GPUTexture *temp_depth_tx_fx;
|
||||
|
||||
/* for buffer only one batch is nedeed because the drawing is only of one stroke */
|
||||
GPUBatch *batch_buffer_stroke;
|
||||
|
|
|
@ -48,6 +48,8 @@ extern char datatoc_gpencil_fx_light_frag_glsl[];
|
|||
extern char datatoc_gpencil_fx_pixel_frag_glsl[];
|
||||
extern char datatoc_gpencil_fx_rim_prepare_frag_glsl[];
|
||||
extern char datatoc_gpencil_fx_rim_resolve_frag_glsl[];
|
||||
extern char datatoc_gpencil_fx_shadow_prepare_frag_glsl[];
|
||||
extern char datatoc_gpencil_fx_shadow_resolve_frag_glsl[];
|
||||
extern char datatoc_gpencil_fx_swirl_frag_glsl[];
|
||||
extern char datatoc_gpencil_fx_wave_frag_glsl[];
|
||||
|
||||
|
@ -407,8 +409,8 @@ static void DRW_gpencil_fx_rim(
|
|||
e_data->gpencil_fx_blur_sh,
|
||||
psl->fx_shader_pass_blend);
|
||||
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_rim);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_rim);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_fx);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_fx);
|
||||
DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
|
||||
|
||||
DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
|
||||
|
@ -425,13 +427,82 @@ static void DRW_gpencil_fx_rim(
|
|||
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_rim);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeRim", &e_data->temp_color_tx_fx);
|
||||
DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
|
||||
DRW_shgroup_uniform_int(fx_shgrp, "mode", &fxd->mode, 1);
|
||||
|
||||
fxd->runtime.fx_sh_c = fx_shgrp;
|
||||
}
|
||||
|
||||
/* Shadow FX */
|
||||
static void DRW_gpencil_fx_shadow(
|
||||
ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
|
||||
tGPencilObjectCache *cache)
|
||||
{
|
||||
if (fx == NULL) {
|
||||
return;
|
||||
}
|
||||
ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
|
||||
if ((!fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
|
||||
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
|
||||
DRWShadingGroup *fx_shgrp;
|
||||
|
||||
struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
|
||||
/* prepare pass */
|
||||
fx_shgrp = DRW_shgroup_create(
|
||||
e_data->gpencil_fx_shadow_prepare_sh,
|
||||
psl->fx_shader_pass_blend);
|
||||
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
|
||||
DRW_shgroup_uniform_vec2(fx_shgrp, "Viewport", DRW_viewport_size_get(), 1);
|
||||
|
||||
DRW_shgroup_uniform_int(fx_shgrp, "offset", &fxd->offset[0], 2);
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "scale", &fxd->scale[0], 2);
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "rotation", &fxd->rotation, 1);
|
||||
DRW_shgroup_uniform_vec4(fx_shgrp, "shadow_color", &fxd->shadow_rgba[0], 1);
|
||||
|
||||
if ((fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT)) {
|
||||
DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &fxd->object->loc[0], 1);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
|
||||
}
|
||||
|
||||
const int nowave = -1;
|
||||
if (fxd->flag & FX_SHADOW_USE_WAVE) {
|
||||
DRW_shgroup_uniform_int(fx_shgrp, "orientation", &fxd->orientation, 1);
|
||||
}
|
||||
else {
|
||||
DRW_shgroup_uniform_int(fx_shgrp, "orientation", &nowave, 1);
|
||||
}
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "amplitude", &fxd->amplitude, 1);
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "period", &fxd->period, 1);
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "phase", &fxd->phase, 1);
|
||||
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
|
||||
DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
|
||||
|
||||
fxd->runtime.fx_sh = fx_shgrp;
|
||||
|
||||
/* resolve pass */
|
||||
fx_shgrp = DRW_shgroup_create(
|
||||
e_data->gpencil_fx_shadow_resolve_sh,
|
||||
psl->fx_shader_pass_blend);
|
||||
DRW_shgroup_call_add(fx_shgrp, fxquad, NULL);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeColor", &e_data->temp_color_tx_a);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowColor", &e_data->temp_color_tx_fx);
|
||||
DRW_shgroup_uniform_texture_ref(fx_shgrp, "shadowDepth", &e_data->temp_depth_tx_fx);
|
||||
|
||||
fxd->runtime.fx_sh_b = fx_shgrp;
|
||||
}
|
||||
|
||||
/* Swirl FX */
|
||||
static void DRW_gpencil_fx_swirl(
|
||||
ShaderFxData *fx, GPENCIL_e_data *e_data, GPENCIL_Data *vedata,
|
||||
|
@ -531,6 +602,13 @@ void GPENCIL_create_fx_shaders(GPENCIL_e_data *e_data)
|
|||
e_data->gpencil_fx_rim_resolve_sh = DRW_shader_create_fullscreen(
|
||||
datatoc_gpencil_fx_rim_resolve_frag_glsl, NULL);
|
||||
}
|
||||
if (!e_data->gpencil_fx_shadow_prepare_sh) {
|
||||
e_data->gpencil_fx_shadow_prepare_sh = DRW_shader_create_fullscreen(
|
||||
datatoc_gpencil_fx_shadow_prepare_frag_glsl, NULL);
|
||||
|
||||
e_data->gpencil_fx_shadow_resolve_sh = DRW_shader_create_fullscreen(
|
||||
datatoc_gpencil_fx_shadow_resolve_frag_glsl, NULL);
|
||||
}
|
||||
if (!e_data->gpencil_fx_swirl_sh) {
|
||||
e_data->gpencil_fx_swirl_sh = DRW_shader_create_fullscreen(
|
||||
datatoc_gpencil_fx_swirl_frag_glsl, NULL);
|
||||
|
@ -551,6 +629,8 @@ void GPENCIL_delete_fx_shaders(GPENCIL_e_data *e_data)
|
|||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_pixel_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_prepare_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_rim_resolve_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_prepare_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_shadow_resolve_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_swirl_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data->gpencil_fx_wave_sh);
|
||||
}
|
||||
|
@ -602,6 +682,9 @@ void DRW_gpencil_fx_prepare(
|
|||
case eShaderFxType_Rim:
|
||||
DRW_gpencil_fx_rim(fx, e_data, vedata, cache);
|
||||
break;
|
||||
case eShaderFxType_Shadow:
|
||||
DRW_gpencil_fx_shadow(fx, e_data, vedata, cache);
|
||||
break;
|
||||
case eShaderFxType_Swirl:
|
||||
DRW_gpencil_fx_swirl(fx, e_data, vedata, cache);
|
||||
break;
|
||||
|
@ -706,8 +789,8 @@ static void draw_gpencil_rim_blur(
|
|||
fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b);
|
||||
|
||||
/* copy pass from b for ping-pong frame buffers */
|
||||
GPU_framebuffer_bind(fbl->temp_fb_rim);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_rim, clearcol, 1.0f);
|
||||
GPU_framebuffer_bind(fbl->temp_fb_fx);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
|
||||
DRW_draw_pass(psl->mix_pass_noblend);
|
||||
}
|
||||
|
||||
|
@ -729,8 +812,8 @@ static void draw_gpencil_rim_passes(
|
|||
int by = fxd->blur[1];
|
||||
|
||||
/* prepare mask */
|
||||
GPU_framebuffer_bind(fbl->temp_fb_rim);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_rim, clearcol, 1.0f);
|
||||
GPU_framebuffer_bind(fbl->temp_fb_fx);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
|
||||
DRW_draw_pass_subset(
|
||||
psl->fx_shader_pass_blend,
|
||||
fxd->runtime.fx_sh, fxd->runtime.fx_sh);
|
||||
|
@ -772,6 +855,44 @@ static void draw_gpencil_rim_passes(
|
|||
DRW_draw_pass(psl->mix_pass_noblend);
|
||||
}
|
||||
|
||||
/* helper to draw SHADOW passes */
|
||||
static void draw_gpencil_shadow_passes(
|
||||
struct GPENCIL_e_data *e_data,
|
||||
struct GPENCIL_Data *vedata,
|
||||
struct ShadowShaderFxData *fxd)
|
||||
{
|
||||
if (fxd->runtime.fx_sh_b == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
|
||||
GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
|
||||
|
||||
static float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
/* prepare shadow */
|
||||
GPU_framebuffer_bind(fbl->temp_fb_fx);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_fx, clearcol, 1.0f);
|
||||
DRW_draw_pass_subset(
|
||||
psl->fx_shader_pass_blend,
|
||||
fxd->runtime.fx_sh, fxd->runtime.fx_sh);
|
||||
|
||||
/* resolve */
|
||||
GPU_framebuffer_bind(fbl->temp_fb_b);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_b, clearcol, 1.0f);
|
||||
DRW_draw_pass_subset(
|
||||
psl->fx_shader_pass_blend,
|
||||
fxd->runtime.fx_sh_b, fxd->runtime.fx_sh_b);
|
||||
|
||||
/* copy pass from b to a for ping-pong frame buffers */
|
||||
e_data->input_depth_tx = e_data->temp_depth_tx_b;
|
||||
e_data->input_color_tx = e_data->temp_color_tx_b;
|
||||
|
||||
GPU_framebuffer_bind(fbl->temp_fb_a);
|
||||
GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
|
||||
DRW_draw_pass(psl->mix_pass_noblend);
|
||||
}
|
||||
|
||||
/* apply all object fx effects */
|
||||
void DRW_gpencil_fx_draw(
|
||||
struct GPENCIL_e_data *e_data,
|
||||
|
@ -822,6 +943,12 @@ void DRW_gpencil_fx_draw(
|
|||
draw_gpencil_rim_passes(e_data, vedata, fxd);
|
||||
break;
|
||||
}
|
||||
case eShaderFxType_Shadow:
|
||||
{
|
||||
ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
|
||||
draw_gpencil_shadow_passes(e_data, vedata, fxd);
|
||||
break;
|
||||
}
|
||||
case eShaderFxType_Swirl:
|
||||
{
|
||||
SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
|
||||
/* ******************************************************************* */
|
||||
/* create shadow */
|
||||
/* ******************************************************************* */
|
||||
uniform sampler2D strokeColor;
|
||||
uniform sampler2D strokeDepth;
|
||||
uniform vec2 Viewport;
|
||||
|
||||
uniform int offset[2];
|
||||
uniform float scale[2];
|
||||
uniform float rotation;
|
||||
uniform vec4 shadow_color;
|
||||
|
||||
uniform float amplitude;
|
||||
uniform float period;
|
||||
uniform float phase;
|
||||
uniform int orientation;
|
||||
|
||||
uniform vec3 loc;
|
||||
uniform float pixsize; /* rv3d->pixsize */
|
||||
uniform float pixelsize; /* U.pixelsize */
|
||||
uniform float pixfactor;
|
||||
|
||||
#define M_PI 3.1415926535897932384626433832795
|
||||
|
||||
#define HORIZONTAL 0
|
||||
#define VERTICAL 1
|
||||
|
||||
float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
|
||||
vec2 noffset = vec2(offset[0], offset[1]);
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
/* project 3d point to 2d on screen space */
|
||||
vec2 toScreenSpace(vec4 vertex)
|
||||
{
|
||||
/* 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;
|
||||
sc.y = ((ndc.y + 1.0) / 2.0) * Viewport.y;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = vec2(gl_FragCoord.xy);
|
||||
vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
|
||||
vec2 loc2d = toScreenSpace(nloc);
|
||||
|
||||
float dx = (ProjectionMatrix[3][3] == 0.0) ? (noffset[0] / (nloc.z * defaultpixsize)) : (noffset[0] / defaultpixsize);
|
||||
float dy = (ProjectionMatrix[3][3] == 0.0) ? (noffset[1] / (nloc.z * defaultpixsize)) : (noffset[1] / defaultpixsize);
|
||||
|
||||
/* move point to new coords system */
|
||||
vec2 tpos = vec2(uv.x, uv.y) - loc2d;
|
||||
|
||||
/* apply offset */
|
||||
tpos = vec2(tpos.x - dx, tpos.y - dy);
|
||||
|
||||
/* apply scale */
|
||||
tpos.x *= 1.0 / scale[0];
|
||||
tpos.y *= 1.0 / scale[1];
|
||||
|
||||
/* rotation */
|
||||
tpos.x = (tpos.x * cos(rotation)) - (tpos.y * sin(rotation));
|
||||
tpos.y = (tpos.x * sin(rotation)) + (tpos.y * cos(rotation));
|
||||
|
||||
/* back to original coords system */
|
||||
vec2 texpos = tpos + loc2d;
|
||||
|
||||
/* wave */
|
||||
float value;
|
||||
if (orientation == HORIZONTAL) {
|
||||
float pval = (uv.x * M_PI) / Viewport[0];
|
||||
value = amplitude * sin((period * pval) + phase);
|
||||
texpos.y += value;
|
||||
}
|
||||
else if (orientation == VERTICAL){
|
||||
float pval = (uv.y * M_PI) / Viewport[1];
|
||||
value = amplitude * sin((period * pval) + phase);
|
||||
texpos.x += value;
|
||||
}
|
||||
|
||||
float stroke_depth = texelFetch(strokeDepth, ivec2(texpos.x, texpos.y), 0).r;
|
||||
vec4 src_pixel= texelFetch(strokeColor, ivec2(texpos.x, texpos.y), 0);
|
||||
vec4 outcolor;
|
||||
outcolor = shadow_color;
|
||||
|
||||
/* is transparent */
|
||||
if (src_pixel.a == 0.0f) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// /* check inside viewport */
|
||||
// else if ((uv.x - dx < 0) || (uv.x - dx > Viewport[0])) {
|
||||
// discard;
|
||||
// }
|
||||
// else if ((uv.y - dy < 0) || (uv.y - dy > Viewport[1])) {
|
||||
// discard;
|
||||
// }
|
||||
// /* pixel is equal to mask color, keep */
|
||||
// else if (src_pixel.rgb == mask_color.rgb) {
|
||||
// discard;
|
||||
// }
|
||||
// else {
|
||||
// if ((src_pixel.a > 0) && (offset_pixel.a > 0)) {
|
||||
// discard;
|
||||
// }
|
||||
// else {
|
||||
// outcolor = vec4(rim_color, 1.0);
|
||||
// }
|
||||
// }
|
||||
|
||||
gl_FragDepth = stroke_depth;
|
||||
FragColor = outcolor;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/* ******************************************************************* */
|
||||
/* Resolve Shadow pass */
|
||||
/* ******************************************************************* */
|
||||
uniform sampler2D strokeColor;
|
||||
uniform sampler2D strokeDepth;
|
||||
uniform sampler2D shadowColor;
|
||||
uniform sampler2D shadowDepth;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 uv = ivec2(gl_FragCoord.xy);
|
||||
|
||||
float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
|
||||
float shadow_depth = texelFetch(shadowDepth, uv.xy, 0).r;
|
||||
vec4 stroke_pixel= texelFetch(strokeColor, uv.xy, 0);
|
||||
vec4 shadow_pixel= texelFetch(shadowColor, uv.xy, 0);
|
||||
|
||||
/* copy original pixel */
|
||||
vec4 outcolor = stroke_pixel;
|
||||
float outdepth = stroke_depth;
|
||||
|
||||
/* if stroke is not on top, copy shadow */
|
||||
if ((stroke_pixel.a <= 0.2) && (shadow_pixel.a > 0.0)) {
|
||||
outcolor = shadow_pixel;
|
||||
outdepth = shadow_depth;
|
||||
}
|
||||
|
||||
gl_FragDepth = outdepth;
|
||||
FragColor = outcolor;
|
||||
}
|
|
@ -44,6 +44,7 @@ typedef enum ShaderFxType {
|
|||
eShaderFxType_Wave = 6,
|
||||
eShaderFxType_Rim = 7,
|
||||
eShaderFxType_Colorize = 8,
|
||||
eShaderFxType_Shadow = 9,
|
||||
NUM_SHADER_FX_TYPES
|
||||
} ShaderFxType;
|
||||
|
||||
|
@ -169,6 +170,26 @@ typedef enum RimShaderFxModes {
|
|||
eShaderFxRimMode_Divide = 5,
|
||||
} RimShaderFxModes;
|
||||
|
||||
typedef struct ShadowShaderFxData {
|
||||
ShaderFxData shaderfx;
|
||||
struct Object *object;
|
||||
int offset[2];
|
||||
int flag; /* flags */
|
||||
float shadow_rgba[4];
|
||||
float amplitude;
|
||||
float period;
|
||||
float phase;
|
||||
int orientation;
|
||||
float scale[2];
|
||||
float rotation;
|
||||
ShaderFxData_runtime runtime;
|
||||
} ShadowShaderFxData;
|
||||
|
||||
typedef enum eShadowShaderFx_Flag {
|
||||
FX_SHADOW_USE_OBJECT = (1 << 0),
|
||||
FX_SHADOW_USE_WAVE = (1 << 1),
|
||||
} eShadowShaderFx_Flag;
|
||||
|
||||
typedef struct SwirlShaderFxData {
|
||||
ShaderFxData shaderfx;
|
||||
struct Object *object;
|
||||
|
|
|
@ -621,6 +621,7 @@ extern StructRNA RNA_ShaderFxFlip;
|
|||
extern StructRNA RNA_ShaderFxLight;
|
||||
extern StructRNA RNA_ShaderFxPixel;
|
||||
extern StructRNA RNA_ShaderFxRim;
|
||||
extern StructRNA RNA_ShaderFxShadow;
|
||||
extern StructRNA RNA_ShaderFxSwirl;
|
||||
extern StructRNA RNA_ShaderFxWave;
|
||||
extern StructRNA RNA_TexMapping;
|
||||
|
|
|
@ -55,6 +55,7 @@ const EnumPropertyItem rna_enum_object_shaderfx_type_items[] = {
|
|||
{eShaderFxType_Light, "FX_LIGHT", ICON_SHADERFX, "Light", "Simulate ilumination" },
|
||||
{eShaderFxType_Pixel, "FX_PIXEL", ICON_SHADERFX, "Pixelate", "Pixelate image"},
|
||||
{eShaderFxType_Rim, "FX_RIM", ICON_SHADERFX, "Rim", "Add a rim to the image" },
|
||||
{eShaderFxType_Shadow, "FX_SHADOW", ICON_SHADERFX, "Shadow", "Create a shadow effect"},
|
||||
{eShaderFxType_Swirl, "FX_SWIRL", ICON_SHADERFX, "Swirl", "Create a rotation distortion"},
|
||||
{eShaderFxType_Wave, "FX_WAVE", ICON_SHADERFX, "Wave Distortion", "Apply sinusoidal deformation"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
|
@ -101,6 +102,8 @@ static StructRNA *rna_ShaderFx_refine(struct PointerRNA *ptr)
|
|||
return &RNA_ShaderFxPixel;
|
||||
case eShaderFxType_Rim:
|
||||
return &RNA_ShaderFxRim;
|
||||
case eShaderFxType_Shadow:
|
||||
return &RNA_ShaderFxShadow;
|
||||
case eShaderFxType_Swirl:
|
||||
return &RNA_ShaderFxSwirl;
|
||||
case eShaderFxType_Flip:
|
||||
|
@ -180,6 +183,7 @@ static void rna_##_type##ShaderFx_##_prop##_set(PointerRNA *ptr, PointerRNA valu
|
|||
}
|
||||
|
||||
RNA_FX_OBJECT_SET(Light, object, OB_EMPTY);
|
||||
RNA_FX_OBJECT_SET(Shadow, object, OB_EMPTY);
|
||||
RNA_FX_OBJECT_SET(Swirl, object, OB_EMPTY);
|
||||
|
||||
#undef RNA_FX_OBJECT_SET
|
||||
|
@ -382,6 +386,89 @@ static void rna_def_shader_fx_rim(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
}
|
||||
|
||||
static void rna_def_shader_fx_shadow(BlenderRNA *brna)
|
||||
{
|
||||
static EnumPropertyItem prop_shaderfx_shadow_type_items[] = {
|
||||
{ 0, "HORIZONTAL", 0, "Horizontal", "" },
|
||||
{ 1, "VERTICAL", 0, "Vertical", "" },
|
||||
{ 0, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "ShaderFxShadow", "ShaderFx");
|
||||
RNA_def_struct_ui_text(srna, "Shadow Effect", "Shadow effect");
|
||||
RNA_def_struct_sdna(srna, "ShadowShaderFxData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_SHADERFX);
|
||||
|
||||
prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Object", "Object to determine center of rotation");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_ShadowShaderFx_object_set", NULL, NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_update(prop, 0, "rna_ShaderFx_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "offset", PROP_INT, PROP_PIXEL);
|
||||
RNA_def_property_int_sdna(prop, NULL, "offset");
|
||||
RNA_def_property_range(prop, -INT_MAX, INT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Offset", "Offset of the shadow");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "scale");
|
||||
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Scale", "Offset of the shadow");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_range(prop, 0.0, 1.0);
|
||||
RNA_def_property_float_sdna(prop, NULL, "shadow_rgba");
|
||||
RNA_def_property_array(prop, 4);
|
||||
RNA_def_property_ui_text(prop, "Shadow Color", "Color used for Shadow");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "orientation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "orientation");
|
||||
RNA_def_property_enum_items(prop, prop_shaderfx_shadow_type_items);
|
||||
RNA_def_property_ui_text(prop, "Orientation", "Direction of the wave");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "amplitude", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "amplitude");
|
||||
RNA_def_property_range(prop, 0, FLT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Amplitude", "Amplitude of Wave");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "period", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "period");
|
||||
RNA_def_property_range(prop, 0, FLT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Period", "Period of Wave");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "phase", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "phase");
|
||||
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Phase", "Phase Shift of Wave");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rotation");
|
||||
RNA_def_property_range(prop, DEG2RAD(-360), DEG2RAD(360));
|
||||
RNA_def_property_ui_range(prop, DEG2RAD(-360), DEG2RAD(360), 5, 2);
|
||||
RNA_def_property_ui_text(prop, "Rotation", "Rotation around center or object");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_object", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_SHADOW_USE_OBJECT);
|
||||
RNA_def_property_ui_text(prop, "Use Object", "Use object as center of rotation");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_wave", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", FX_SHADOW_USE_WAVE);
|
||||
RNA_def_property_ui_text(prop, "Wave", "Use wave effect");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_ShaderFx_update");
|
||||
}
|
||||
|
||||
static void rna_def_shader_fx_swirl(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -529,6 +616,7 @@ void RNA_def_shader_fx(BlenderRNA *brna)
|
|||
rna_def_shader_fx_wave(brna);
|
||||
rna_def_shader_fx_pixel(brna);
|
||||
rna_def_shader_fx_rim(brna);
|
||||
rna_def_shader_fx_shadow(brna);
|
||||
rna_def_shader_fx_swirl(brna);
|
||||
rna_def_shader_fx_flip(brna);
|
||||
rna_def_shader_fx_light(brna);
|
||||
|
|
|
@ -49,6 +49,7 @@ set(SRC
|
|||
intern/FX_shader_light.c
|
||||
intern/FX_shader_pixel.c
|
||||
intern/FX_shader_rim.c
|
||||
intern/FX_shader_shadow.c
|
||||
intern/FX_shader_swirl.c
|
||||
intern/FX_shader_wave.c
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ extern ShaderFxTypeInfo shaderfx_Type_Flip;
|
|||
extern ShaderFxTypeInfo shaderfx_Type_Light;
|
||||
extern ShaderFxTypeInfo shaderfx_Type_Pixel;
|
||||
extern ShaderFxTypeInfo shaderfx_Type_Rim;
|
||||
extern ShaderFxTypeInfo shaderfx_Type_Shadow;
|
||||
extern ShaderFxTypeInfo shaderfx_Type_Swirl;
|
||||
extern ShaderFxTypeInfo shaderfx_Type_Wave;
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2018, Blender Foundation
|
||||
* This is a new part of Blender
|
||||
*
|
||||
* Contributor(s): Antonio Vazquez
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*
|
||||
*/
|
||||
|
||||
/** \file blender/shader_fx/intern/FX_shader_shadow.c
|
||||
* \ingroup shader_fx
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_gpencil_types.h"
|
||||
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_shader_fx.h"
|
||||
|
||||
#include "FX_shader_types.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_build.h"
|
||||
|
||||
static void initData(ShaderFxData *md)
|
||||
{
|
||||
ShadowShaderFxData *gpfx = (ShadowShaderFxData *)md;
|
||||
gpfx->rotation = 0.0f;
|
||||
ARRAY_SET_ITEMS(gpfx->offset, 15, 20);
|
||||
ARRAY_SET_ITEMS(gpfx->scale, 1.0f, 1.0f);
|
||||
ARRAY_SET_ITEMS(gpfx->shadow_rgba, 0.54f, 0.62f, 1.0f, 0.9f);
|
||||
|
||||
gpfx->amplitude = 10.0f;
|
||||
gpfx->period = 20.0f;
|
||||
gpfx->phase = 0.0f;
|
||||
gpfx->orientation = 1;
|
||||
}
|
||||
|
||||
static void copyData(const ShaderFxData *md, ShaderFxData *target)
|
||||
{
|
||||
BKE_shaderfx_copyData_generic(md, target);
|
||||
}
|
||||
|
||||
static void updateDepsgraph(ShaderFxData *fx, const ModifierUpdateDepsgraphContext *ctx)
|
||||
{
|
||||
ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
|
||||
if (fxd->object != NULL) {
|
||||
DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_GEOMETRY, "Shadow ShaderFx");
|
||||
DEG_add_object_relation(ctx->node, fxd->object, DEG_OB_COMP_TRANSFORM, "Shadow ShaderFx");
|
||||
}
|
||||
DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Shadow ShaderFx");
|
||||
}
|
||||
|
||||
static bool isDisabled(ShaderFxData *fx, int UNUSED(userRenderParams))
|
||||
{
|
||||
ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
|
||||
|
||||
return (!fxd->object) && (fxd->flag & FX_SHADOW_USE_OBJECT);
|
||||
}
|
||||
|
||||
static void foreachObjectLink(
|
||||
ShaderFxData *fx, Object *ob,
|
||||
ShaderFxObjectWalkFunc walk, void *userData)
|
||||
{
|
||||
ShadowShaderFxData *fxd = (ShadowShaderFxData *)fx;
|
||||
|
||||
walk(userData, ob, &fxd->object, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
ShaderFxTypeInfo shaderfx_Type_Shadow = {
|
||||
/* name */ "Shadow",
|
||||
/* structName */ "ShadowShaderFxData",
|
||||
/* structSize */ sizeof(ShadowShaderFxData),
|
||||
/* type */ eShaderFxType_GpencilType,
|
||||
/* flags */ 0,
|
||||
|
||||
/* copyData */ copyData,
|
||||
|
||||
/* initData */ initData,
|
||||
/* freeData */ NULL,
|
||||
/* isDisabled */ isDisabled,
|
||||
/* updateDepsgraph */ updateDepsgraph,
|
||||
/* dependsOnTime */ NULL,
|
||||
/* foreachObjectLink */ foreachObjectLink,
|
||||
/* foreachIDLink */ NULL,
|
||||
};
|
|
@ -49,6 +49,7 @@ void shaderfx_type_init(ShaderFxTypeInfo *types[])
|
|||
INIT_FX_TYPE(Light);
|
||||
INIT_FX_TYPE(Pixel);
|
||||
INIT_FX_TYPE(Rim);
|
||||
INIT_FX_TYPE(Shadow);
|
||||
INIT_FX_TYPE(Swirl);
|
||||
INIT_FX_TYPE(Wave);
|
||||
#undef INIT_FX_TYPE
|
||||
|
|
Loading…
Reference in New Issue