Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/gpencil/shaders')
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl60
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl86
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl37
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl70
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl50
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl64
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl98
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl70
-rw-r--r--source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl40
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl12
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl17
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl48
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl15
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl143
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl14
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl9
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl49
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl82
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl37
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl15
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl46
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl208
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl37
-rw-r--r--source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl45
24 files changed, 1352 insertions, 0 deletions
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
new file mode 100644
index 00000000000..1bf1d025430
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_blur_frag.glsl
@@ -0,0 +1,60 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform int blur[2];
+
+uniform vec3 loc;
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform float pixfactor;
+
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+vec2 noffset = vec2(blur[0], blur[1]);
+
+out vec4 FragColor;
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+
+ 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);
+
+ /* apply blurring, using a 9-tap filter with predefined gaussian weights */
+ /* depth */
+ float outdepth = 0;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0).r * 0.0947416;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0).r * 0.118318;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x + 1.0 * dx, uv.y + 1.0 * dy), 0).r * 0.0947416;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x - 1.0 * dx, uv.y + 0.0 * dy), 0).r * 0.118318;
+
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x, uv.y), 0).r * 0.147761;
+
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x + 1.0 * dx, uv.y + 0.0 * dy), 0).r * 0.118318;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x - 1.0 * dx, uv.y - 1.0 * dy), 0).r * 0.0947416;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x + 0.0 * dx, uv.y - 1.0 * dy), 0).r * 0.118318;
+ outdepth += texelFetch(strokeDepth, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0).r * 0.0947416;
+
+ gl_FragDepth = outdepth;
+
+ /* color */
+ vec4 outcolor = vec4(0.0);
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 0.0 * dx, uv.y + 1.0 * dy), 0) * 0.118318;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 1.0 * dy), 0) * 0.0947416;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318;
+
+ outcolor += texelFetch(strokeColor, ivec2(uv.x, uv.y), 0) * 0.147761;
+
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y + 0.0 * dy), 0) * 0.118318;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x - 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 0.0 * dx, uv.y - 1.0 * dy), 0) * 0.118318;
+ outcolor += texelFetch(strokeColor, ivec2(uv.x + 1.0 * dx, uv.y - 1.0 * dy), 0) * 0.0947416;
+
+ FragColor = clamp(outcolor, 0, 1.0);
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl
new file mode 100644
index 00000000000..33b249ac09b
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_colorize_frag.glsl
@@ -0,0 +1,86 @@
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform vec4 low_color;
+uniform vec4 high_color;
+uniform int mode;
+uniform float factor;
+
+out vec4 FragColor;
+
+#define MODE_GRAYSCALE 0
+#define MODE_SEPIA 1
+#define MODE_BITONE 2
+#define MODE_CUSTOM 3
+#define MODE_TRANSPARENT 4
+
+float get_luminance(vec4 color)
+{
+ float lum = (color.r * 0.2126) + (color.g * 0.7152) + (color.b * 0.723);
+ return lum;
+}
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
+ float luminance = get_luminance(src_pixel);
+ vec4 outcolor;
+
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
+
+ switch(mode) {
+ case MODE_GRAYSCALE:
+ {
+ outcolor = vec4(luminance, luminance, luminance, src_pixel.a);
+ break;
+ }
+ case MODE_SEPIA:
+ {
+ float Red = (src_pixel.r * 0.393) + (src_pixel.g * 0.769) + (src_pixel.b * 0.189);
+ float Green = (src_pixel.r * 0.349) + (src_pixel.g * 0.686) + (src_pixel.b * 0.168);
+ float Blue = (src_pixel.r * 0.272) + (src_pixel.g * 0.534) + (src_pixel.b * 0.131);
+ outcolor = vec4(Red, Green, Blue, src_pixel.a);
+ break;
+ }
+ case MODE_BITONE:
+ {
+ if (luminance <= factor) {
+ outcolor = low_color;
+ }
+ else {
+ outcolor = high_color;
+ }
+ break;
+ }
+ case MODE_CUSTOM:
+ {
+ /* if below umbral, force custom color */
+ if (luminance <= factor) {
+ outcolor = low_color;
+ }
+ else {
+ outcolor = vec4(luminance * low_color.r, luminance * low_color.b, luminance * low_color.b, src_pixel.a);
+ }
+ break;
+ }
+ case MODE_TRANSPARENT:
+ {
+ outcolor = vec4(src_pixel.rgb, src_pixel.a * factor);
+ break;
+ }
+ default:
+ {
+ outcolor = src_pixel;
+ }
+
+ }
+
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl
new file mode 100644
index 00000000000..43589461cd1
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_flip_frag.glsl
@@ -0,0 +1,37 @@
+out vec4 FragColor;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform vec2 wsize;
+uniform int flipmode;
+
+void main()
+{
+ vec2 mode = vec2(0,0);
+ /* horz. */
+ if (flipmode >= 110) {
+ mode[0] = 1;
+ }
+ /* vert. */
+ if ((flipmode == 101) || (flipmode == 111)) {
+ mode[1] = 1;
+ }
+
+ vec2 uv = vec2(gl_FragCoord.xy);
+ float stroke_depth;
+ vec4 outcolor;
+
+ if (mode[0] > 0) {
+ uv.x = wsize.x - uv.x;
+ }
+ if (mode[1] > 0) {
+ uv.y = wsize.y - uv.y;
+ }
+
+ ivec2 iuv = ivec2(uv.x, uv.y);
+ stroke_depth = texelFetch(strokeDepth, iuv, 0).r;
+ outcolor = texelFetch(strokeColor, iuv, 0);
+
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl
new file mode 100644
index 00000000000..6dcd0499baf
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_light_frag.glsl
@@ -0,0 +1,70 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform vec2 Viewport;
+uniform vec4 loc;
+uniform float energy;
+uniform float ambient;
+
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform float pixfactor;
+
+out vec4 FragColor;
+
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+
+#define height loc.w
+
+/* 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()
+{
+ float stroke_depth;
+ vec4 objcolor;
+
+ vec4 light_loc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+ vec2 light2d = toScreenSpace(light_loc);
+
+ /* 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 = height * 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);
+ vec3 norm = vec3(0, 0, 1.0); /* always z-up */
+
+ ivec2 iuv = ivec2(uv.x, uv.y);
+ stroke_depth = texelFetch(strokeDepth, iuv, 0).r;
+ objcolor = texelFetch(strokeColor, iuv, 0);
+
+ /* diffuse light */
+ vec3 lightdir = normalize(light3d - frag_loc);
+ float diff = max(dot(norm, lightdir), 0.0);
+ float dist = length(light3d - frag_loc) / pxscale;
+ float factor = diff * ((energy * 100.0) / (dist * dist));
+
+ 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/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl
new file mode 100644
index 00000000000..0b25dbbd012
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_pixel_frag.glsl
@@ -0,0 +1,50 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform int size[3];
+uniform vec4 color;
+
+uniform vec3 loc;
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform float pixfactor;
+
+out vec4 FragColor;
+
+int uselines = size[2];
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+vec2 nsize = max(vec2(size[0], size[1]), 3.0);
+
+/* This pixelation shader is a modified version of original Geeks3d.com code */
+void main()
+{
+ vec2 uv = vec2(gl_FragCoord.xy);
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+
+ float dx = (ProjectionMatrix[3][3] == 0.0) ? (nsize[0] / (nloc.z * defaultpixsize)) : (nsize[0] / defaultpixsize);
+ float dy = (ProjectionMatrix[3][3] == 0.0) ? (nsize[1] / (nloc.z * defaultpixsize)) : (nsize[1] / defaultpixsize);
+
+ dx = max(abs(dx), 3.0);
+ dy = max(abs(dy), 3.0);
+
+ vec2 coord = vec2(dx * floor(uv.x / dx), dy * floor(uv.y / dy));
+
+ float stroke_depth = texelFetch(strokeDepth, ivec2(coord), 0).r;
+ vec4 outcolor = texelFetch(strokeColor, ivec2(coord), 0);
+
+ if (uselines == 1) {
+ float difx = uv.x - (floor(uv.x / nsize[0]) * nsize[0]);
+ if ((difx == 0.5) && (outcolor.a > 0)) {
+ outcolor = color;
+ }
+ float dify = uv.y - (floor(uv.y / nsize[1]) * nsize[1]);
+ if ((dify == 0.5) && (outcolor.a > 0)) {
+ outcolor = color;
+ }
+ }
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl
new file mode 100644
index 00000000000..6ea4faf11fd
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_prepare_frag.glsl
@@ -0,0 +1,64 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+/* ******************************************************************* */
+/* create rim and mask */
+/* ******************************************************************* */
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform vec2 Viewport;
+
+uniform int offset[2];
+uniform vec3 rim_color;
+uniform vec3 mask_color;
+
+uniform vec3 loc;
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform float pixfactor;
+
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+vec2 noffset = vec2(offset[0], offset[1]);
+
+out vec4 FragColor;
+
+void main()
+{
+ vec2 uv = vec2(gl_FragCoord.xy);
+ vec4 nloc = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+
+ 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);
+
+ float stroke_depth = texelFetch(strokeDepth, ivec2(uv.xy), 0).r;
+ vec4 src_pixel= texelFetch(strokeColor, ivec2(uv.xy), 0);
+ vec4 offset_pixel= texelFetch(strokeColor, ivec2(uv.x - dx, uv.y - dy), 0);
+ vec4 outcolor;
+
+ /* 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;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl
new file mode 100644
index 00000000000..0a7eb65d564
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_rim_resolve_frag.glsl
@@ -0,0 +1,98 @@
+/* ******************************************************************* */
+/* Resolve RIM pass and add blur if needed */
+/* ******************************************************************* */
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform sampler2D strokeRim;
+
+uniform vec3 mask_color;
+uniform int mode;
+
+out vec4 FragColor;
+
+#define MODE_NORMAL 0
+#define MODE_OVERLAY 1
+#define MODE_ADD 2
+#define MODE_SUB 3
+#define MODE_MULTIPLY 4
+#define MODE_DIVIDE 5
+
+float overlay_color(float a, float b)
+{
+ float rtn;
+ if (a < 0.5) {
+ rtn = 2.0 * a * b;
+ }
+ else {
+ rtn = 1.0 - 2.0 * (1.0 - a) * (1.0 - b);
+ }
+
+ return rtn;
+}
+
+vec4 get_blend_color(int mode, vec4 src_color, vec4 mix_color)
+{
+ vec4 outcolor;
+ if (mode == MODE_NORMAL) {
+ outcolor = mix_color;
+ }
+ else if (mode == MODE_OVERLAY) {
+ outcolor.r = overlay_color(src_color.r, mix_color.r);
+ outcolor.g = overlay_color(src_color.g, mix_color.g);
+ outcolor.b = overlay_color(src_color.b, mix_color.b);
+ }
+ else if (mode == MODE_ADD){
+ outcolor = src_color + mix_color;
+ }
+ else if (mode == MODE_SUB){
+ outcolor = src_color - mix_color;
+ }
+ else if (mode == MODE_MULTIPLY) {
+ outcolor = src_color * mix_color;
+ }
+ else if (mode == MODE_DIVIDE) {
+ outcolor = src_color / mix_color;
+ }
+ else {
+ outcolor = mix_color;
+ }
+
+ /* use always the alpha of source color */
+
+ outcolor.a = src_color.a;
+ /* use alpha to calculate the weight of the mixed color */
+ outcolor = mix(src_color, outcolor, mix_color.a);
+
+ return outcolor;
+}
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ float stroke_depth = texelFetch(strokeDepth, uv.xy, 0).r;
+ vec4 src_pixel= texelFetch(strokeColor, uv.xy, 0);
+ vec4 rim_pixel= texelFetch(strokeRim, uv.xy, 0);
+
+ vec4 outcolor = src_pixel;
+
+ /* is transparent */
+ if (src_pixel.a == 0.0f) {
+ discard;
+ }
+ /* pixel is equal to mask color, keep */
+ else if (src_pixel.rgb == mask_color.rgb) {
+ outcolor = src_pixel;
+ }
+ else {
+ if (rim_pixel.a == 0.0f) {
+ outcolor = src_pixel;
+ }
+ else {
+ outcolor = get_blend_color(mode, src_pixel, rim_pixel);
+ }
+ }
+
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
new file mode 100644
index 00000000000..78aacafdcb7
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_swirl_frag.glsl
@@ -0,0 +1,70 @@
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrix;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform vec2 Viewport;
+uniform vec3 loc;
+uniform int radius;
+uniform float angle;
+uniform int transparent;
+
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform float pixfactor;
+
+out vec4 FragColor;
+
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+
+/* 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;
+}
+
+/* This swirl shader is a modified version of original Geeks3d.com code */
+void main()
+{
+ vec2 uv = vec2(gl_FragCoord.xy);
+ float stroke_depth;
+ vec4 outcolor;
+
+ vec4 center3d = ProjectionMatrix * ViewMatrix * vec4(loc.xyz, 1.0);
+ vec2 center = toScreenSpace(center3d);
+ vec2 tc = uv - center;
+
+ float dist = length(tc);
+ float pxradius = (ProjectionMatrix[3][3] == 0.0) ? (radius / (loc.z * defaultpixsize)) : (radius / defaultpixsize);
+ pxradius = max(pxradius, 1);
+
+ if (dist <= pxradius) {
+ float percent = (pxradius - dist) / pxradius;
+ float theta = percent * percent * angle * 8.0;
+ float s = sin(theta);
+ float c = cos(theta);
+ tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
+ tc += center;
+
+ stroke_depth = texelFetch(strokeDepth, ivec2(tc), 0).r;
+ outcolor = texelFetch(strokeColor, ivec2(tc), 0);
+ }
+ else {
+ if (transparent == 1) {
+ discard;
+ }
+ stroke_depth = texelFetch(strokeDepth, ivec2(uv), 0).r;
+ outcolor = texelFetch(strokeColor, ivec2(uv), 0);
+ }
+
+ gl_FragDepth = stroke_depth;
+ FragColor = outcolor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
new file mode 100644
index 00000000000..882b2cf59f1
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/fx/gpencil_fx_wave_frag.glsl
@@ -0,0 +1,40 @@
+
+out vec4 FragColor;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+uniform float amplitude;
+uniform float period;
+uniform float phase;
+uniform int orientation;
+uniform vec2 wsize;
+
+#define M_PI 3.1415926535897932384626433832795
+
+#define HORIZONTAL 0
+#define VERTICAL 1
+
+void main()
+{
+ vec4 outcolor;
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float stroke_depth;
+
+ float value;
+ if (orientation == HORIZONTAL) {
+ float pval = (uv.x * M_PI) / wsize[0];
+ value = amplitude * sin((period * pval) + phase);
+ outcolor = texelFetch(strokeColor, ivec2(uv.x, uv.y + value), 0);
+ stroke_depth = texelFetch(strokeDepth, ivec2(uv.x, uv.y + value), 0).r;
+ }
+ else {
+ float pval = (uv.y * M_PI) / wsize[1];
+ value = amplitude * sin((period * pval) + phase);
+ outcolor = texelFetch(strokeColor, ivec2(uv.x + value, uv.y), 0);
+ stroke_depth = texelFetch(strokeDepth, ivec2(uv.x + value, uv.y), 0).r;
+ }
+
+ FragColor = outcolor;
+ gl_FragDepth = stroke_depth;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl
new file mode 100644
index 00000000000..cbd7a461dd3
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_background_frag.glsl
@@ -0,0 +1,12 @@
+out vec4 FragColor;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ gl_FragDepth = texelFetch(strokeDepth, uv, 0).r;
+ FragColor = texelFetch(strokeColor, uv, 0);
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl
new file mode 100644
index 00000000000..b3bd8e488f2
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_frag.glsl
@@ -0,0 +1,17 @@
+in vec4 mColor;
+in vec2 mTexCoord;
+out vec4 fragColor;
+
+void main()
+{
+ vec2 centered = mTexCoord - vec2(0.5);
+ float dist_squared = dot(centered, centered);
+ const float rad_squared = 0.25;
+
+ // round point with jaggy edges
+ if (dist_squared > rad_squared) {
+ discard;
+ }
+
+ fragColor = mColor;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
new file mode 100644
index 00000000000..0d2da00db66
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_geom.glsl
@@ -0,0 +1,48 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 Viewport;
+
+layout(points) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+in vec4 finalColor[1];
+in float finalThickness[1];
+
+out vec4 mColor;
+out vec2 mTexCoord;
+
+/* project 3d point to 2d on screen space */
+vec2 toScreenSpace(vec4 vertex)
+{
+ return vec2(vertex.xy / vertex.w) * Viewport;
+}
+
+void main(void)
+{
+ vec4 P0 = gl_in[0].gl_Position;
+ vec2 sp0 = toScreenSpace(P0);
+
+ float size = finalThickness[0];
+
+ /* generate the triangle strip */
+ mTexCoord = vec2(0, 1);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y + size) / Viewport, 0, 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y - size) / Viewport, 0, 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(1, 1);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y + size) / Viewport, 0, 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(1, 0);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y - size) / Viewport, 0, 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
new file mode 100644
index 00000000000..77fdf58bea0
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_edit_point_vert.glsl
@@ -0,0 +1,15 @@
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in vec4 color;
+in float size;
+
+out vec4 finalColor;
+out float finalThickness;
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
+ finalColor = color;
+ finalThickness = size;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
new file mode 100644
index 00000000000..d2cad4e44f7
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_frag.glsl
@@ -0,0 +1,143 @@
+uniform vec4 color2;
+uniform int fill_type;
+uniform float mix_factor;
+
+uniform float gradient_angle;
+uniform float gradient_radius;
+uniform float pattern_gridsize;
+uniform vec2 gradient_scale;
+uniform vec2 gradient_shift;
+
+uniform float texture_angle;
+uniform vec2 texture_scale;
+uniform vec2 texture_offset;
+uniform int texture_mix;
+uniform int texture_flip;
+uniform float texture_opacity;
+uniform int xraymode;
+
+uniform sampler2D myTexture;
+uniform int texture_clamp;
+
+/* keep this list synchronized with list in gpencil_draw_utils.c */
+#define SOLID 0
+#define GRADIENT 1
+#define RADIAL 2
+#define CHESS 3
+#define TEXTURE 4
+#define PATTERN 5
+
+#define GP_XRAY_FRONT 0
+#define GP_XRAY_3DSPACE 1
+#define GP_XRAY_BACK 2
+
+in vec4 finalColor;
+in vec2 texCoord_interp;
+out vec4 fragColor;
+#define texture2D texture
+
+void set_color(in vec4 color, in vec4 color2, in vec4 tcolor, in float mixv, in float factor,
+ in int tmix, in int flip, out vec4 ocolor)
+{
+ /* full color A */
+ if (mixv == 1.0) {
+ if (tmix == 1) {
+ ocolor = (flip == 0) ? color : tcolor;
+ }
+ else {
+ ocolor = (flip == 0) ? color : color2;
+ }
+ }
+ /* full color B */
+ else if (mixv == 0.0) {
+ if (tmix == 1) {
+ ocolor = (flip == 0) ? tcolor : color;
+ }
+ else {
+ ocolor = (flip == 0) ? color2 : color;
+ }
+ }
+ /* mix of colors */
+ else {
+ if (tmix == 1) {
+ ocolor = (flip == 0) ? mix(color, tcolor, factor) : mix(tcolor, color, factor);
+ }
+ else {
+ ocolor = (flip == 0) ? mix(color, color2, factor) : mix(color2, color, factor);
+ }
+ }
+}
+
+void main()
+{
+ vec2 t_center = vec2(0.5, 0.5);
+ mat2 matrot_tex = mat2(cos(texture_angle), -sin(texture_angle), sin(texture_angle), cos(texture_angle));
+ vec2 rot_tex = (matrot_tex * (texCoord_interp - t_center)) + t_center + texture_offset;
+ vec4 tmp_color;
+ tmp_color = (texture_clamp == 0) ? texture2D(myTexture, rot_tex * texture_scale) : texture2D(myTexture, clamp(rot_tex * texture_scale, 0.0, 1.0));
+ vec4 text_color = vec4(tmp_color[0], tmp_color[1], tmp_color[2], tmp_color[3] * texture_opacity);
+ vec4 chesscolor;
+
+ /* solid fill */
+ if (fill_type == SOLID) {
+ fragColor = finalColor;
+ }
+ else {
+ vec2 center = vec2(0.5, 0.5) + gradient_shift;
+ mat2 matrot = mat2(cos(gradient_angle), -sin(gradient_angle), sin(gradient_angle), cos(gradient_angle));
+ vec2 rot = (((matrot * (texCoord_interp - center)) + center) * gradient_scale) + gradient_shift;
+ /* gradient */
+ if (fill_type == GRADIENT) {
+ set_color(finalColor, color2, text_color, mix_factor, rot.x - mix_factor + 0.5, texture_mix, texture_flip, fragColor);
+ }
+ /* radial gradient */
+ if (fill_type == RADIAL) {
+ float in_rad = gradient_radius * mix_factor;
+ float ex_rad = gradient_radius - in_rad;
+ float intensity = 0;
+ float distance = length((center - texCoord_interp) * gradient_scale);
+ if (distance > gradient_radius) {
+ discard;
+ }
+ if (distance > in_rad) {
+ intensity = clamp(((distance - in_rad) / ex_rad), 0.0, 1.0);
+ }
+ set_color(finalColor, color2, text_color, mix_factor, intensity, texture_mix, texture_flip, fragColor);
+ }
+ /* chessboard */
+ if (fill_type == CHESS) {
+ vec2 pos = rot / pattern_gridsize;
+ if ((fract(pos.x) < 0.5 && fract(pos.y) < 0.5) || (fract(pos.x) > 0.5 && fract(pos.y) > 0.5)) {
+ chesscolor = (texture_flip == 0) ? finalColor : color2;
+ }
+ else {
+ chesscolor = (texture_flip == 0) ? color2 : finalColor;
+ }
+ /* mix with texture */
+ fragColor = (texture_mix == 1) ? mix(chesscolor, text_color, mix_factor) : chesscolor;
+ }
+ /* texture */
+ if (fill_type == TEXTURE) {
+ fragColor = (texture_mix == 1) ? mix(text_color, finalColor, mix_factor) : text_color;
+ }
+ /* pattern */
+ if (fill_type == PATTERN) {
+ fragColor = finalColor;
+ fragColor.a = min(text_color.a, finalColor.a);
+ }
+ }
+
+ /* set zdepth */
+ if (xraymode == GP_XRAY_FRONT) {
+ gl_FragDepth = 0.000001;
+ }
+ else if (xraymode == GP_XRAY_3DSPACE) {
+ gl_FragDepth = gl_FragCoord.z;
+ }
+ else if (xraymode == GP_XRAY_BACK) {
+ gl_FragDepth = 0.999999;
+ }
+ else {
+ gl_FragDepth = 0.000001;
+ }
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
new file mode 100644
index 00000000000..52da354a562
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_fill_vert.glsl
@@ -0,0 +1,14 @@
+uniform mat4 ModelViewProjectionMatrix;
+
+in vec3 pos;
+in vec4 color;
+in vec2 texCoord;
+out vec4 finalColor;
+out vec2 texCoord_interp;
+
+void main(void)
+{
+ gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
+ finalColor = color;
+ texCoord_interp = texCoord;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
new file mode 100644
index 00000000000..c2e3f787bec
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_paper_frag.glsl
@@ -0,0 +1,9 @@
+uniform vec3 color;
+uniform float opacity;
+
+out vec4 FragColor;
+
+void main()
+{
+ FragColor = vec4(color, opacity);
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
new file mode 100644
index 00000000000..0d6d2b22a55
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_frag.glsl
@@ -0,0 +1,49 @@
+uniform int color_type;
+uniform int mode;
+uniform sampler2D myTexture;
+
+in vec4 mColor;
+in vec2 mTexCoord;
+out vec4 fragColor;
+
+#define texture2D texture
+
+#define GPENCIL_MODE_LINE 0
+#define GPENCIL_MODE_DOTS 1
+#define GPENCIL_MODE_BOX 2
+
+/* keep this list synchronized with list in gpencil_engine.h */
+#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_TEXTURE 1
+#define GPENCIL_COLOR_PATTERN 2
+
+void main()
+{
+ vec2 centered = mTexCoord - vec2(0.5);
+ float dist_squared = dot(centered, centered);
+ const float rad_squared = 0.25;
+
+ // round point with jaggy edges
+ if ((mode != GPENCIL_MODE_BOX) && (dist_squared > rad_squared))
+ discard;
+
+ vec4 tmp_color = texture2D(myTexture, mTexCoord);
+
+ /* Solid */
+ if (color_type == GPENCIL_COLOR_SOLID) {
+ fragColor = mColor;
+ }
+ /* texture */
+ if (color_type == GPENCIL_COLOR_TEXTURE) {
+ fragColor = texture2D(myTexture, mTexCoord);
+ /* mult both alpha factor to use strength factor with texture */
+ fragColor.a = min(fragColor.a * mColor.a, fragColor.a);
+ }
+ /* pattern */
+ if (color_type == GPENCIL_COLOR_PATTERN) {
+ vec4 text_color = texture2D(myTexture, mTexCoord);
+ fragColor = mColor;
+ /* mult both alpha factor to use strength factor with color alpha limit */
+ fragColor.a = min(text_color.a * mColor.a, mColor.a);
+ }
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
new file mode 100644
index 00000000000..63f22e0f812
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_geom.glsl
@@ -0,0 +1,82 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 Viewport;
+uniform int xraymode;
+
+layout(points) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+in vec4 finalColor[1];
+in float finalThickness[1];
+in vec2 finaluvdata[1];
+
+out vec4 mColor;
+out vec2 mTexCoord;
+
+#define GP_XRAY_FRONT 0
+#define GP_XRAY_3DSPACE 1
+#define GP_XRAY_BACK 2
+
+/* project 3d point to 2d on screen space */
+vec2 toScreenSpace(vec4 vertex)
+{
+ return vec2(vertex.xy / vertex.w) * Viewport;
+}
+
+/* get zdepth value */
+float getZdepth(vec4 point)
+{
+ if (xraymode == GP_XRAY_FRONT) {
+ return 0.000001;
+ }
+ if (xraymode == GP_XRAY_3DSPACE) {
+ return (point.z / point.w);
+ }
+ if (xraymode == GP_XRAY_BACK) {
+ return 0.999999;
+ }
+
+ /* in front by default */
+ return 0.000001;
+}
+
+vec2 rotateUV(vec2 uv, float angle)
+{
+ /* translate center of rotation to the center of texture */
+ vec2 new_uv = uv - vec2(0.5f, 0.5f);
+ vec2 rot_uv;
+ rot_uv.x = new_uv.x * cos(angle) - new_uv.y * sin(angle);
+ rot_uv.y = new_uv.y * cos(angle) + new_uv.x * sin(angle);
+ return rot_uv + vec2(0.5f, 0.5f);
+}
+
+void main(void)
+{
+ /* receive 4 points */
+ vec4 P0 = gl_in[0].gl_Position;
+ vec2 sp0 = toScreenSpace(P0);
+
+ float size = finalThickness[0];
+ float aspect = 1.0;
+ /* generate the triangle strip */
+ mTexCoord = rotateUV(vec2(0, 1), finaluvdata[0].y);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y + size * aspect) / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ mTexCoord = rotateUV(vec2(0, 0), finaluvdata[0].y);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x - size, sp0.y - size * aspect) / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ mTexCoord = rotateUV(vec2(1, 1), finaluvdata[0].y);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y + size * aspect) / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ mTexCoord = rotateUV(vec2(1, 0), finaluvdata[0].y);
+ mColor = finalColor[0];
+ gl_Position = vec4(vec2(sp0.x + size, sp0.y - size * aspect) / Viewport, getZdepth(P0), 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
new file mode 100644
index 00000000000..5e89bf8e5ce
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_point_vert.glsl
@@ -0,0 +1,37 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ProjectionMatrix;
+
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform int keep_size;
+uniform float objscale;
+uniform float pixfactor;
+
+in vec3 pos;
+in vec4 color;
+in float thickness;
+in vec2 uvdata;
+
+out vec4 finalColor;
+out float finalThickness;
+out vec2 finaluvdata;
+
+#define TRUE 1
+
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+
+void main()
+{
+ gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
+ finalColor = color;
+
+ if (keep_size == TRUE) {
+ finalThickness = thickness;
+ }
+ else {
+ float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize);
+ finalThickness = max(size * objscale, 4.0); /* minimum 4 pixels */
+ }
+
+ finaluvdata = uvdata;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl
new file mode 100644
index 00000000000..dd54e38c3d0
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_simple_mix_frag.glsl
@@ -0,0 +1,15 @@
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
+ vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
+
+ FragColor = stroke_color;
+ gl_FragDepth = stroke_depth;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
new file mode 100644
index 00000000000..d57921c1629
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_frag.glsl
@@ -0,0 +1,46 @@
+uniform int color_type;
+uniform sampler2D myTexture;
+
+in vec4 mColor;
+in vec2 mTexCoord;
+in float uvfac;
+
+out vec4 fragColor;
+
+#define texture2D texture
+
+/* keep this list synchronized with list in gpencil_engine.h */
+#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_TEXTURE 1
+#define GPENCIL_COLOR_PATTERN 2
+
+void main()
+{
+ vec4 tColor = vec4(mColor);
+ /* if alpha < 0, then encap (only solid mode ) */
+ if ((mColor.a < 0) && (color_type == GPENCIL_COLOR_SOLID)) {
+ vec2 center = vec2(uvfac, 1.0);
+ tColor.a = tColor.a * -1.0;
+ float dist = length(mTexCoord - center);
+ if (dist > 0.50) {
+ discard;
+ }
+ }
+ /* Solid */
+ if (color_type == GPENCIL_COLOR_SOLID) {
+ fragColor = tColor;
+ }
+ /* texture */
+ if (color_type == GPENCIL_COLOR_TEXTURE) {
+ fragColor = texture2D(myTexture, mTexCoord);
+ /* mult both alpha factor to use strength factor */
+ fragColor.a = min(fragColor.a * tColor.a, fragColor.a);
+ }
+ /* pattern */
+ if (color_type == GPENCIL_COLOR_PATTERN) {
+ vec4 text_color = texture2D(myTexture, mTexCoord);
+ fragColor = tColor;
+ /* mult both alpha factor to use strength factor with color alpha limit */
+ fragColor.a = min(text_color.a * tColor.a, tColor.a);
+ }
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
new file mode 100644
index 00000000000..f9054b44996
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_geom.glsl
@@ -0,0 +1,208 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec2 Viewport;
+uniform int xraymode;
+uniform int color_type;
+
+layout(lines_adjacency) in;
+layout(triangle_strip, max_vertices = 13) out;
+
+in vec4 finalColor[4];
+in float finalThickness[4];
+in vec2 finaluvdata[4];
+
+out vec4 mColor;
+out vec2 mTexCoord;
+out float uvfac;
+
+#define GP_XRAY_FRONT 0
+#define GP_XRAY_3DSPACE 1
+#define GP_XRAY_BACK 2
+
+/* keep this list synchronized with list in gpencil_engine.h */
+#define GPENCIL_COLOR_SOLID 0
+#define GPENCIL_COLOR_TEXTURE 1
+#define GPENCIL_COLOR_PATTERN 2
+
+/* project 3d point to 2d on screen space */
+vec2 toScreenSpace(vec4 vertex)
+{
+ return vec2(vertex.xy / vertex.w) * Viewport;
+}
+
+/* get zdepth value */
+float getZdepth(vec4 point)
+{
+ if (xraymode == GP_XRAY_FRONT) {
+ return 0.000001;
+ }
+ if (xraymode == GP_XRAY_3DSPACE) {
+ return (point.z / point.w);
+ }
+ if (xraymode == GP_XRAY_BACK) {
+ return 0.999999;
+ }
+
+ /* in front by default */
+ return 0.000001;
+}
+void main(void)
+{
+ float MiterLimit = 0.75;
+ uvfac = 0;
+
+ /* receive 4 points */
+ vec4 P0 = gl_in[0].gl_Position;
+ vec4 P1 = gl_in[1].gl_Position;
+ vec4 P2 = gl_in[2].gl_Position;
+ vec4 P3 = gl_in[3].gl_Position;
+
+ /* get the four vertices passed to the shader */
+ vec2 sp0 = toScreenSpace(P0); // start of previous segment
+ vec2 sp1 = toScreenSpace(P1); // end of previous segment, start of current segment
+ vec2 sp2 = toScreenSpace(P2); // end of current segment, start of next segment
+ vec2 sp3 = toScreenSpace(P3); // end of next segment
+
+ /* culling outside viewport */
+ vec2 area = Viewport * 4.0;
+ if (sp1.x < -area.x || sp1.x > area.x) return;
+ if (sp1.y < -area.y || sp1.y > area.y) return;
+ if (sp2.x < -area.x || sp2.x > area.x) return;
+ if (sp2.y < -area.y || sp2.y > area.y) return;
+
+ /* determine the direction of each of the 3 segments (previous, current, next) */
+ vec2 v0 = normalize(sp1 - sp0);
+ vec2 v1 = normalize(sp2 - sp1);
+ vec2 v2 = normalize(sp3 - sp2);
+
+ /* determine the normal of each of the 3 segments (previous, current, next) */
+ vec2 n0 = vec2(-v0.y, v0.x);
+ vec2 n1 = vec2(-v1.y, v1.x);
+ vec2 n2 = vec2(-v2.y, v2.x);
+
+ /* determine miter lines by averaging the normals of the 2 segments */
+ vec2 miter_a = normalize(n0 + n1); // miter at start of current segment
+ vec2 miter_b = normalize(n1 + n2); // miter at end of current segment
+
+ /* determine the length of the miter by projecting it onto normal and then inverse it */
+ float an1 = dot(miter_a, n1);
+ float bn1 = dot(miter_b, n2);
+ if (an1 == 0) an1 = 1;
+ if (bn1 == 0) bn1 = 1;
+ float length_a = finalThickness[1] / an1;
+ float length_b = finalThickness[2] / bn1;
+ if (length_a <= 0.0) length_a = 0.01;
+ if (length_b <= 0.0) length_b = 0.01;
+
+ /* prevent excessively long miters at sharp corners */
+ if (dot(v0, v1) < -MiterLimit) {
+ miter_a = n1;
+ length_a = finalThickness[1];
+
+ /* close the gap */
+ if (dot(v0, n1) > 0) {
+ mTexCoord = vec2(0, 0);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 + finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 + finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0.5);
+ mColor = finalColor[1];
+ gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+ }
+ else {
+ mTexCoord = vec2(0, 1);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 - finalThickness[1] * n1) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 1);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 - finalThickness[1] * n0) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0.5);
+ mColor = finalColor[1];
+ gl_Position = vec4(sp1 / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ EndPrimitive();
+ }
+ }
+
+ if (dot(v1, v2) < -MiterLimit) {
+ miter_b = n1;
+ length_b = finalThickness[2];
+ }
+
+ /* generate the start endcap (alpha < 0 used as endcap flag)*/
+ if ((P0 == P2) && (color_type == GPENCIL_COLOR_SOLID)){
+ mTexCoord = vec2(2, 1);
+ mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ;
+ vec2 svn1 = normalize(sp1 - sp2) * length_a * 4.0;
+ gl_Position = vec4((sp1 + svn1) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 0);
+ mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ;
+ gl_Position = vec4((sp1 - (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(0, 2);
+ mColor = vec4(finalColor[1].rgb, finalColor[1].a * -1.0) ;
+ gl_Position = vec4((sp1 + (length_a * 2.0) * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+ }
+
+ /* generate the triangle strip */
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 0) : vec2(finaluvdata[1].x, 0);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 + length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(0, 1) : vec2(finaluvdata[1].x, 1);
+ mColor = finalColor[1];
+ gl_Position = vec4((sp1 - length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
+ EmitVertex();
+
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 0) : vec2(finaluvdata[2].x, 0);
+ mColor = finalColor[2];
+ gl_Position = vec4((sp2 + length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ mTexCoord = (color_type == GPENCIL_COLOR_SOLID) ? vec2(1, 1) : vec2(finaluvdata[2].x, 1);
+ mColor = finalColor[2];
+ gl_Position = vec4((sp2 - length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ /* generate the end endcap (alpha < 0 used as endcap flag)*/
+ if ((P1 == P3) && (color_type == GPENCIL_COLOR_SOLID)){
+ mTexCoord = vec2(finaluvdata[2].x, 2);
+ mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ;
+ uvfac = finaluvdata[2].x;
+ gl_Position = vec4((sp2 + (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(finaluvdata[2].x, 0);
+ mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ;
+ uvfac = finaluvdata[2].x;
+ gl_Position = vec4((sp2 - (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+
+ mTexCoord = vec2(finaluvdata[2].x + 2, 1);
+ mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ;
+ uvfac = finaluvdata[2].x;
+ vec2 svn2 = normalize(sp2 - sp1) * length_b * 4.0;
+ gl_Position = vec4((sp2 + svn2) / Viewport, getZdepth(P2), 1.0);
+ EmitVertex();
+ }
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
new file mode 100644
index 00000000000..2f9a105e911
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_stroke_vert.glsl
@@ -0,0 +1,37 @@
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 ProjectionMatrix;
+
+uniform float pixsize; /* rv3d->pixsize */
+uniform float pixelsize; /* U.pixelsize */
+uniform int keep_size;
+uniform float objscale;
+uniform float pixfactor;
+
+in vec3 pos;
+in vec4 color;
+in float thickness;
+in vec2 uvdata;
+
+out vec4 finalColor;
+out float finalThickness;
+out vec2 finaluvdata;
+
+#define TRUE 1
+
+float defaultpixsize = pixsize * pixelsize * (1000.0 / pixfactor);
+
+void main(void)
+{
+ gl_Position = ModelViewProjectionMatrix * vec4( pos, 1.0 );
+ finalColor = color;
+
+ if (keep_size == TRUE) {
+ finalThickness = thickness;
+ }
+ else {
+ float size = (ProjectionMatrix[3][3] == 0.0) ? (thickness / (gl_Position.z * defaultpixsize)) : (thickness / defaultpixsize);
+ finalThickness = max(size * objscale, 1.0);
+ }
+
+ finaluvdata = uvdata;
+}
diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl
new file mode 100644
index 00000000000..0983e6c4d87
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/shaders/gpencil_zdepth_mix_frag.glsl
@@ -0,0 +1,45 @@
+in vec4 uvcoordsvar;
+
+out vec4 FragColor;
+
+uniform sampler2D strokeColor;
+uniform sampler2D strokeDepth;
+uniform int tonemapping;
+
+float srgb_to_linearrgb(float c)
+{
+ if (c < 0.04045)
+ return (c < 0.0) ? 0.0 : c * (1.0 / 12.92);
+ else
+ return pow((c + 0.055) * (1.0 / 1.055), 2.4);
+}
+
+float linearrgb_to_srgb(float c)
+{
+ if (c < 0.0031308)
+ return (c < 0.0) ? 0.0 : c * 12.92;
+ else
+ return 1.055 * pow(c, 1.0 / 2.4) - 0.055;
+}
+
+void main()
+{
+ ivec2 uv = ivec2(gl_FragCoord.xy);
+ float stroke_depth = texelFetch(strokeDepth, uv, 0).r;
+ vec4 stroke_color = texelFetch(strokeColor, uv, 0).rgba;
+
+ /* premult alpha factor to remove double blend effects */
+ if (stroke_color.a > 0) {
+ stroke_color = vec4(vec3(stroke_color.rgb / stroke_color.a), stroke_color.a);
+ }
+
+ /* apply color correction for render only */
+ if (tonemapping == 1) {
+ stroke_color.r = srgb_to_linearrgb(stroke_color.r);
+ stroke_color.g = srgb_to_linearrgb(stroke_color.g);
+ stroke_color.b = srgb_to_linearrgb(stroke_color.b);
+ }
+
+ FragColor = stroke_color;
+ gl_FragDepth = stroke_depth;
+}