Unity - 从RG中解压法线贴图
环境
Unity : 2020.3.37f1
Pipeline : BRP
目的
备忘便于索引
问题
之前使用 GPA 还原一些效果的时候,发现 法线贴图的 Y 通道数值不对,感觉被 翻转了
比方说,下面是 GPA 中的法线
这个法线是 DX 方式的,不是 OpenGL 的,如何辨别 法线是属于 DX 还是 OpenGL 的,可以参考:快速判断OpenGL和DirectX法线的技巧
具体我们打开 PS 来查看差异
可总结为:
- GL 的 凸面
- 正X 是向右的
- 正Y 是向上的 (绿色向上)
- DX 的 凸面
- 正X 是向右的
- 正Y 是向下的 (绿色向下)
解决
我们在 BRP 管线中,可以看到类似的 解释方式
已知 normal.rg
那么 normal.z = sqrt(1 - dot(normal.rg, normal.rg))
然后如果要 scale
的话还可以这样: normal.xy *= scale
因此我们自己的想就可以按自己的方式来处理
不用判断 DX 或是 GL,反正我们自己限制好使用 GL 的规格,即可
这样法线贴图只使用到两个通道,然后 BA
通道还可以放其他的数据
如果是要是需要你也可以整一个参数控制 normal flipping
...
half3 raw_normal = tex2D(_BumpMap, uv);
raw_normal.y = lerp(raw_normal.y, raw_normal.y * -1, _NormalY_Flipping);
raw_normal.z = sqrt(1 - dot(raw_normal.xy, raw_normal.xy));
half3 normalWS = T2W(raw_normal, xxx);
...
最终我们还原了 GPA 的大概效果:
nVidia texture tools - normal map 也有类似说明
视频直达传送门: NVIDIA_Texture_Tools_Normalmap_Overview_embed_2
留意:
这里头有将怎么计算 b 通道
b = 0.5 * sqrt(1 - (2r - 1)^2 - (2g - 1)^2 + 0.5
其中:-1~+1
的 b 为: b = sqrt(1 - (2r - 1)^2 - (2g - 1)^2
然后我们通过 val * 0.5 + 0.5
转为 0~1
所以上述公式可以看成是:b = 0.5 * b + 0.5
这个式子是来自于 单位向量公式:(x,y,z)
x^2 + y^2 + z^2 = 1