如何在 Minecraft 中加入元素視野效果(一)

一、前言
最近在學(xué)?GLSL(OpenGL Shading Language)的相關(guān)知識,正巧 Minecraft 光影就是這方面的東西,所以準備動手制作了一個簡單的光影,它能夠像做到像原神的元素視野一樣“掃描”場景中的事物。
由于 Minecraft 使用的渲染引擎,也就是?OpenGL?的版本十分老舊,在效率低下的同時,也對遠古顯卡擁有很好的兼容性。雖然其在快照版本?21w10a (1.17)?時更新到了?OpenGL 3.2 (2009),不過在此之前一直使用?OpenGL 2.1?(2006)。
如果有不對的地方,歡迎在評論區(qū)指出 ~

二、環(huán)境
準備好一個可以運行光影的?Minecraft?客戶端,版本 20w22a (1.16)?及以上,因為在更新日志中有指出,深度緩沖區(qū)在此版本中加入,而掃描特效正好需要使用此緩沖區(qū)的數(shù)據(jù)。我并沒有測試過低版本能否運行,所以這里為了保險起見建議使用新版本來開發(fā)。
準備一個光影加載器,像 Optifine 或者?Iris Shaders 之類的主流加載器一般都沒問題。
在這里我使用了游戲版本 1.19.4 以及 Iris?Shaders?1.6.4,因為?Iris?Shaders 能夠為用戶輸出光影包的錯誤信息,供開發(fā)者快速定位 bug 的位置,是我個人比較喜歡的一個 Mod。

三、創(chuàng)建
為了使客戶端可以讀取到我們的光影,需要進入其光影文件夾中,并在其中建立一個光影我們的光影包,它依然可以是一個文件夾,而并非需要像網(wǎng)上下載的那樣壓縮成 zip。這個光影包的名字是隨意的,只要確保你準備的光影加載器能夠讀取到即可。
PS:如果你的文件管理能力比較強,也可以嘗試在其他位置建立這樣的一個包,并使用版本管理工具改善開發(fā)工作。

進入我們創(chuàng)建好的光影包文件夾中,創(chuàng)建一個 shaders 文件夾,這里將是加載器加載的地方。在其中創(chuàng)建名為?final.vsh?與?final.fsh?的文件,作為接下來需要編寫的頂點著色器(vertex shader)和片段著色器(fragment shader)。

四、頂點著色器
Minecraft?光影首先會為畫面上的多種物件進行分開渲染,如云朵、天空、方塊、實體等,將使用不同的著色器代碼進行先一步繪制,而最終所有物件將匯集到?final 著色器,進行最后的處理。要實現(xiàn)這個簡單的光影,我們只需要用到 final 著色器即可。
首先打開創(chuàng)建好的?final.vsh 文件,在此著色器中,可以對當(dāng)前顏色位置進行一些變換,由于原神中的場景掃描僅僅只是改變了畫面的顏色,所以我們并不需要對位置做任何事情,只需要將當(dāng)前位置傳遞到?fsh 著色器中即可。
在最開始寫上 #version 120 表示該著色器將使用 GLSL 1.20 版本,接著創(chuàng)建一個二維向量?texCoord?用于將數(shù)據(jù)傳遞至 final.fsh 中,下方則是主要代碼位置,寫上 main 函數(shù),寫到這里我們已經(jīng)不難看出,GLSL 的語法其實類似于耳熟能詳?shù)?c 語言。
使用 ftransform() 函數(shù)對內(nèi)置變量?gl_Position?寫入原本的數(shù)據(jù),輸出原本的位置信息,此時我們還需要將位置信息中的?x 與 y 寫入 texCoord,用于下一個階段的渲染。在著色器語法中,把需要用到的向量屬性連起來寫,如這里的 xy,將會轉(zhuǎn)換為一個二維向量。
五、片段著色器
雖然這跟上一個著色器有著不一樣的名稱,但它們其實只是渲染的兩個階段,這些階段都將在顯卡處理器中運行,所以它們擁有相同的語法,以及不同的可使用數(shù)據(jù)。
首先我們編寫一個最簡單的例子,用于測試光影是否穩(wěn)定運行。我們將需要的代碼寫上,一個 從上一階段傳遞過來的變量?texCoord,一個二維紋理變量 gcolor,以及用于渲染的 main 函數(shù)。此時我們使用?texture2D 函數(shù)檢索紋理 gcolor 在位置?texCoord 中的顏色,并把顏色中的 r 與 b 調(diào)換位置,此時我們將得到一個紅色與藍色調(diào)換的世界。
PS:如果不成功,請檢查光影加載器提供的錯誤信息,并修復(fù)代碼中的錯誤。
