tag:blogger.com,1999:blog-6042417775578107106.post686888426331326284..comments2023-08-05T11:30:32.754-04:00Comments on The Hacks of Life: Yet Another This-Is-Our-GBuffer-Format PostChrishttp://www.blogger.com/profile/14648675681957285299noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-6042417775578107106.post-88524169137149070492010-12-16T14:13:03.115-05:002010-12-16T14:13:03.115-05:00Hi Cam,
You are right that emmissive could be pre...Hi Cam,<br /><br />You are right that emmissive could be pre-multiplied...it's a case where we don't have a good way to recycle the last channel. The problem is that we need alpha blending in the channel to be on so that we can do "replace" operations. <br /><br />Consider if a non-lit box is drawn in front of a self-emmissive box. Where the over-draw occurs, the forward renderer would end up fully replacing the previous bright pixels with new dark ones. <br /><br />With the g-buffer, the equivalent op has to happen for us per-channel. So we need to write to the emmissive channel with alpha = 1 and RGB = 0 to tell the GPU to _nuke_ what's already there and replace it with our new (non-emmissive) texels.<br /><br />You are right that the _resulting_ alpha is useless, so if we could find a 3-channel renderable format, we could win. But the GL doesn't have this, it only has 1,2, or 4. And we can't reuse the alpha channel without turning blending off (so we could write something sane there instead of using our alpha out in our fragment as the 'control'). So we end up wasting it. :-( It's a cost of supporting some proximate form of blending.<br /><br />(If we had only alpha _testing_ we'd turn off blending and simply kill the fragment when we didn't want to write it out.)Benjamin Supnikhttps://www.blogger.com/profile/04886313844644521178noreply@blogger.comtag:blogger.com,1999:blog-6042417775578107106.post-74197209281899299642010-12-16T07:19:05.711-05:002010-12-16T07:19:05.711-05:00If emmissive is strictly additive, why does it nee...If emmissive is strictly additive, why does it need alpha? Can you just premultiply RGB by A and discard A (and use the full 8 bit alpha for your shininess?)camhttps://www.blogger.com/profile/14248026293143232607noreply@blogger.comtag:blogger.com,1999:blog-6042417775578107106.post-14378940060102582572010-12-08T15:49:32.372-05:002010-12-08T15:49:32.372-05:00Hi SebH,
Yeah - you're right, my bad...side ...Hi SebH, <br /><br />Yeah - you're right, my bad...side angled face + normal map = back-facing normal :-) But it hasn't proven to be an issue so far...generally that case means that you have some combo of:<br />- Your normal map is on edge, so the fact that it is flat and not really extruded is perhaps more of an issue, particularly if it is 'heavily extruded'.<br />- You may have some anisotropic filtering, but the as you approach 90 degrees the quality of the texture sampling is going to get a bit fugly anyway.<br /><br />So...we'll eat the marginal light cost...I'll try to follow up if we find a case that forces us to stash Z somewhere.<br /><br />We haven't played with Crytek's normal map optimization schemes yet, although I did read the paper a few weeks ago.<br /><br />I'm not sure how much it would matter to us...there are basically two cases:<br />- Gbuffer - we're sending more than 8 bits on dx and dy. :-)<br />- RGBA8 normal map from an art asset...since we use tangent space normal maps, we don't need to represent every direction, and in practice monstrous amounts of deflection may not be super useful (because the art asset isn't actually extruded in 3-d). <br /><br />(Side note -- I should probably verify that our art guys aren't actually pushing the normal maps farther than I think they are. :-)<br /><br />The alternative to best-fit in RGB is to recycle that B channel for something else, and that's really, really tempting...we have several candidate effects we could use it for.<br /><br />Another option would be to apply a non-linear scale to the dx and dy. Specular hilites tend to be really sensitive to very slight changes from perfect on-axis viewing, and thus the difference between a truly 'flat' normal (dx=dy=0) and a slightly offset one is a big deal.<br /><br />Consider the relationship between the specular hilite level and the dx component of a normal (assume 2-d for easy math). It's roughly:<br /><br />(sqrt(1-dx^2))^128^2.2<br /><br />If you graph that, nearly all of the light falloff hapens in the first 25% of your normal space...that is to say, all of the information is crammed into 1/4 of the bits.<br /><br />So (this is theoretical, I haven't tried it, and I'm sure I am not the first to think of this) it seems like it might be useful to 'compress' dx and dy of a tangent space normal map using 2-part piece-wise linear curve or some other (hopefully) cheap encoding that would use the first 50% of the channel range for the first few % of normal deflection.Benjamin Supnikhttps://www.blogger.com/profile/04886313844644521178noreply@blogger.comtag:blogger.com,1999:blog-6042417775578107106.post-35047831000993454352010-12-08T15:25:53.291-05:002010-12-08T15:25:53.291-05:00Interesting! :)
@Benjamin there is some cases whe...Interesting! :)<br /><br />@Benjamin there is some cases where you can see back faces due to the perspective projection (there is a Crytek presentation about normals compression to get precision where it matters showing this case). But I guess that not taking into account the sign of normal.z does not make such a huge difference in most cases.<br /><br />May be it was not fitting well your rendering pipeline but: did you have a look at the "best fit normal" method?sebhhttps://www.blogger.com/profile/14650504326449432531noreply@blogger.comtag:blogger.com,1999:blog-6042417775578107106.post-90051733046073208022010-12-06T13:16:19.096-05:002010-12-06T13:16:19.096-05:00Sign of Z - nope, no need. The Z axis here is in ...Sign of Z - nope, no need. The Z axis here is in eye space..if the normal isn't facing us, how can we see it? :-)<br /><br />This does assume that when we use back-face culling we do not rely on having the wrong-direction normal be available. This assumption is true for X-Plane.<br /><br />If you did need sign-of-Z you could stash it in the depth component..there we are really assured we don't need both positive and negative values.Benjamin Supnikhttps://www.blogger.com/profile/04886313844644521178noreply@blogger.comtag:blogger.com,1999:blog-6042417775578107106.post-17375150143946114422010-12-06T12:38:45.206-05:002010-12-06T12:38:45.206-05:00Are you storing the sign of Z for your normals som...Are you storing the sign of Z for your normals somewhere in your G-Buffer?MJPhttps://www.blogger.com/profile/00019213063129052143noreply@blogger.com