Boson引擎

發布日期

在真實世界,我們的眼睛因為光子射入而能看見,在電腦中,我們沒有能夠模擬趨近無限個光子的資源, 更何況是好幾十個動態光源。所以,我們有個小小的技巧——因為我們只想要打到相機的光子, 所以我們只要模擬它們就足了。Voila!這和從前對於看見的迷思有一樣的原理。

C++建置

草圖

在一開始,我寫了個簡單的草稿,從donut.c(一個立體甜甜圈渲染器)中找到靈感。從開發的開始, 我便面對許多問題,像是隱晦複製物件問題與昂貴複製問題。我的想法是我們可以從虛擬螢幕射出一條射線, 將射線單位加上去,如果和表面相撞,則產生一個亮度因子。聽起來很簡單,但是我花了一個小時除錯, 因為每個單位的亮度因子都相同,後來發現是轉型的問題。

線性代數

「太少數學了!」你一定這麼問,所以就來談碳吧。在引擎中,我使用傳統的三四四矩陣模型, 即視矩陣、模矩陣與自矩陣。由於方便考量,自矩陣已先被計算為向量。當我們移動相機, 視矩陣被更新,用一些簡單的乘法,我們可以用對角線元素拉伸元素。

Vf=[xoyxozxowxoxyyozyowyoxzoyzzowzoxwoywozww]ViV_f = \left[\begin{matrix} x & o_{yx} & o_{zx} & o_{wx} \\ o_{xy} & y & o_{zy} & o_{wy} \\ o_{xz} & o_{yz} & z & o_{wz} \\ o_{xw} & o_{yw} & o_{zw} & w \end{matrix}\right] \cdot V_i

對於碰撞邏輯,我使用一個啟發法公式。給定一三角形有三點:

n1=(v1v)×(v2v)n2=(v2v)×(v3v)n3=(v3v)×(v1v)n_1 = (v_1 - v) \times (v_2 - v) \\ n_2 = (v_2 - v) \times (v_3 - v) \\ n_3 = (v_3 - v) \times (v_1 - v)

,當任一為零, 或當n1^n2^||\hat{n_1} \cdot \hat{n_2}||n2^n3^||\hat{n_2} \cdot \hat{n_3}|| 都是一時,碰撞就發生了。下一步就是計算亮度因子,使用內積。 不過這個公式只適用在理想世界,因為電腦會受到精度影響,因此我們需要有一個閾值來確定。

埋頭苦幹

有了個三角形後,我需要做的事便是渲染更多三角形。不過我需要先清理乾淨之前的程式碼, 第一件事是我的矩陣和向量都是使用std模態,而且東西都塞在同個檔案main.cpp中, 所以,我把檔案分開並加入命名空間以產生更符合語意的環境。使用線性代數時, 我使用 TMP(超模板程式設計)產生動態矩陣,不需要使用記憶堆,而且速度媲美靜態矩陣。 現在只剩下的是 ECS 系統,不過我大錯特錯。

Rust 建置

C++專案維修的問題接二連三的飛來。彼此耦合的定義與宣告零散在四處,讓除錯變得像貓抓老鼠。因此,重新寫一個引擎的想法在腦中萌生,正巧我在學 Rust, 所以我花一些時間將 Boson 改寫成 Rust。在 Rust 中,我不需要為參考與指標擔憂,而寫 Rust 給我的感學和寫 C 相近,簡易又明瞭, 因此我寫了個Rust 建置