[程式] 超新手 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