只需三步,實時多邊形折射

2022-07-11 03:33:09 字數 4104 閱讀 1542

在本教程中,您將學習如何使用three.js在三個步驟中使物件看起來像玻璃。

渲染3d物件時,無論使用某種3d軟體還是使用webgl進行實時顯示,始終都必須為其分配材料以使其可見並具有所需的外觀。

可以使用three.js之類的庫中的現成程式來模仿許多態別的材料,但是在本教程中,我將向您展示如何使用三個物件(三個步驟)使物件看起來像玻璃一樣。

在本演示中,我將使用菱形幾何圖形,但是您可以跟隨乙個簡單的盒子或任何其他幾何圖形。

讓我們建立我們的專案。我們需要乙個渲染器,乙個場景,乙個透視相機和我們的幾何圖形。為了渲染我們的幾何圖形,我們需要為其分配材質。建立此材料將是本教程的主要重點。因此,繼續建立具有基本頂點和片段著色器的新shadermaterial。

與您期望的相反,我們的材料將不是透明的,實際上,我們將對鑽石後面的任何東西進行取樣和變形。為此,我們需要將場景(沒有菱形)渲染為紋理。我只是使用正交攝影機渲染全屏平面,但這也可能是充滿其他物件的場景。在three.js中從菱形分割背景幾何圖形的最簡單方法是使用「圖層」。

我們的渲染迴圈如下所示:

this.envfbo = new three.webglrendertarget(width, height);

this.renderer.autoclear = false;

render() ;

好吧,現在該花一點點理論了。透明材料(如玻璃)可以彎曲,因此可見。那是因為光在玻璃中的傳播要比空氣中的傳播慢,因此當光波以一定角度撞擊玻璃物體時,這種速度變化會導致光波改變方向。波浪方向的這種變化描述了折射現象。

為了在**中複製這一點,我們將需要知道我們的眼睛向量與世界空間中鑽石表面(法線)向量之間的角度。讓我們更新頂點著色器以計算這些向量。

varying vec3 eyevector;

varying vec3 worldnormal;

void main()

在片段著色器中,我們現在可以將eyevector和worldnormal用作glsl內建折射函式的前兩個引數。第三個引數是折射率的比率,即我們的快速介質(空氣)的折射率(ior)除以我們的慢速介質(玻璃)的ior。在這種情況下,該值為1.0 / 1.5,但是您可以調整該值以獲得所需的結果。例如,水的ior為1.33,鑽石的ior為2.42。

真好!我們成功編寫了折射著色器。但是我們的鑽石幾乎看不見……部分原因是我們只處理了玻璃的一種視覺特性。並非所有的光都會穿過要折射的材料,實際上,一部分光會被反射。讓我們看看如何實現它!

為了簡單起見,在本教程中,我們將不計算適當的反射,而僅將白色用作反射光。現在,我們怎麼知道什麼時候該反思,什麼時候該折射?理論上,這取決於材料的折射率,當入射向量和表面法線之間的角度大於臨界角時,光波將被反射。

在片段著色器中,我們將使用菲涅耳方程來計算反射光線與折射光線之間的比率。不幸的是,glsl也沒有內建此方程式,但是您可以從這裡複製它:

float fresnel(vec3 eyevector, vec3 worldnormal) 

現在,我們可以根據剛計算出的菲涅耳比,簡單地將折射紋理顏色與白色反射顏色混合。

看起來已經好多了,但是還有一些不足之處……嗯,我們看不到透明物件的另一面。讓我們解決這個問題!

資源搜尋**大全

廣州vi設計公司

到目前為止,我們已經了解了有關反射和折射的知識,我們可以理解,光在離開物件之前可以在物件內部來回**幾次。

為了獲得物理上正確的結果,我們將必須跟蹤每條光線,但是不幸的是,這種計算量太大,無法實時渲染。因此,我將向您展示乙個簡單的近似值,至少可以直觀地看到我們鑽石的背面。

在乙個片段著色器中,我們需要幾何圖形的正面和背面的世界法線。由於我們不能同時渲染兩側,因此需要首先將背面法線渲染為紋理。

讓我們像在步驟1中一樣製作乙個新的shadermaterial,但是這次我們將世界法線渲染為gl_fragcolor。

varying vec3 worldnormal;

void main()

接下來,我們將更新渲染迴圈以包括背面通道。

this.backfacefbo = new three.webglrendertarget(width, height);

...render() ;

現在,我們在折射材料中取樣背面法線紋理。

vec3 backfacenormal = texture2d(backfacemap, uv).rgb;
最後,我們結合了正面和背面法線。

float a = 0.33;

vec3 normal = worldnormal * (1.0 - a) - backfacenormal * a;

在此等式中,a只是乙個標量值,指示應應用背面法線的數量。

我們做到了!我們可以看到鑽石的所有側面,僅是因為我們對鑽石的材質進行了折射和反射。

正如我已經解釋的那樣,用這種方法實時渲染物理上正確的透明材料是不可能的。當在彼此前面渲染多個玻璃物件時會發生另乙個問題。由於我們僅對環境取樣一次,因此無法看透一連串的物件。最後,我在這裡演示的螢幕空間折射在畫布的邊緣附近效果不佳,因為光線可能會折射到其邊界之外的值,並且在將背景場景渲染到渲染目標時我們沒有捕獲到該資料。

當然,有多種方法可以克服這些限制,但是對於您在webgl中進行實時渲染,它們可能並不是全部很好的解決方案。

單點登入只需三步

操作檢測 public function check login type 1 this load m admin admin uid this getgpc admin s t ok en token t oken this getcookie admin login token var dump...

只需三步!慢日誌去無蹤

作者 第一步 explain 最先登場的毫無疑問就是 explain 語句了,用過 mysql 的人應該都知道這個檢視 sql 語句執行計畫的命令,詳細的資料在網上有很多,這裡就略過了。一般來說,95 的慢查詢問題只需要 explain 就可以解決了。手工執行的時候,在 extra 列裡面,避免出現...

vue入門之環境搭建只需三步

我們一般用npm命令列安裝vue,所以第一步安裝node.js,如果已安裝就可以忽略此步驟 node.js node.js 安裝node.js一路next即可。在命令列中輸入vue npminstall global 注意 此處是全域性安裝 在命令列中輸入vue npminstall g vue c...