Jump to content
  • Advertisement
Sign in to follow this  
Chris_F

Getting the most out of my normals

This topic is 2522 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm concerned about the precision of my normals and storing them efficiently. So there are two issues. The format I store them in the texture, and the format I store them in the gbuffer.

The simplest solution is to use RGB8 normal map textures and store them into an RGB8 portion of a render target. I'm not particular pleased with the amount of precision this gives you, since you are using less than 2% of the 24-bit space to actually store your normal vectors. Crytek's "best fit normals" are interesting, since they make use of nearly 98% of the 24-bit space, but linear interpolation would wreck the results, which makes it only useful for storing normals in the gbuffer. Also, unless you really need to find an extra 8-bits of gbuffer, why not just store them as R10G10B10? That should offer even better precision than the BFN method, and it wouldn't require any expensive encoding.

For storing them in a texture, I could use R16G16 to store the X and Y components at 16-bit precision, and reconstruct Z. This should work as long as Z is never negative. Is it ever valid for Z to be negative in a tangent normal map?

Share this post


Link to post
Share on other sites
Advertisement
If you're not worried about memory consumption, then I'm sure that storing XY an R16G16_SNORM texture will give you pretty awesome precision. But if memory consumption is an issue, then you'll have to compare against BC5 and judge whether the extra quality is worth consuming 4x the memory (perhaps even on a per-texture basis).

Share this post


Link to post
Share on other sites
I wonder what format Crytek saves their normals in. I don't think it would make any sense to use their Best Fit Normals in the gbuffer if their source was coming from a BC5 encoded 8-bit X&Y normal map. huh.png

Share this post


Link to post
Share on other sites
It definitely still makes sense to maximize precision in the G-Buffer, since the normals you store in a G-Buffer are transformed versions and interpolated versions of the normals in your normal maps. Even a perfectly flat plane with no normal maps can exhibit precision artifacts if your G-Buffer has insufficient normal precision (especially if you store view space normals).

Share this post


Link to post
Share on other sites
How about tangent normal maps? Sometimes I see tangent normal maps with different signs in the Z channel? If it's sometimes correct for a tangent normal map to have a different Z sign, then X&Y compression can't work for all normal maps.

Share this post


Link to post
Share on other sites
you are right, without some tricks, two channels are not enough to save XYZ -> in general, you need at least two channels + 1bit for the sign of the 3rd channel if you stay in the same coordinate system, there is a good comparision of various gbuffer formats for normals, check out
aras-p.info/texts/CompactNormalStorage.html (it's somehow down for me atm)

Share this post


Link to post
Share on other sites

you need at least two channels + 1bit for the sign of the 3rd channel if you stay in the same coordinate system

This is almost right. Some transformations on aras page(i.e. method 4&7) already consider the negative z axis. Atleast most of it, there're still some values which are 'unsafe' like -1 or almost near -1. But in general this resolution is enough to handle the normals in a gbuffer with only two channels. And, an other important advantage is, that you can use interpolation of normals without fearing many artifacts.

Share this post


Link to post
Share on other sites

[quote name='Krypt0n' timestamp='1326793220' post='4903562']
you need at least two channels + 1bit for the sign of the 3rd channel if you stay in the same coordinate system

This is almost right.[/quote]which part is wrong?
Some transformations on aras page(i.e. method 4&7) already consider the negative z axis.[/quote]
when you transform into a different coordinate system (4=spherical ; 7=parabolid(?)), then it works, but staying in the (orthogonal) 3d cartesian coordinate system, forces you to save the sign of the 3rd channel/axis, no way around it, as long as you use bumpmaps. but it's usually not of an issue in the gbuffer, as you don't interpolate anyway.

Share this post


Link to post
Share on other sites
I know that the Z will point away in the g-buffer, which is why I'm planning on using the sphere map technique. I would consider the X&Y approach useless for g-buffer packing. I'm more concerned about how I store the textures. It seems to me that it would make no sense to have negative Z in a tangent space normal map, in which case X&Y would be perfectly fine in all cases. And yet when I do a Google image search for normal maps, it doesn't take very long to find examples of tangent normal maps with both positive and negative Z values.

Share this post


Link to post
Share on other sites
I'm having difficulty thinking of a case where it would make sense to have a negative Z value in a normal map. It would literally mean that the surface points inward at itself. Maybe for some weird special-case scenarios, but not for your typical "generated from a heightmap" or "generated from a high-poly base mesh" scenarios. So I don't think that you have anything to worry about.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!