一、原理
levoy在2023年提出了光線投射(ray-casting)演算法[1],其基本原理是:從螢幕上每乙個畫素點出發,沿著視線方向發射出一條光線,當這條光線穿過體資料時,沿著光線方向等距離取樣,利用插值計算出取樣點的顏色值和不透明度;接著按照從前到後或從後到前的順序對光線上的取樣點進行合成,計算出這條光線對應的螢幕上畫素點的顏色值。其原理如圖1所示。
圖1光線投射原理
該演算法基於射線掃瞄過程,符合人類生活常識,容易理解可以達到較好的繪製效果。因此光線投射是目前應用最為廣泛的體繪製方法。然而當觀察方向發生變化時,取樣點的前後關係也必然變化,因此需要重新進行取樣,計算量極為龐大。針對演算法所存在的問題,人們提出了不少優化方法,如光線提前終止、利用空間資料結構來跳過無用的體素,如八叉樹、金字塔、k-d樹等。
該演算法的流程圖2所示。其中資料的分類主要是將體資料的標量值對映為顏色和不透明度,這需要構造合適的轉換函式。對體資料的取樣需要進行座標系的變換,因為發射光線起點和方向是在影象空間描述的,而取樣則是在物體空間進行的。影象空間到物體空間的轉換可以通過旋轉和平移操作實現。將光線的描述轉換到物體空間後,沿著光線等間隔取樣,取樣點的顏色和不透明度通過插值獲得。最後需要沿著光線對所有取樣點的進行合成,得到光線對應的二維螢幕上畫素點的顏色。
圖2 光線投射流程
二、實現
在實驗中,我們繪製了乙個人工生成的體資料,該體資料是乙個大正方體,內部包含乙個球體,球體內又包含乙個小正方體。繪製結果如圖3所示。
在資料分類階段,我們簡單地將三個幾何體分別賦為白色、紅色和黃色,並設定一定的透明度。我們選擇了平行投影的方式,這樣從影象平面發出的所有光線的方向都一致,因此在進行座標變換時,光線方向的變換只需要進行一次。另外需要將每條光線的起點進行旋轉和平移,以轉換到物體空間描述。對取樣點的插值採用的是三線性插值,這也是整個演算法最耗時的部分。關於取樣點的合成,我們採用從前向後的合成方式,合成公式如下:
這樣可以利用提前終止條件以加速演算法,即當累計不透明度超過1時就停止合成操作。
從實驗結果可以看出,光線投射法通過不透明度的設定可以得到半透明的繪製效果,這樣就能有效地反映出物體內部結構,這也是體繪製與面繪製的最大區別。光線投射法作為最為通用的體繪製方法,其繪圖質量最高,但相應的問題就是繪製速度較低,難以實時化。實際上,對於本實驗中的體積資料,使用簡單的最近鄰插值得到的結果與三線性插值並沒有差異,而且速度上能提高不少。因為在該體資料中,對大部分取樣點來說,與其鄰近的八個資料點的值都是相同的。
圖3 光線投射實驗結果
(注:核心**純c,影象顯示部分使用了opengl)
Unity之基於光線投射演算法的體渲染技術(二)
接上文 第二種光線投射演算法的實現,基於光線起點 相機位置 將相機位置由世界座標通過模型檢視投影矩陣反變換到長方體的區域性座標空間。每個fragment的座標作為光線的入射點,由變換後的相機位置與光線入射點確定光線的方向,在沿著光線方向從入射點前進時,每到達乙個新的點,判斷其是否在長方體內,如果在,...
真實感場景繪製(附原始碼)
首先給出繪製效果圖 說明 本系統繪製了乙個真實感的三維場景,並實現場景漫遊。使用按鍵 或w s a d控制運動方向,pgdn和pgup可以改變觀察者的高度,滑鼠控制轉向,按鍵 f 可以開啟和關閉 霧氣 esc退出程式。本場景中繪製了牆壁與地面 天空 石柱 箱子 玻璃球 雪人 霧等物件,下面將依次分析...
GL 遊戲演算法(附原始碼)
gl遊戲規則 有個列相當長的格仔 格仔總數不超過10的四次方 某些格仔裡面放了棋子 棋子總數足夠多 1.如果格仔裡面有棋子,就可以少拿走其中一顆,同時在這個格仔的左邊兩個格仔裡面各放一顆 2.如果連續兩個格仔裡面都有棋子,可以分別從兩個格仔中都拿走一顆,並在她們右邊的格仔裡面放入一顆 輸入初始狀態,...