HLSL - Convert Normal map to Parallax Occlusion Map

Started by
4 comments, last by Hodgman 10 years, 6 months ago

Hi guys! happy.png

Just a quick question.

I've had parallax occlusion mapping implemented for a while now, but I soon realized that problems came, not every artist wants to create a parallax occlusion compatible map just for some bricks, they've already made some normal maps, but unfortunately they aren't compatible. (Not that I know of...)

  • So how would you be able to convert a normal map to a pom map in realtime, preferably in hlsl?
  • Is the performance worth it? dry.png

I've seen some offline examples, but again, is this possible in runtime?

Thanks, as usual.

-MIGI0027

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

Advertisement

And how (If possible), would you convert it the other way: Parallax -> Normal?

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

You just need a height map for POM, so there's nothing to "convert" really. You can put the height value in the alpha channel of the normal map if you want as a convenience/optimization, but you can also keep it separate. Usually normal maps are generated from height maps, so your artists should be able to get you one. If you're using a tool like xNormal to bake a normal map from a high-poly mesh it can spit out a height map for you. Or a tool like CrazyBump can try to auto-generate a height map from a color map, although this is an imperfect process. Usually these sorts of tools first generate a height map when you ask them to make a normal map from a color map, and they typically do this by generating height values based on the luminosity of the texel.

There is no way to do this properly, at least not in real-time. A parallax-map works by giving the height-offset at a certain point, while a normal map does just that - give the normal vector at a certain spot. You can't directly judge from one of those properties to the other - a normal with (0, 1, 0) at a certain point might be at height 0 or at height 2,5, speaking in geometry. So you'd at least have to look at the whole texture to get a somewhat passable value. Its a bit like creating a normalmap from a diffuse texture - it works (offline), but is never nearly as good as creating a normal map from a high-res model. So, no, AFAIK there is no such way (at last in real time).

Well that was what I was fearing. MJP: About putting the height in the alpha channel of the normal map, that would be a useful way without wasting any (almost) resources, the only problem is if I don't have a heightmap, just the normal map.

Anyway, thanks for giving me this information. smile.png

-MIGI0027

FastCall22: "I want to make the distinction that my laptop is a whore-box that connects to different network"

Blog about... stuff (GDNet, WordPress): www.gamedev.net/blog/1882-the-cuboid-zone/, cuboidzone.wordpress.com/

You can kind-of convert a normal-map back into a height-map. The normal map defines slopes per pixel. If you step from one pixel to the next treating all the slopes as lines (in 1d) or planes (in 2d), and fitting them all so they connect to their neighbours, then you end up with a surface that you can calculate the height of per pixel. Depending on where you start this process from, the whole surface will be shifted up or down, so you'll want to renormalize the heights, by offsetting them all so the average height is 0, or 127 or whatever.

e.g.

dKjiybr.png

If a 2D normal map isn't based on a physical model, or simply due to quantization errors in the normal map, this surface might be impossible, like an Escher-esque staircase. I guess you'd want to apply neighbour constraints in a few iterations, in different orders to converge towards the most sensible solution, which is obviously going to be slow...

IIRC, the nVidia photoshop plugin has a filter that can do this for you, so you could ask the artists to generate them that way.

Or, you could implement this algorithm yourself and either execute it on your loading screen, as each normal map is loaded from disk, or make it into an executable that you can use to batch-process all of the normal map files ahead of time.

This topic is closed to new replies.

Advertisement