Jump to content
  • Advertisement
  • entries
    422
  • comments
    1540
  • views
    490116

Yay!

Sign in to follow this  
jollyjeffers

945 views

So it seems that I cracked the UVAtlas problems. Yay[attention][attention]...

The Problem
One of the most common ways of creating a 3D terrain mesh is to use a "heightmap" - where a grid of equally spaced vertices are each given a height. My big problem was with the texture mapping used by most heightmap implementations. Or, at least, MY heightmap implementations!.

The original grid of vertices was simply assigned a regular 0.0-1.0 texture coordinate based on their grid position - with no regard to the height at any point. A suitably large texture would then be loaded into video RAM and effectively "draped" over the terrain.


(Click To Enlarge)


In the above image we see the problem quite clearly. The texture being used is a blue/white/black "checkerboard" - the colour alternates every pixel. Thus each "dot" that you can make out is actually one pixel's worth of texture.

Notice where the arrows are pointing. Two of them point to areas where the texture is horrifically blurred due to stretching (not enough pixels for the size of the triangle). The remaining arrow is pointing at an area where there is a very high density of pixels being mapped to a relatively small area of triangles.

If you look at the terrain from directly above, preferrably orthogonally, then these errors disappear.


The Solution


(Click To Enlarge)


The above image shows the same piece of terrain with modified texture coordinates. The texture coordinates now map to the source texture based on the surface area of each triangle. Small triangles get allocated few pixels, large triangles get allocated a larger number. This eliminates the stretching as well as the over-dense areas. Compare the three areas being pointed at in the first image, and you'll see they are vastly improved in this second image.


(Click To Enlarge)


The above image shows the texture-map generated using the D3DX UV-Atlas tools. The magenta areas are unused pixels, which could possibly be better utilized. The tool has divided up the mesh into a series of 'charts' and then attempted to optimally place them inside the texture.


(Click To Enlarge)


The two images above show how the UV map is actually placed over the mesh. As seen in the previous image, I coloured each of the charts so as to make it easy to identify them. On the right is an untextured view, but with the boundaries marked in orange.

Where Next
Right, that's all I have to say on the topic for now. Once I've worked out how I created my solution I'll post it here. It's probably the most fugly code I've written in a long time, so don't expect a demo - just the important snippets [wink]

After that I'm going to see if I can improve the IMT calculations (more on these next time), I'm wondering if tweaking them (as well as the many other params) can generate even better UV mappings.
Sign in to follow this  


9 Comments


Recommended Comments

Guest Anonymous Poster

Posted

How much time do you spend for actually writing a post in your journal? :O

Share this comment


Link to comment
Top work!
Maybe I'm being dense here, but is there a reason you couldn't just warp the texture coordinates so that the points are denser over the larger triangles rather than splitting up your texture? The results would probably be less accurate, but I'd have thought it neater to work with the entire texture being mapped cleanly over the entire surface (and easier to edit).

Share this comment


Link to comment
Quote:
Very cool. [smile]

Thanks!

Quote:
How much time do you spend for actually writing a post in your journal?

This one probably took 30mins or so, including gathering the screenshots, writing the text, uploading it...

Quote:
Maybe I'm being dense here, but is there a reason you couldn't just warp the texture coordinates so that the points are denser over the larger

That's not dense - it is a possibility [smile] I wanted to see how the D3DX functions worked... All the "grunt work" so far is handled by a call to D3DXUVAtlasCreate() - no complex algorithms in my code [wink]

The only problem with your method that I can see, is that if you start stretching one area (to give better resolution to a big triangle) you *have* to shrink another area... which could be a knock-on effect.

Thanks for the comments!
Jack

Share this comment


Link to comment
So, it looks like you have the same seams problems than me.

The area pointed by the red arrow in your second image, shows a complete texture coordinates mess. In addition, seams are visible near the boundaries between charts...

IMO you have traded one problem (stretching) for another issue (seams). This technique also doesn't work well with dynamic terrain LOD, as the mapping is pre-processed.

Share this comment


Link to comment
To pick up Ysaneya's point, would this technique be calculatable enough for real-time use in a LOD terrain system?

Share this comment


Link to comment
Again, thanks for the feedback - some interesting points [smile]

Quote:
The area pointed by the red arrow in your second image, shows a complete texture coordinates mess.

Yup, that is true. The texture that I'm using isn't a particularly good example - I'm working on a better "test" to see if it's actually a problem.

The big artifact that I envisage is that of neigbouring texels being different sizes - a small triangle next to a large triangle will have a border between different sized sampling points.

Quote:
IMO you have traded one problem (stretching) for another issue (seams).

Very true. Given time for a bit more experimentation I wonder which will prove to be "lesser of two evils".

uniform texture mapping gives some blurry textures but less/no actual artifacts.

UVAtlas mapping gives a better ratio but can generate seams and artifacts.

Quote:
would this technique be calculatable enough for real-time use in a LOD terrain system?

It's not really a real-time algorithm - very much a pre-processing step. I haven't actually timed it, but the mapping I've shown took around 5-10 seconds to generate.

If you wanted to combine it with LOD then you'd probably have to generate several layers of UV-mapping's... [oh]

Share this comment


Link to comment
YAyyy, I am visiting you journal again. Hmm looks a bit messy? Whats up with the sink, dont you know how to wash dishes or something?

Anyways... Someone should rate you up and send you over to the Eighteenth Century, the Age of Enlightenment. Will have more on topic after I read your entry.

Share this comment


Link to comment
Quote:
YAyyy, I am visiting you journal again. Hmm looks a bit messy?

** Jack gets coloured pens and gradient-text tool out ** [evil]

I'm quite happy with the 21st century for now, why would I want to go back to the 18th? [smile]

Cheers,
Jack

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!