Projecting lines on circles

Started by
35 comments, last by Medium9 14 years, 4 months ago
Glad to help, Merry Christmas =)
Advertisement
I finally got to think about how I would like to implement this, and have one big problem. It was mentioned before shortly: I will have to handle lines that pass angle 0 somehow. If I process these straight forward, they will cover almost the entire output (if near enough), which renders the whole idea somewhat useless :(

The really big problem with that is, that I am not allowed to switch to DirectX 10, with which I could solve this using a small geometry shader that splits these cases into two lines.

Is there any way at all to reference vertices that blong to the same primitive as the currently processed one in a VS using SM3? I wouldn't need to output more than before, because if I just could even detect these cases, I can work that out.

If I had to do this beforehand when creating the vertex buffer, I fear it will most likely slow things down to very unacceptable speeds. (Just calculating the atan2() for every vertex for every pixel on CPU would probably kill it, let alone refilling the entire vertex buffer on every occasion.)

I really fear that I have to scrap this extremely nice idea just because of this tiny bitty stupid issue. Please tell me that there is a way to resolve this in DX9! (If not, please say so too. That'll save some brain power (and time) used by any futile desparate attempt I may come up with now :))

[Edited by - Medium9 on December 27, 2009 12:05:26 PM]
You could draw each line twice, and simply discard every other line by setting both the points to (-1,-1,-1) or something in the vertex shader to cull it, unless you notice that two lines are required. Like include an ID in the vertex declaration, and if it's '0' always draw the line, or the first part if there are two parts, and if it's '1', either cull it away or draw the second part, if there is one.
Another solution is to always draw a line from 0 to 360, and check if you're in range for every pixel, and otherwise discard.
This is a really neat and interesting problem. I like what you're using it for.

It'd be interesting if you could somehow make use of locational coherence. Every pixel for which you do this lies next the previous pixel. So going from one pixel to the next, there will usually not be a lot of change. If you could somehow use this to optimize the algorithm, it may run even faster.

But that's just a last-level optimization that you should worry about in the end, after you have a fast individual pixel algorithm.
Erik, I fear you're already a few steps ahead :). Handling the situation could very well consist of simply culling the whole line, since they are mostly near 1-2 pixels long at most anyway, often even sub-pixel lengths. One missing might not even have such a notable impact.

But I don't yet bother with handling whether it might look odd afterwards - the issue is merely finding out in the VS that such a situation is at hand! How can I detect a line crossing angle 0 if I only have access to one vertex? (Sidenote: Vertex-IDs seem to be a feature introduced with DX10. I fear I'll have to do without them, though I could abuse my lines' z coords for something, since they're unused so far.)

In response to shurcool (I like the name; my usual gaming nick is "Shu" ;)):
This is something that's crossing my head from time to time, too. However, since I tend to use shaders, there are limited options for incremental optimizations because of the parallel processing. Working things out in a way that this doesn't get in the way... well let's just say I'm far from that right now :)
Oh and thanks for the notion of interest. Reading these forums, I often think to myself: "Anything you could be doing or asking here could be, at best, not entirely boring." There is just so much knowledge and skill around here!

[Edited by - Medium9 on December 27, 2009 3:59:43 PM]
I see, I guess sub-pixel lines will probably be culled away, or drawn exactly as a point, but you could increase the texture size until enough precision is obtained.

You could create a vertex declaration that includes the other point for each line to the vertex shader. With vertex ID I meant adding a custom ID (or use the Z coord as you said).
Like:
struct VS_Input { float4 Position : POSITION; float4 OtherPointOnLine : TEXCOORD0;};


You probably need this anyway, in order to do calculations on the line in the vertex shader. By using the line equation to determine which side of the line the "camera" is on, you can know the orientation of your line, to avoid drawing an edge-line around the whole circle. If they are only a couple of pixels long you could perhaps start by just skipping them.
You might be able to pre-calculate some things on the CPU (that can be the same for each pixel), and put in your vertex declaration. It's hard to say exactly which way will be the fastest.

So if you have a single line from 0,0 to 1,1 you create two vertices:
VS_Input points[2] = { {{0,0}, {1,1}}, {{1,1}, {0,0}}};

Or whatever other information you want to pass to the vertex shader.
Right, texcoords are available in the VS! Again a very nice idea, and so elegant and simple in retrospect. That should save both, the approach and my day :)
Big thanks again!

This topic is closed to new replies.

Advertisement