小程序[渲染层网络层错误] failed to load image_游戏中水的渲染技术
水的渲染一直是圖形學需要解決的問題,本篇博客主要介紹用傅里葉變換算法實現的水反射,也是一種假反射效果,目的是優化效率。實現的效果如下圖所示:
使用傅里葉系數來表示地形高度的假反射效果,在我們開發的游戲中使用水著色器,告訴讀者我將如何利用引擎處理水的反射,我們自己開發水渲染效果,需要在優化方面考慮,計算每幀渲染時間。我們要處理渲染簡化的低分辨率反射地圖,因為我們還要渲染對于流動的水平面。算法的實現其實都是源于生活,大家如果平時出去旅游,經常會看到山丘的反射,近處反射的比較清晰,但在遠處它只是一個黑色的斑點。試想一下,如果我們能夠記錄每個水點周圍的水面上方的地形的角度,然后我可以在水著色器中使用這個反射光線,它應該是從“天空”過渡到“地形”的點。(Spherical harmonics)球面諧波是一種眾所周知的技術,通常用于全局照明。非常簡要地總結:每個頂點存儲一組預先計算的系數,這允許我們重建擊中對象的環境光。這些系數基本上存儲從每個方向照射該點的光的映射圖。反射/環境光通常是非常低的頻率,因此這是這些系數如何包含這么“多”的信息原因。我決定用我引擎中的水嘗試類似的技術,每個頂點保存一組小系數,描述地形在水上方圍繞該點的每個方向上升的角度。這可以用一個四元系列的系數來描述 - 基本上是球面諧波的2d方程。當在頂點之間插值時,這些傅里葉系數就可以計算出來了,給讀者展示一下效果圖吧。在水上的一個點周圍的采樣方向上的各種角度。
我們計算每個水頂點的系數,這涉及每個頂點的操作:
1、在點周圍選擇 ?k個均勻間隔的采樣方向。k的值只影響計算,因此您可以將其設置為一定
的高以實現其仿真度,我目前使用13。
2、對于每個采樣方向,執行光線跟蹤。一次執行一個高度地圖像素,測量水面上方的地形角度。你想要精確的反射取決于你離岸的距離,在本文的示例應用程序中,我目前使用5個像素。如果你的游戲涉及從低水平面的不同的水觀察視角,你將需要使用更多(后面更多)。
3、現在我們有一個函數(每2π循環)表示點周圍的地形高度。
4、為了獲得表示該函數的傅里葉系數,我們需要對每個系數的表達式進行積分計算,確切的表達式可以在網上找到。我使用數值積分,分辨率為400(例如每個函數400個樣本),使用的數字僅影響計算。
?5、我計算前8個系數,這個數字直接影響效果的品質和性能。8對我的目的來說肯定夠好了,當然我們會盡量降低。
我把我的系數作為16位浮點存儲在我的頂點結構中(因此每個頂點占用16個字節)。
在水著色器中,我使用反射向量來確定我設置的角度,代碼如下:
float3 reflectionRay = reflect(worldPosition - CameraPosition, normal);float angle = atan2(-reflectionRay.z, -reflectionRay.x) + PI;//這給出了0和2π之間的角度,然后我們能夠使用它來查找地形高度。本文實現的傅里葉評估函數看起來像這樣(t是角度):
float EvaluateFourier(float t, float4 coefs1, float4 coefs2){ float4 sins; float4 coses; sincos(float4(t, 2 * t, 3 * t, 4 * t), sins, coses); float value = coefs1.r; // a0 value += coefs1.g * coses.r; // a1 value += coefs1.b * sins.r; // b1 value += coefs1.a * coses.g; // a2 value += coefs2.r * sins.g; // b2 value += coefs2.g * coses.b; // a3 value += coefs2.b * sins.b; // b3 value += coefs2.a * coses.a; // a4 return value;}方程給了我一個角度,這也是算法與編程結合的函數實現,然后我可以比較水面上的反射光線的角度,以確認我們是否應該繪制天空或反射的地形,目前我只是使用黑色的反射地形,效果似乎滿足需求。如果我們想要更好的效果,還可以存儲地形的顏色,除了高度。當然這將使所需的數據量增加四倍。
那它是如何工作的呢?您可以查看本文頂部的照片作為示例。這里有一個版本的頂點網格繪制。每個頂點存儲16字節的數據在我當前的實現。上圖顯示了我使用的頂點分辨率效果。
在水面上使用的法線貼圖有助于實現這種假反射效果,實現的效果如下所示:
以上實現的效果在性能方面也給讀者分析一下,這也有助于讀者優化Shader的渲染效果:上面給讀者實現了一種假反射,以避免渲染昂貴的反射貼圖,因此它需要具有高性能。不幸的是,這需要大量的著色器指令在我當前的實現中評估。atan2約有20條指令。HLSL產生4個標量sincos指令,其實際上每個占用8個指令槽。總共,它為像素著色器添加了約64個指令槽。針對上述問題,我們的下一步任務是找到一種減少指令數量的方法。可以使用atan,然后是正弦和余弦,我可以通過做一些三角取代來減少這一點。或者我可以考慮使用e與虛數的冪的和來評估該系列。當然我們還可以減少系數的數量。另外,我將看到我是否可以存儲每個系數在單個字節而不是16位浮點。最后總結一下,對于具有更多不同視圖的游戲,這可能不是一個很好的選擇。還有這個技術的一個問題是它只反射靜態對象,地形,以及你決定在你的射線檢測算法中包含的任何其他游戲元素。總結
以上是生活随笔為你收集整理的小程序[渲染层网络层错误] failed to load image_游戏中水的渲染技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle行列互换sql,解决Orac
- 下一篇: 奔腾双核linux服务器,Dell推出双