Skip to main content
GameDev.net gamedev.net
🔒 Locked

Precise triangle rasterization

Started by yahastu Mar 29, 2009 at 10:37 AM 5 replies 3.3k views
Original Post
yahastu
yahastu
I'm writing some software to render to texture based on vertex colors (no texture map at this point). There are often many triangles with shared vertices in a UV map, so in order to prevent ambiguity about triangle borders, I'm only filling the pixels which are inside the edges of the triangle (shown as green dots). However, since this is used as a texture map with bilinear interpolation for texture lookups, pixels outside of this area will influence the texture and cause visible seams. The bilinear interpolation grid is shown in pink. The pixels that should influence the texture that are not inside the triangle shown in red. I can't seem to figure out a clean and simple solution to this problem. One idea I had was to do the rendering in two passes: in the first pass, whenever I render a triangle, I calculate the edge normals, push the edges out 1 unit in the normal direction, then re-intersect them and render the area under the triangle. Then in the second pass, I can render on top of this texture the normal sized triangles. This idea doesn't work, because (a) it can result in enlarging triangles much more than they need to be in some dimensions, possibly causing overlap problems; (b) it doesn't always cover all the pixels that would be needed for bilinear interpolation anyway; (c) it doesn't work for degenerate triangles, which still need to have area covered in the map (see the bottom figured triangle). Another idea is to render the interior parts of triangles first, and then do a second pass and try to fill each pixel that has an 8-connected neighbor to a previously written pixel. But this would not work for triangles that are thin and manage to squeeze between 2 pixels. Even if I can figure out a simple way to fill the necessary pixels, it's not totally straightforward to figure out what color to interpolate there based on the vertex colors. I suppose the gradients could be extended, and then cropped for over/under saturation.. Anyway, I thought maybe these issues have been tackled before, any advice or resources would be appreciated
Thaumaturge
Thaumaturge
Hmm... I may well be missing something, but could you not determine which squares (defined by sets of four pixels) the edges of a given triangle pass through (a simple line-segment-line-segment intersection springs to mind, although there might be better methods; a sweep line algorithm, perhaps), and mark the pixels associated with those squares as part of the desired result set?

Of course, I'm not at all sure of the efficiency of such a tactic, but it might be of use.

I'm afraid that I also don't have a suggestion for the colour interpolation offhand. :/
MWAHAHAHAHAHAHA!!! My Twitter Account: @EbornIan
yahastu
yahastu
Thaumaturge,

Thanks for taking a look! That's a great suggestion(++). I didn't think of it before because I wasn't drawing the lines out like this in my diagram, sometimes it just helps to have an extra pair of eyes to see that.

As for the question of what color to interpolate there, well..I've figured out a solution to that, as well :) Basically, you can over-interpolate the X,Y,Z values in texture space off of the edge of the triangle, and then use that to look up a texture value spatially, even if the (u,v) coordinates do not map anywhere onto the model surface. This solves the problem.
Thaumaturge
Thaumaturge
I'm glad to have been of help, and glad that you found a solution to the interpolation issue. ^_^
MWAHAHAHAHAHAHA!!! My Twitter Account: @EbornIan
ddyer
ddyer
This is definitely not something you want to invent yourself on
an ad-hoc basis - there is a perfect solution that works and is
simple to implement.

The standard algorithm for this involves setting up a difference
equation for each edge, with precise (and obscure to me) initial
conditions. The triangle is rasterized one row at a time, and the
step to the next row involves just one add/compare step to see if
the start or end of the row changes. I don't have the actual code
handy any more, but I would check graphics gems.

---visit my game site http://www.boardspace.net - free online strategy games
popsoftheyear
popsoftheyear
Instead of a grid of infinitely small dots with spacing in between them, re-imagine your grid as a grid of pixels. So each one of your squares is a pixel, and the dots are just the top left hand corner of each pixel. Now, rasterize your triangle based on which pixels is crosses into. There are methods to avoid overdraw on the edges, but this is a good place to start.

As for rendering, typically you start at the top of the triangle, and work your way to the bottom, tracking the left and right sides of it, interpolating the left and right colors in your case as you go. While doing this, you draw each scan line, interpolating the color across the scan line, given your current left and right color values. It can get rather complex when you move up to other parameters like texture coordinates, normals, inverted z-values, etc.

Best bet is to find some source code on this, see how it works, then try to come up with your own. You definitely will want to get a basic rasterizer down before worrying about 1 pixel overdraws on the edges, as it's not going to matter much unless you start using alpha blending on your triangles.

Cheers
Hello Kitty
Hello Kitty
If your question is about rasterization, then RUN dont walk to chris heckers website, and his pixel perfect triangle rasterizer.

http://chrishecker.com/Miscellaneous_Technical_Articles

Dont use any other rasterizer for the rest of your life!


-goodbye-

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.