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_basic_geom.glsl
2016-05-26 18:53:09 +10:00

101 lines
3.1 KiB
GLSL

/*
* Used the implementation of wide lines of Timo Suoranta (http://neure.dy.fi/wideline.html)
*/
#define PASSTHROUGH 0
layout(lines) in;
#if defined(DRAW_LINE)
#if PASSTHROUGH
layout(line_strip, max_vertices = 10) out;
#else
layout(triangle_strip, max_vertices = 6) out;
#endif
varying out float t;
varying in vec4 varying_vertex_color_line[];
varying out vec4 varying_vertex_color;
uniform ivec4 viewport;
uniform float line_width;
uniform int stipple_factor;
void main(void)
{
vec2 window_size = viewport.zw;
vec4 start = gl_in[0].gl_Position;
vec4 end = gl_in[1].gl_Position;
#if PASSTHROUGH
gl_Position = start; EmitVertex();
gl_Position = end; EmitVertex();
EndPrimitive();
return;
#endif
/* t = 0 t = ~(len(end - start) + 2*line_width)
* A-------------------------------------B
* | | | |
* | side | |
* | | | |
* |--axis--*start--------------*end-----|
* | | | |
* | | | |
* | | | |
* D-------------------------------------C
*/
/* Clip the line before homogenization.
* Compute line start and end distances to nearplane in clipspace
* Distances are t0 = dot(start, plane) and t1 = dot(end, plane)
*/
float t0 = start.z + start.w;
float t1 = end.z + end.w;
if (t0 < 0.0) {
if (t1 < 0.0) {
return;
}
start = mix(start, end, (0 - t0) / (t1 - t0));
}
if (t1 < 0.0) {
end = mix(start, end, (0 - t0) / (t1 - t0));
}
/* Compute line axis and side vector in screen space */
vec2 startInNDC = start.xy / start.w; /* clip to NDC: homogenize and drop z */
vec2 endInNDC = end.xy / end.w;
vec2 lineInNDC = endInNDC - startInNDC;
vec2 lineInScreen = lineInNDC * window_size; /* ndc to screen (direction vector) */
vec2 axisInScreen = normalize(lineInScreen);
vec2 sideInScreen = vec2(-axisInScreen.y, axisInScreen.x); /* rotate */
vec2 axisInNDC = axisInScreen / window_size; /* screen to NDC */
vec2 sideInNDC = sideInScreen / window_size;
vec4 axis = vec4(axisInNDC, 0.0, 0.0) * line_width; /* NDC to clip (delta vector) */
vec4 side = vec4(sideInNDC, 0.0, 0.0) * line_width;
vec4 A = (start + (side - axis) * start.w);
vec4 B = (end + (side + axis) * end.w);
vec4 C = (end - (side - axis) * end.w);
vec4 D = (start - (side + axis) * start.w);
/* There is no relation between lines yet */
/* TODO Pass here t0 to make continuous pattern. */
t0 = 0;
t1 = (length(lineInScreen) + 2 * line_width) / (2 * line_width * stipple_factor);
gl_Position = A; t = t0; varying_vertex_color = varying_vertex_color_line[0]; EmitVertex();
gl_Position = D; t = t0; varying_vertex_color = varying_vertex_color_line[0]; EmitVertex();
gl_Position = B; t = t1; varying_vertex_color = varying_vertex_color_line[1]; EmitVertex();
gl_Position = C; t = t1; varying_vertex_color = varying_vertex_color_line[1]; EmitVertex();
EndPrimitive();
}
#else
void main(void)
{
}
#endif