Let me preface this by acknowledging that I suck at math.
I'm trying to billboard a volumetric spline ribbon with the option to keep it constant width. I don't want to project the end result, because I still want it to be depth tested. Here's the relevant bit from my geometry shader with my own comments on what I think the math does. I'm pretty sure I'm wrong, though:
// seg has two points, a and b, whose position is in world space
// convert the end points to view space
vec4 vsp1 = gd_matModelView * vec4(seg.a.position.xyz, 1);
vec4 vsp2 = gd_matModelView * vec4(seg.b.position.xyz, 1);
// direction is an interpolated normal along the spline at knots (seg.a.position and seg.b.position);
// convert these to view space as well
vec4 vsn1 = gd_matModelView * vec4(seg.dir1, 1);
vec4 vsn2 = gd_matModelView * vec4(seg.dir2, 1);
// project and normalize
dir1 = vec3(normalize(vsn1.xy), 0);
dir2 = vec3(normalize(vsn2.xy), 0);
// this part is definitely wrong, but I'm not sure what it should be; the idea is to avoid
// segments whose end points change orientation from becoming twists (see below screenshot).
// I'm basically trying to smooth out the discontinuity that arises at oblique angles.
if(dot(dir1, dir2) < 0)
dir2 = -dir2;
// calculate the right vectors in view space
vec3 n1 = vec3(-dir1.y, dir1.x, 0);
vec3 n2 = vec3(-dir2.y, dir2.x, 0);
....
// the segments are issued as:
// vsn1 + n1 * thickness1
// vsn1 - n1 * thickness1
// vsn2 + n2 * thickness2
// vsn2 - n2 * thickness2
....
// and finally, vertices are emitted after converting to clip space:
gl_Position = gd_matProjection * position;
There are several issues here, most of which are hilighted in the screenshot below. For this example I set the line thickness to something constant. The thickness is not adjusted for by distance.
From most directions the ribbon actually seems fine, but when the camera points increasingly down the direction of the spline:
1) the ribbon generates a twist
2) projection does not seem to work the way my little brain assumes it should
What am I doing wrong?
↧