Billboarding a line

Started by
14 comments, last by irreversible 6 years, 12 months ago
8 minutes ago, iedoc said:

I'm not sure exactly what your doing in your geometry shader to get the final position, but it looks to me like your not taking the camera position into account. For the dot product, you should dot the normal of your segments with the camera-to-segment direction.

something like this maybe:



dot(segmentNormal, camPosition - segmentPosition) > 0) // reverse segment direction because segment is now facing away from camera

 

Trying not to sound dumb here, but doesn't transforming the WS position with the modelview matrix get me to view space, which is already camera-relative? If I then discard Z, then my coordinate should effectively be in screen space. Insofar as I follow the math, I'm transforming the WS end points to views space, then I project the spline directions at either endpoint to screen space and compute the 2D normals (right vectors)*, which are implicitly camera-aligned orthogonal vectors to the view space point. Right?

Finally, transforming by the projection matrix gets me to clip space.

 

* this would akin to calculating normalize(cross(endNormal, camPosition - endPosition))

Advertisement

oh yeah, your right, that does actually make sense. But since your z is bigger the further away from the camera, when you multiply by the projection matrix the width of your ribbon will get smaller the further away it is, if your using the same width all the way through.

I'll have to think about your code a little longer to figure out why it appears to be twisting and turning so much. are seg.a and seg.b the left and right side of the ribbon?, and seg.dir1 and seg.dir2 are the direction the ribbon is flowing from the two points?

can you try this? (if it works probably want to pull out the dot so you don't have to do it twice)


if(dir1.z - dir2.z < 0 && dot(dir1, dir2) < 0)
	dir2 = -dir2;
else if(dir2.z - dir1.z < 0 && dot(dir1, dir2) < 0)
	dir1 = -dir1;

 

4 minutes ago, iedoc said:

are seg.a and seg.b the left and right side of the ribbon?, and seg.dir1 and seg.dir2 are the direction the ribbon is flowing from the two points?

No - these are midpoints at either end of a spline segment.

Given a 3-point spline { p0, p1, p2 }, the two segments that are drawn by the above shader are:

1)

seg.a.position = p0
seg.b.position = p1

dir1 = normalize(p1 - p0)
dir2 = normalize(lerp(p1 - p0, p2 - p1, 0.5))

2)

seg.a.position = p1
seg.b.position = p2

dir1 = normalize(lerp(p1 - p0, p2 - p1, 0.5))
dir2 = normalize(p2 - p1)

 

(actually the directions for the first and last points are derived from adjacency information, but that's irrelevant here)

 

15 minutes ago, iedoc said:

can you try this? (if it works probably want to pull out the dot so you don't have to do it twice)



if(dir1.z - dir2.z < 0 && dot(dir1, dir2) < 0)
	dir2 = -dir2;
else if(dir2.z - dir1.z < 0 && dot(dir1, dir2) < 0)
	dir1 = -dir1;

 

This makes no difference. And I'm not sure why it should... It doesn't matter which normal I flip - either should do the trick.

Frankly, it doesn't even make sense to me that the twist happens over the the course of several segments (this implies that the code is wrong on a more fundamental level). It should be a discontinuity, which occurs at a single point, which is dependent on the position of the camera.

This topic is closed to new replies.

Advertisement