[程式] 超新手 shader language 教学文 (七)

楼主: meowyih (meowyih)   2022-06-19 00:22:42
[2022/06/19] 为了让观念更清楚,我大改程式,所以更新文章
这次我也有自己做 shader 当教材唷,影片在这。
https://youtu.be/Je88e5KKYJU (没有鱼眼)
https://youtu.be/_RTsKbjj0iw (有鱼眼)
本篇也是讲 ray marching,主要是讲些实作上的小技巧。
如果你打算做的 3D 游戏有户外或是看的到天空的场景,
那这篇就挺重要的,请务必看一下。
[准备]
完整的程式在这:
https://www.shadertoy.com/view/sdVcDG
请务必先搞懂前一篇 (六) 的程式,
如果前一篇有模糊不清的地方,这篇只会更搞不懂的。
[天空的构造]
这次的世界有二部分,
一个是天空 (sky),一个是河流 (river),
二部分的程式几乎是一样的。
为了当教材,我刻意写二份,
让他们各自独立且可以分拆来显示。
先用 sky 当说明。
前一篇 (六) 的范例,我们有个 world(pos),
它会回传 pos 这个点的密度。
这次的范例除了密度,还会回传一个 distance 的值,
那个值是 pos 离天空最近的距离值,
主要的用途是加快 ray marching 的速度。
因为天空是水平平面,
所以最近距离就是 pos 和天空的垂直距离。
再者,最近距离 > 0 时,通常密度就是 0,
要到天空里面才会有天空密度,这是当然的。
void sky( pos, out distance, out density )
在抽象上,我把天空当成一个高度是 1.0 的无限大的水平平面。
float sky( pos, out distance, out density )
{
// pos 和 sky 的最短距离
distance = 1. - pos.y + fbm(pos*4.-iTime*0.2) * 0.3;
// pos 的密度
density = step(distance, 0.05) * (0.05 - distance);
}
分行说明
一、distance = 1. - pos.y + fbm(pos*4.-iTime*0.2) * 0.3;
(1.0 - pos.y) 的意思可以用简单的示意图来说明:
高度 distance density
+3 -2.0 2.05
+2 -1.0 1.05
+1
作者: dklassic (DK)   2022-06-19 14:08:00
推推
作者: iLeyaSin365 (伊雷雅鑫)   2022-06-19 21:35:00
加油
作者: a82611141   2022-06-21 08:34:00

Links booklink

Contact Us: admin [ a t ] ucptt.com