LordHippo Posted January 9, 2012 Share Posted January 9, 2012 Hello everyone, I've implemented a really handy method for storing normal values in the gBuffer developed by Crytek. The main idea is simple. The default way of storing normalized normals in the gBuffer, only uses some parts of RGB values. As you know there are 256*256*256 values for a RGB value (with 8 bit buffers). So mathematically there are 16,777,216 values. But when using normalized values, only 289,880 values are used. So only %1.7 of values are used As you can see in the top image there are some artifacts in the reflected image. This is not beacause 8-bit colors are not sufficient for storing normals, it's because we're wasting it completely The simple way is to use 16 bits for normal buffer. But it would use twice the memory, and is slower. This method tries to fit the normals in 8 bits with the quality of 16-bit normal buffer . It tries to find the best length for a given normal direction, that when scaled and stored in 8 bits, are the closest possible to direction of original normal. The length scales are pre-calculated and saved in a cubemap. So when storing normals in the gBuffer, all you have to do is to lookup the normal direction in the cubemap, and scale the normal by the value read from the cubemap. So as you can see the second is much better and almost has no artifacts. Then the cubemap lookup is turned into a 2D texture lookup that has only one channel (TEXTURE_ALPHA8) which is really fast. In my framework I load and bound the lookup texture in the beginning of gBuffer generation, so the bandwidth is saved. So by using this method GPU memory, bandwidth, and time could be saved with NO drawbacks B) Note: The texture attached is provided by Crytek. NormalsFittingTexture_2.rar Quote Ali Salehi | Programmer Intel Core i3 2100 @ 3.0GHz | GeForce GTS 450 | 4GB DDR3 RAM | Windows 7 Ultimate x64 LE 2.50 | Visual Studio 2010 | RenderMonkey 1.82 | gDEBugger 5.8 | FX Composer 2.5 | UU3D 3 | xNormal 3.17 Link to comment Share on other sites More sharing options...
Josh Posted January 9, 2012 Share Posted January 9, 2012 I don't understand how this compression works. The scale of the normal should always be 1.0. Does it store a coordinate point, with 8 bits for each axis, that when pointed at results in the closest normal? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
LordHippo Posted January 9, 2012 Author Share Posted January 9, 2012 I don't understand how this compression works. The scale of the normal should always be 1.0. No, it's not necessary. It can be normalized in every shader that reads normal from gBuffer. I think most of the LE's shaders does this currently. Quote Ali Salehi | Programmer Intel Core i3 2100 @ 3.0GHz | GeForce GTS 450 | 4GB DDR3 RAM | Windows 7 Ultimate x64 LE 2.50 | Visual Studio 2010 | RenderMonkey 1.82 | gDEBugger 5.8 | FX Composer 2.5 | UU3D 3 | xNormal 3.17 Link to comment Share on other sites More sharing options...
Josh Posted January 9, 2012 Share Posted January 9, 2012 Then it's not a normal, it's a vector. But yeah, I see what you're saying. It's surprising to me that a short vector would have more accuracy in some situations. I can't really picture a situation where a shorter vector would be more accurate than a longer one, since you will always have a greater resolution of pixels further away from the origin. That is pretty nice. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
LordHippo Posted January 9, 2012 Author Share Posted January 9, 2012 Then it's not a normal, it's a vector. But yeah, I see what you're saying. It's surprising to me that a short vector would have more accuracy in some situations. I can't really picture a situation where a shorter vector would be more accurate than a longer one, since you will always have a greater resolution of pixels further away from the origin. That is pretty nice. Yeah, mathematically it's not a normal. But here in the picture you can see errors for different lengths as blue lines. So as you can see longer is not more accurate actually. The red arrow shows the best length, and the minimal error. Quote Ali Salehi | Programmer Intel Core i3 2100 @ 3.0GHz | GeForce GTS 450 | 4GB DDR3 RAM | Windows 7 Ultimate x64 LE 2.50 | Visual Studio 2010 | RenderMonkey 1.82 | gDEBugger 5.8 | FX Composer 2.5 | UU3D 3 | xNormal 3.17 Link to comment Share on other sites More sharing options...
Josh Posted January 10, 2012 Share Posted January 10, 2012 Yeah, mathematically it's not a normal. But here in the picture you can see errors for different lengths as blue lines. So as you can see longer is not more accurate actually. The red arrow shows the best length, and the minimal error. Ah, that's a good illustration. I like this approach. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.