PDA

View Full Version : Vertex/UV question


Midnight Synergy
01-02-2006, 03:29 PM
I'm starting on a new project, and an old foe of mine has raised its ugly head again. In previous projects I found very in-elegant ways around this issue, but I wonder if there are better ways to deal with it.

Say I create a mesh consisting of a simple square, made up of two triangles. I want the two triangles to grab their textures from different parts of the texture image, hence the vertices need different uv coordinates along the main diagonal. As a result, I use six instead of four vertices, doubling up the main diagonal. Then each triplet of vertices gets their own texture coordinates, and off I go. The problem is that rendering the two triangles this way always leaves a hair-thin line between them. I assume this is because the two edges are drawn slightly differently, even though their vertices are at identical locations.

So, how do you get around this? I know I can make the line disappear if I use only four vertices, but then the main diagonal's texture uv must be the same for each triangle. I can also stretch one of the triangles to overlap the other a slight bit - my above "in-elegant" solution.

Has anyone dealt with this issue before?

(I use Blitz3D, if it makes a difference)

Cheers, and a very happy new year to the IndieGamer community!
Patrick

oNyx
01-02-2006, 04:15 PM
The easy solution would be using quads instead of tris. Would be odd if blitz wouldnt support something basic (haha...) as that.

Midnight Synergy
01-02-2006, 05:35 PM
Well, triangles is just one example. Using quads I would have the same issue if I put two squares next to each other, right?

oNyx
01-02-2006, 07:35 PM
Yes. Well, that one has been already discussed in the past.

http://forums.indiegamer.com/showthread.php?t=4736

(The magic search term was GL_CLAMP_TO_EDGE ;))

HTH

dima
01-02-2006, 07:41 PM
The most likely reason you see the line is due to texture filtering and using different textures. If you disable texture filtering (you should be able to in B3D) the line will disappear, but textures look jaggedy if not at 1:1 ratio.

I think by playing with texture clamping might fix this issue, I am not 100% sure how it is done and if you can do it in B3D (never used it).

However, if disabling texture filtering does not fix your problem, then it's due to something else.

EDIT: guy above mentioned clamping while I was typing message.

Midnight Synergy
01-02-2006, 08:44 PM
Onyx: Thanks again for the quick reply. Clamping works if use one bitmap image per texture... the problem is that I am using multiple pieces of the same bitmap, and so the edges of the triangles don't line up with the edges of the texture.

Dima: I'll look into texture filtering, not really familiar with it.

I might just have to stick with nudging both vertices and uv coordinates a little at the edges. It does work, but it feels like "cheating" -there should be a "cleaner" solution.

dima
01-02-2006, 09:00 PM
oops, double post ..

dima
01-02-2006, 09:04 PM
Clamping just works.. period. Doesn't matter if you use different bitmaps for each triangle, or same bitmap with different parts. If texture filtering (what makes your games textures look smooth and blurry when you get close to them instead of really pixely like quake 1 software version) is enabled, clamping should be used to ensure that when you render a triangle, no color from neighbouring texels bleed into your triangle. This IS the proper solution and is not as noticible when your triangles use same or very similar textures. Both GL and DX have options for different clamping modes. Hope this makes sence.

Fabio
01-03-2006, 04:05 AM
Wrong. The only solution to his problem as he specifically stated it is to duplicate parts of each other's texture around the UV borders he has chosen. This will make the textures bigger and may even not be feasible (if the combinations are too many).

Daire Quinlan
01-03-2006, 04:07 AM
Whats the situation in which this is necessary ? Maybe a few more details as to why you're doing it this way and we could come up with a completely different solution ? The only way I could think of having to use this would be if you had an autogenerated texture atlas of some sort for a mesh. Normally what happens in that case is that each triangle on the texture atlas actually has a 1 pixel border repeating the edge pixels to avoid precisely the problem above. Or indeed as Dima says, clamping should work. In OGL (and presumably DX) the triangles are guaranteed to rasterize correctly if the vertices are the same but naturally if the UVs are different across the edges of two triangles, they'll rasterize with slightly different interpolated color values, causing what you perceive as a seam. The eye is quite sensitive to those sort of discontinuities.

D.

dima
01-03-2006, 08:33 AM
Wrong. The only solution to his problem as he specifically stated it is to duplicate parts of each other's texture around the UV borders he has chosen. This will make the textures bigger and may even not be feasible (if the combinations are too many).Wrong. That is not the only solution.

Daire Quinlan
01-03-2006, 08:56 AM
Wrong. That is not the only solution.

well technically speaking it is actually the only way to duplicate correctly the effect of having both triangles share the same texture space. IE along the shared edge of each triangle's UV space you duplicate the pixels along the shared edge of the -other- triangles UV space. However if this was the desired effect then I don't understand why MS just doesn't do it the normal way. This was why I was asking him to clarify.

D.

dima
01-03-2006, 09:13 AM
Disabling any type of texture filtering does not produce any artifacts as long as verts have same UV and XYZ/normal coords, so that is another way to go. And anctually I would recomment not using filtering if you do not scale or rotate your graphics, sprites just look that much better. Of course without filtering things can get pretty ugly if you zoom or rotate, so clamping is introduced so other colors do not bleed over or textures do not tile.

However, if you have two separate textures that are supposed to be seamless together and you definitely are using filtering, there are ways to hide these artifacts or at least make them not as visible by using clamping, or at the last resort duplicating border pixels (which is not the best solution because you aither have to make actual textures smaller by 2 pixels so after you add the borders things stay ^2). I would personally discourage people from duplicating the border pixels. You can play around with clamping/alpha channel and/or texture filtering. You could also try rendering textured lines on top of the seams to better blend the two textures. I am sure there are other ways as well.

Midnight Synergy
01-03-2006, 06:43 PM
Whats the situation in which this is necessary ?


I'm writing a program to take a very basic tilemap and convert it into a 3d mesh that automatically includes a lot of detail (e.g. your tilemap might just some ground and a bunch of water tiles - the program creates out of that a smooth landscape with ponds/lakes). I keep all of the textures in 64x64 chunks in a single bitmap (e.g. 64 of them in a 512x512) to keep the entire level mesh as a single surface with a single texture (for a number of reasons). Hence my need to pick and choose from different pieces of the same texture for neighbouring triangles.

Anyways, it doesn't look like Blitz has native support to turn off texture filtering, and the clamping options don't make a difference (again, could be Blitz, or my particular situation). I think I'm just going to stick with my old bag of tricks of overlapping triangles and "shrinking" the uv-map a little. Thanks all for the replies.

Cheers!

vjvj
01-04-2006, 12:31 PM
When you say "thin line", do you mean a thin line of a certain color, or a thin transparent line or crack?

Midnight Synergy
01-04-2006, 01:58 PM
Definitely a "crack". When I zoom up close enough I can see whatever background is behind it shine through.

vjvj
01-04-2006, 04:03 PM
I think everyone might be misunderstanding the problem you are having then, as it is not a filtering issue.

It's most likely because either Blitz (or your app) is not using consistent winding when rendering adjacent triangles. If you have two adjacent triangles (such as a quad) with vertices:

0 3
1 2

(forgive my terrible diagram)

If, for example, you render the vertices as 0, 1, 2 and then 3, 2, 0, you will get a crack between the two triangles because the gradients for line 0->2 are not the same as the line for 2->0. I hope my crappy explanation makes sense.

If you have control over this in the app this should be an easy fix; just make sure you always use the same vertex ordering for adjacent triangles. If it's Blitz's fault, I guess you'll have to beg them to fix it for you ;)

Daire Quinlan
01-04-2006, 06:07 PM
wellll, yes and no ... If (i presume) blitz enforces a CCW or CW rule on visible triangles then this isn't the issue, as the wrong winding on the polygon would merely make it invisible. What library does blitz use behind the scenes ? is it OGL or DirectX ? either of them ought to ensure that if the vertices are the same, then a consistent rasterisation will occur. Is there an alpha channel in your texture ? If you have a texture atlas (which is more or less what you seem to be describing above) with an alpha channel then maybe some alpha is being filtered into your edge texels ?

An easier way to do this might be doing the terrain rendering in several different passes, one base pass, and then one per texture. I use it to some effect for my terrain (see sig) done in Java using Opengl (JOGL bindings). Demo is pretty old though. Its since been optimized a little better to do 3 textures per pass.

D.

vjvj
01-04-2006, 07:44 PM
I don't know anything about Blitz3D, but my guess is that he's using some form of immediate mode rendering to render these quads. This would explain why, for example, backface culling may not be happening. Additionally, I would assume that Blitz3D can't assume backface culling is on all the time, as that would complicate rendering in certain cases.

The graphics driver usually makes sure vertex ordering is the same, but I believe that's only for indexed primitives.

MS will need to give more information before we can really find out what's wrong...