欢迎光临散文网 会员登陆 & 注册

UE Source Code Note 1

2023-08-29 03:01 作者:中专人  | 我要投稿

UE Shader层的单位向量压缩与解压

先贴源码:

在论文《Survey of Efficient Representations for Independent Unit Vectors》中,提出一种将三维单位向量压缩成二维向量的方法。方法是先将单位向量从球体(Sphere)映射至八面体(Octahedron),再投影到一个平面正方形(Square)上。

如第四张图所示。

为什么不使用平方和为1的方法进行压缩而要如此大费周章呢?

首先在公式z%20%3D%20%5Csqrt%7B1-x%5E2-y%5E2%7D中可以看到存在两个平方与一个开方的昂贵开销,会大大影响GPU流水线并行速度。其次,平方与开方操作带来的精度问题不容小觑。因此,这种十分影响渲染质量的压缩是得不偿失的。

接下来谈谈ue中的压缩与解压方法。

由图中可得,球上点p的目标是要映射至平面p''点。假设p点坐标为(p_x%2Cp_y%2Cp_z),由球心向p点连线,与球内正接八面体交于点p'。设p'坐标为(p'_x%2Cp'_y%2Cp'_z),向量%5Cvec%7Bop%7D与向量%5Cvec%7Bop'%7D之比为S,那么得到:(P'_x%2CP'_y%2CP'_z)%3D(%5Cfrac%7BP_x%7D%7BS%7D%2C%5Cfrac%7BP_y%7D%7BS%7D%2C%5Cfrac%7BP_z%7D%7BS%7D),又因为p‘在正八面体上,所以%7CP'_x%7C%20%2B%20%7CP'_y%7C%20%2B%20%7CP'_z%7C%20%3D%201,代入之前的式子得出:%7CP_x%7C%20%2B%20%7CP_y%7C%20%2B%20%7CP_z%7C%20%3D%20S,因此:

P'_x%3D%5Cfrac%7BP_x%7D%7B%7CP_x%7C%2B%7CP_y%7C%2B%7CP_z%7C%7D

P'_y%3D%5Cfrac%7BP_y%7D%7B%7CP_x%7C%2B%7CP_y%7C%2B%7CP_z%7C%7D

从p'点到p''点,舍弃z分量,简单投影到xy平面,即p''=p'。

这样,就得到了单位向量从三维降维至二维的方法。

对应至源码中就是

这一行。

上面讨论的是上半球面的情况,这样只得到了一个2134构成的菱形。如果是下半球面的话,为了防止投影时出现重复,需要将其xy进行重映射操作。

比如7号平面在投影时如果向内折叠会与3号重复,那么就将其投影平面向外折叠,可以简单看作是3号的对角线镜像。

那么通过对称关系与简单的几何计算,不难得出,当z小于0时,

P''_x%3D(1-%20%5Cfrac%7B%7CP_y%7C%7D%7B%7CP_x%7C%2B%7CP_y%7C%2B%7CP_z%7C%7D)%20*%20sign(%5Cfrac%7BP_y%7D%7B%7CP_x%7C%2B%7CP_y%7C%2B%7CP_z%7C%7D)

P''_y%3D(1-%20%5Cfrac%7B%7CP_x%7C%7D%7B%7CP_x%7C%2B%7CP_y%7C%2B%7CP_z%7C%7D)*sign(%5Cfrac%7BP_x%7D%7B%7CP_x%7C%2B%7CP_y%7C%2B%7CP_z%7C%7D)

解压就是压缩的逆运算。

此方法除了用于单位向量的压缩外,还用于八面体映射(Octahedral map)的技术之中。

如侵删。

欢迎评论指正。

参考来源:

https://zhuanlan.zhihu.com/p/594429859

https://www.cnblogs.com/timlly/p/13877623.html

UE Source Code Note 1的评论 (共 条)

分享到微博请遵守国家法律