对于变换的空间,没有什么固定的套路可以进行坐标映射。 不过好在前辈们总结了一些函数,多看慢慢能力理解一些. 本节讨论两个非常简单的。后续会探索一个扭曲平面的隐射与 球面映射。不知道什么时候有时间了。
Transform
在之前,我们的物体是不会运动的,也就是没有发生空间变化,我们的纹理坐标直接使用世界坐标,当空间发生变换纹理会出现鬼畜的效果.例如下面旋转物体之后。问题停留在物体在xz平面的投影面上
解决这个问题需要将纹理坐标的 uv跟着物体进行同样的运动。 在 RayMarching和UV构造的时候同时引入一个相同个的 Transfomr函数便可以解决这个这个问题

Infinite
在之前 记事本400行代码实现有山有云有小动物的虚拟世界
中, 天空是一个无尽的平面。同时地面也是无尽的平面,相对于之前 Plane映射, 因为无尽,他会有远处聚合在一条天际线的感觉了。 如下图所示

对于 ground其实就是一个平面隐射。
vec2 uv = p.xz;
vec2 w = fwidth(uv); // filter kernel
vec2 i = (tri(uv+0.5*w)-tri(uv-0.5*w))/w; // analytical integral (box filter)
float grid = 0.5 - 0.5*i.x*i.y;
color += vec3(0.2, 0.8, 0.4)*dif;
对于天空需要多花些时间思考,天空平面的函数为
vec2 sky_uv = fract(1.8 * rd.xz/abs(rd.y + 0.11)* 0.1);
其中rd.xz 是射线方向在水平平面上的投影,形成一个二维向量。 将 rd.xz 除以 rd.y 可以理解为将射线方向投影到一个水平面上,同时考虑射线的倾斜角度,使得云层效果随高度变化。当 rd.y 较大时,表示射线接近垂直向上,此时 uv 值较小, 为 rd.y加上一个偏移量不是很好理解,通过以下代码获取图像感知
color += texture(iChannel1, sky_uv).xyz * smoothstep(0.,0.1, rd.y);
