双通道法线贴图
在移动端用于带宽受限的缘故,延迟管线下不能设定太多GBuffer,否则会导致手机发热。对于normal tex,是可以通过xy来算出z的
inline float3 GetNormalTSFromXY(float4 normal, float normalIntensity = 1.f)
{
float3 o = 0.f;
float2 normalXY = normal.rg * 2.f - 1.f;
o.z = max(1e-16, sqrt(1.f - saturate(dot(normalXY, normalXY))));
o.xy = normalXY * normalIntensity;
return o;
}
这样可以省出一个通道来装填其他数据,如AO
存在的问题
- 但双通道也存在一定的问题,因为第三个通道填充了AO数据,对于normal tex有特定的图片压缩方式,而normal.xy数据和ao本来就没什么关联,所以很可能会导致normal.xy的数据不对
-
纹理过滤丢失高频信息
normal tex因为存储的是一个向量,所以对normal tex进行纹理过滤,本质上是一个球面插值的过程。最终在插值两个normal向量时,当方向差距越大,会使得normal.z的数据越错误
纹理压缩与通道储存
-
为了支持双通道normal tex,从最早的PC端DXT5开始,到现在移动端ASTC,都推出了相应的压缩算法——需要将rg数据放在ag中计算
因此在计算normal时,需要将r通道的值赋给a通道,并使用ag通道来计算normal
GBuffer应该压缩Normal吗?
大部分厂商都没有压缩GBuffer,即使是移动端也是如此,如UE等
因为压缩Normal可能会导致normal的偏差,最终导致渲染的误差,如高光、贴画等,而且是比较明显的,为了稳定还是更建议不压缩
当然CryEngine用到了奇淫技巧MicroGBuffer来压缩Normal,也是可以的
Comments | NOTHING