Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Disclaimer: kindly right click on the images and open them separately so that they're at full size, as there are fine details which don't show up otherwise. Thank you.

I made a simple Blender model, it's a cylinder with the top cap removed:

enter image description here

I've exported the UVs:

enter image description here

Then imported them into Photoshop, and painted the inner area in yellow and the outer area in red. I made sure I cover well the UV lines:

enter image description here

I then save the image and load it as texture on the model in Blender. Actually, I just reload it as the image where the UVs are exported, and change the viewport view mode to textured. When I look at the mesh up-close, there's yellow everywhere, everything seems fine:

enter image description here

However, if I start zooming out, I start seeing red (literally and metaphorically) where the texture edges are:

enter image description here

And the more I zoom, the more I see it:

enter image description here

Same thing happends in Unity, though the effect seems less pronounced. Up close is fine and yellow:

enter image description here

Zoom out and you see red at the seams:

enter image description here

Now, obviously, for this simple example a workaround is to spread the yellow well outside the UV margins, and its fine from all distances. However this is an issue when you try making a complex texture that should tile seamlessly at the edges. In this situation I either make a few lines of pixels overlap (in which case it looks bad from upclose and ok from far away), or I leave them seamless and then I have those seams when seeing it from far away.

So my question is, is there something I'm missing, or some extra thing I must do to have my texture look seamless from all distances?

share|improve this question
    
I'm guessing this is a mipmapping issue. See this question about generating mipmaps: gamedev.stackexchange.com/questions/11907/… –  Byte56 Feb 25 '13 at 21:47
    
Well ok, you're probably right about the reason, but is there some way to fix it. I.e. in Unity I see there's no control over what mipmap level is chosen (and you can't disable it all together either). Make the texture in a resolution closer to the mipmap level used most of the time (so that it no longer mip maps)? Use DDS format? –  Shivan Dragon Feb 25 '13 at 22:01
3  
@ShivanDragon you can disable mipmaps on a per-texture basis. You'd need to go into the advanced import settings to do so. –  Tetrad Feb 25 '13 at 23:24
    
@Tetrad thanks for the info. I will do that. –  Shivan Dragon Feb 26 '13 at 10:25
add comment

1 Answer

up vote 10 down vote accepted

You can't.

All right, that was a bit harsh. Let me illustrate this with two examples.

  1. Let's get outside of the computer graphics world. Suppose you are given a piece of paper with the texture you gave us printed on it. There's a faintly printed millimeter grid in the paper as well.

    Now you get some scissors and some paste, and your task is to make a cylinder out of the piece of paper, but you can only cut exactly through the millimeter grid. No problem! the printed paper was originally created in such a way the yellow and red parts fall exactly on the millimeter grid, so you make your cylinder with no problem.

    Now your task is to make a cylinder half the size. To do this, you get a piece of paper half the size with everything printed half the size. This is where your problems start. Some of the yellow-red borders will fall on the millimeter grid, but others won't. And for those that don't, you can either cut on the yellow or the red parts. Which one is more correct? It depends. Sometimes it's the yellow one, sometimes it's the red one, sometimes it's neither...

  2. So let's get back into the computer graphics world. Let's try to do what you're asking the GPU to do when you're asking it to create mipmaps. Take your large texture and resize it into a texture exactly half the size of the original one. What happens at the yellow-red borders? Well, it depends. It depends on the filtering algorithm you use when scaling your texture down.

    If you use "Nearest neighbor", you will preserve your abrupt yellow-red changes, but some borders (to be precise, those that fall in an odd coordinate in the original texture) will be forced to either side of the pixel grid, and the texture coordinates you originally carefully chose will no longer match the yellow-red border.

    If you use "Bilinear filtering", things are not really better. When the yellow-red border doesn't fall in the pixel grid as before (once again, when the border lies on an odd coordinate in the original texture), the resulting pixel will neither be red or yellow. It will be more like orange! Is this acceptable? I don't know.

You will notice that the problem is limited to the yellow-red borders that fall in odd coordinates. You can say "no problem!" and make sure all the yellow-red borders fall in even coordinates, and problem solved! Or is it?

Actually not. The problem will be solved when creating the first mip level. But when you create the next mip level, which is a texture one quarter of the size of the original, you will experience the same problem with the yellow-red borders that don't fall in an even coordinate in the half-size texture, which happen to be those that don't fall in a multiple of 4 coordinate in the original texture.

So even if you fix it for the second mip level, you will never solve the entire problem. You will just be taking it to a lower mip level.

As you can see this is not a problem with the game engine you're using. It's a problem with mipmapping in general. So does this mean that mipmapping is useless and should be disabled? Actually no. Mipmapping is very useful. You're just using it wrong. Actually, you said the answer yourself:

spread the yellow well outside the UV margins, and its fine from all distances

It seems like an ugly hack, but it's actually not. However, I have a more general solution I hereby call the "First Panda Pajama Rule of 3D skinning".

Don't map abrupt UV coordinate changes to abrupt texture changes.

You're experiencing this problem because you're matching an abrupt texture change (yellow to red) to an abrupt texture coordinate change (the change between the cylinder and the void (or the cap, when you close the cylinder). You want to avoid this when skinning, precisely to avoid the problem you're describing.

Corollary:

If you must make an abrupt UV coordinate change, don't put an abrupt texture change (like your proposed solution of spreading the yellow). If you must make an abrupt texture change, make it so it doesn't require an abrupt UV coordinate change (you should usually prefer doing this)

You can take advantage of the fact that, unlike when you're making models out of paper and paste, the shape of your texture does not have to match the shape of your model. When making the texture for the cap of your cylinder, you don't have to make it round. In fact, I'd make it rectangular so I can match it to the texture of the sides of the cylinder precisely to avoid abrupt UV coordinate changes between the sides and the caps (look for "Filters->Distort->Polar Coordinates" in Photoshop).

I'd also align the left and right borders of the cylinder texture to the left and right borders of the texture, and set the texture mapping to wrap, so the texture wraps nicely around the cylinder.

share|improve this answer
2  
+1 for "Don't map abrupt UV coordinate changes to abrupt texture changes." –  bummzack Feb 26 '13 at 7:16
    
Thanks for the very detailed answer. I stumbled upon some of the things you mentioned while googling for a solution, but you're explanation clears up alot of follow-up questions I was having. I'll try fixing this this evening using your advices (and an actual texture). –  Shivan Dragon Feb 26 '13 at 8:38
    
Actually there's one aspect I didn't get too well: disabling mipmaps. I understand the theoretical implications: no mipmaps = more video memory needed = sometimes not all texture will fit in there = more memory rewrites = slow downs. However I've stumbled over articles saying that this can be a real option, and it should be tested. Is this true? Is it a good practice to disable mipmaps for certain games if the thing still appears to run decently? –  Shivan Dragon Feb 26 '13 at 8:41
3  
@ShivanDragon I think you may be misunderstanding mipmaps. Mipmapping is a technique that makes rendering faster when drawing small things, by trading some video memory (you can also reduce aliasing with mipmapping and trilinear filtering, but that's a different story). By enabling mipmaps, you will actually consume more memory. In general, for 3D you want to have mipmapping enabled, so I don't recommend you disable it. Wikipedia's article on mipmapping is quite good, so you should check it out. –  Panda Pajama Feb 26 '13 at 9:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.