http://advances.realtimerendering.com/crytek总是能发现一些别人没发现的东西。

之前我也发过http://www.cnblogs.com/linyizsh/archive/2009/05/30/1492314.html

说过些packnormal的东西。但是从直觉上,无论哪种方法,总是觉得不怎么完美,一个是计算量太大,

一个是存储bit数太多,如果使用类似deferred lighting的方式,存深度,normal和specular power,

如果希望只用64bit来存,在pc d3d上不考虑扩展情况下,深度通常32bit不可少(当然16bit不是不可以,就像sc2

,但是sc2情况特殊,它没有太远的场景,500米内,16bit通常够用,但是如果希望能够看到更远,16bit

就不够了,如果做ssao之类深度效果,在远处影响就很大),剩下normal和specularpower,specularpower

至少也要8bit,剩下24bit给normal,如果按之前的pack方式,这是很难的,直接存取更不用说,质量太差。

    无数人做过无数方法去弄这个pack问题,但是都忽视一个非常简单的问题,24bit能够存的是一个volume,

有256*256*256个可能的值,直觉上这么多的值,应该是可以保证精度才是,为什么直接存却不行呢,因为

pack都是按照normalized之后的向量去pack的,相当于xyz的关系是确定的,这些xyz构成的是一个球面,

这样给自己下了一个限制,这个球面的空间占这个volume的比例还不到2%。。。浪费了其它n多的空间,精度

当然是相当低的,best fit的方式就是利用这些空间,先把所有256*256*256的各个方向的

向量长度bake到一个图里,去掉对称的和重复的,之后放入一个2d图里。在生成gbuffer的时候,通过normal来查找到

最接近的texel,也就是找到对应的向量长度,然后直接将这个长度的normal,scale到0-1就行了,使用的时候只要scale

回来,然后normalize一下就可以了,可谓方便之极,完全可以到处使用。

    这种方法给存储normal指了另一条明路,如何来利用这256*256*256个值,crytek的方式感觉上还是有些麻烦,

压缩normal的过程在ps3.0下需要18条指令,也许以后还有更简单的方式。

    个人觉得,只有normal能够存入24bit并保证精度,deferredlighting才能真正比较实用,best fit的方式应该是最好的

办法了。