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:
authorClément Foucault <foucault.clem@gmail.com>2020-10-08 22:06:58 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-10-08 22:12:29 +0300
commite90638b9118ba0ef7083604a70768135bfe7d07d (patch)
tree73b2d7b7bcfc3a680b3fe051dbeef3ea076eab7e /source/blender/gpu/shaders
parenta31a87f8943aa4029ff0f23a6dc46f5d0c895e8b (diff)
Fix T80974 GPU: Wide Line emulation shader does not always works
This was caused by points well behind the near clip making the computation of the width wrong. The fix is to clip the line to the near clip plane.
Diffstat (limited to 'source/blender/gpu/shaders')
-rw-r--r--source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl37
1 files changed, 27 insertions, 10 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl
index cca94680284..fd9b7e221e6 100644
--- a/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_geom.glsl
@@ -20,7 +20,23 @@ noperspective out float smoothline;
#define SMOOTH_WIDTH 1.0
-void do_vertex(const int i, vec2 ofs)
+/* Clips point to near clip plane before perspective divide. */
+vec4 clip_line_point_homogeneous_space(vec4 p, vec4 q)
+{
+ if (p.z < -p.w) {
+ /* Just solves p + (q - p) * A; for A when p.z / p.w = -1.0. */
+ float denom = q.z - p.z + q.w - p.w;
+ if (denom == 0.0) {
+ /* No solution. */
+ return p;
+ }
+ float A = (-p.z - p.w) / denom;
+ p = p + (q - p) * A;
+ }
+ return p;
+}
+
+void do_vertex(const int i, vec4 pos, vec2 ofs)
{
#if defined(UNIFORM)
finalColor = color;
@@ -38,21 +54,22 @@ void do_vertex(const int i, vec2 ofs)
#endif
smoothline = (lineWidth + SMOOTH_WIDTH) * 0.5;
- gl_Position = gl_in[i].gl_Position;
- gl_Position.xy += ofs * gl_Position.w;
+ gl_Position = pos;
+ gl_Position.xy += ofs * pos.w;
EmitVertex();
smoothline = -(lineWidth + SMOOTH_WIDTH) * 0.5;
- gl_Position = gl_in[i].gl_Position;
- gl_Position.xy -= ofs * gl_Position.w;
+ gl_Position = pos;
+ gl_Position.xy -= ofs * pos.w;
EmitVertex();
}
void main(void)
{
- vec2 p0 = gl_in[0].gl_Position.xy / gl_in[0].gl_Position.w;
- vec2 p1 = gl_in[1].gl_Position.xy / gl_in[1].gl_Position.w;
- vec2 e = normalize((p1 - p0) * viewportSize.xy);
+ vec4 p0 = clip_line_point_homogeneous_space(gl_in[0].gl_Position, gl_in[1].gl_Position);
+ vec4 p1 = clip_line_point_homogeneous_space(gl_in[1].gl_Position, gl_in[0].gl_Position);
+ vec2 e = normalize(((p1.xy / p1.w) - (p0.xy / p0.w)) * viewportSize.xy);
+
#if 0 /* Hard turn when line direction changes quadrant. */
e = abs(e);
vec2 ofs = (e.x > e.y) ? vec2(0.0, 1.0 / e.x) : vec2(1.0 / e.y, 0.0);
@@ -62,8 +79,8 @@ void main(void)
ofs /= viewportSize.xy;
ofs *= lineWidth + SMOOTH_WIDTH;
- do_vertex(0, ofs);
- do_vertex(1, ofs);
+ do_vertex(0, p0, ofs);
+ do_vertex(1, p1, ofs);
EndPrimitive();
}