二维空间下的推导

球型映射-示意
如上图所示,将高度为 $h$ 的草映射到不同半径的圆上,故有

$$ \begin{aligned} &\frac{1}{2} \text{圆: }\quad h = \frac{1}{2} c = \frac{1}{2} \cdot 2 \pi r \\ &\frac{1}{4} \text{圆: }\quad h = \frac{1}{4} c = \frac{1}{4} \cdot 2 \pi r \end{aligned} $$

由此可得所映射圆半径的表达式为

$$ r = \frac{h}{a \cdot \pi}, \quad a \in (0, 1] $$

当 $a=1$ 时,表示映射到 $\frac{1}{2}\text{圆}$ 上,即草弯曲并刚好碰到地面; 当 $a \to 0$ 时,表示映射到一个无穷大圆上,表示草是竖直无弯曲的。

球型映射-动画示意
接下来,我们设点 $J$ 为草的顶点,映射后的点为 $J'$,如下图
球型映射-取点示意
$OP=\widehat{OP'}$,由弧顶定义求 $\widehat{OP'}$ 对应的角度 $\alpha$ 得

$$ \alpha = \frac{\widehat{OJ}}{r} $$

由此便可得点 $P'$ 的坐标

$$ P' = r \cdot (-cos\alpha, sin\alpha) + O_圆 $$

在实际情况下,顶点不可能完全在本地空间的竖直轴线上,如下图所示

球型映射-点偏移示意
偏移距离 $L$ 即为半径 $r$ 的变化量

$$ P' = (r - L) \cdot (-cos\alpha, sin\alpha) + O_圆 $$

最后整理公式: 草高度 $h$,弯曲系数 $0 < a \leq 1$,顶点 $P(x,y)$

$$ \begin{aligned} &r = \frac{h}{a \cdot \pi} \\ &\alpha = \frac{P_y}{r} \\ &P' = (r - P_x) \cdot (-cos\alpha, sin\alpha) + (r, 0) \end{aligned} $$

引入风向并转到三维

在以上的二维空间中草是向 X 轴弯曲的,引入风向后便是沿着风向轴弯曲。 假设 Z 轴向上,有顶点 $P(x,y,z)$,有风向 $W(x,y)$。 先计算顶点 P 在风向 W 方向上的分量,即投影长度,该值便是上文提到的偏移距离 $L$

$$ L = \frac{P_{xy} \cdot W}{|W|} $$

计算映射后的点在风向风向上的分量,并乘以归一化风向向量便得到映射后的点在 XY 平面上的位置

$$ P'_{xy} = [(r - L) \cdot (-cos\alpha) + r] \cdot W $$

计算映射后的点在竖直方向 Z 上的位置

$$ P'_z = (r - L) \cdot sin\alpha $$

示例代码

HLSL
float3 GA_Test(float3 PositionLS, float Height, float WarpFactor, float2 WindDir) {
    float r = Height / WarpFactor * 0.31831;
    float alpha = PositionLS.z / r * TestValue;
    float L = dot(PositionLS.xy, WindDir) / length(WindDir);
    float z = (r - L) * sin(alpha);
    float2 xy = ((r - L) * -cos(alpha) + r) * WindDir;
    xy -= L * WindDir;
    return float3(xy.x, xy.y, z - PositionLS.z); // WPO
}
点击展开查看更多

版权声明

作者: Cheyne Xie

链接: https://chaim.eu.org/posts/585f79bc/

许可证: CC BY-NC-SA 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Please attribute the source, use non-commercially, and maintain the same license.

开始搜索

输入关键词搜索文章内容

↑↓
ESC
⌘K 快捷键