This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/gpu/shaders/gpu_shader_gpencil_stroke_geom.glsl
Antonio Vazquez 66da2f537a New Grease Pencil object for 2D animation
This commit merge the full development done in greasepencil-object branch and include mainly the following features.

- New grease pencil object.
- New drawing engine.
- New grease pencil modes Draw/Sculpt/Edit and Weight Paint.
- New brushes for grease pencil.
- New modifiers for grease pencil.
- New shaders FX.
- New material system (replace old palettes and colors).
- Split of annotations (old grease pencil) and new grease pencil object.
- UI adapted to blender 2.8.

You can get more info here:

https://code.blender.org/2017/12/drawing-2d-animation-in-blender-2-8/
https://code.blender.org/2018/07/grease-pencil-status-update/

This is the result of nearly two years of development and I want thanks firstly the other members of the grease pencil team: Daniel M. Lara, Matias Mendiola and Joshua Leung for their support, ideas and to keep working in the project all the time, without them this project had been impossible.

Also, I want thanks other Blender developers for their help, advices and to be there always to help me, and specially to Clément Foucault, Dalai Felinto, Pablo Vázquez and Campbell Barton.
2018-07-31 10:50:43 +02:00

197 lines
5.6 KiB
GLSL

uniform mat4 ModelViewProjectionMatrix;
uniform vec2 Viewport;
uniform int xraymode;
layout(lines_adjacency) in;
layout(triangle_strip, max_vertices = 13) out;
in vec4 finalColor[4];
in float finalThickness[4];
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.0;
}
if (xraymode == GP_XRAY_3DSPACE) {
return (point.z / point.w);
}
if (xraymode == GP_XRAY_BACK) {
return 1.0;
}
/* in front by default */
return 0.0;
}
void main(void)
{
float MiterLimit = 0.75;
/* 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) {
mTexCoord = vec2(1, 0.5);
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, 1);
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 = vec2(0, 0);
mColor = finalColor[1];
gl_Position = vec4((sp1 + length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
EmitVertex();
mTexCoord = vec2(0, 1);
mColor = finalColor[1];
gl_Position = vec4((sp1 - length_a * miter_a) / Viewport, getZdepth(P1), 1.0);
EmitVertex();
mTexCoord = vec2(0, 0);
mColor = finalColor[2];
gl_Position = vec4((sp2 + length_b * miter_b) / Viewport, getZdepth(P2), 1.0);
EmitVertex();
mTexCoord = vec2(0, 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) {
mTexCoord = vec2(0, 1);
mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ;
gl_Position = vec4((sp2 + (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
EmitVertex();
mTexCoord = vec2(0, 0);
mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ;
gl_Position = vec4((sp2 - (length_b * 2.0) * miter_b) / Viewport, getZdepth(P2), 1.0);
EmitVertex();
mTexCoord = vec2(1, 0.5);
mColor = vec4(finalColor[2].rgb, finalColor[2].a * -1.0) ;
vec2 svn2 = normalize(sp2 - sp1) * length_b * 4.0;
gl_Position = vec4((sp2 + svn2) / Viewport, getZdepth(P2), 1.0);
EmitVertex();
}
EndPrimitive();
}