小程序•小故事(18)——微信3D小游戲下HUD繪制的經驗分享

發布時間:2018/11/17 20:50:24來源:微信開發者 點擊 5

平視顯示器(head up display)簡稱HUD。游戲經常在三維場景上疊加文本或二維圖形信息,如彈窗,血量條等,同時需要保證它們在屏幕上的位置和大小不變。


傳統的H5游戲可以使用dom,或是在原本的webgl上面蓋一個新的2D canvas(畫布)做為HUD來實現,同時使用其接口就可以畫出HUD所需要的內容。

但微信小游戲只支持一個畫布,無法和傳統H5游戲的繪制方式一樣。因此,要在3D世界中實現HUD就必須在這個唯一的畫布上實現。


我們在后臺收到了許多反饋:如何用小游戲的框架來實現HUD的繪制。這一期的小故事,我們跟大家分享如何在微信3D小游戲中繪制HUD:


本文的內容包括:

1.微信小游戲只支持一個畫布

2.如何使用三維平面模擬HUD?

3.相機變化導致HUD產生位移縮放

4.如何用圖形渲染管線解決上述問題?

5.繪制場景時視點變化與投影階段的問題

6.如何使用頂點著色器解決上述問題?


微信小游戲只支持一個畫布


與瀏覽器不同,微信客戶端只有一個畫布,并且不能使用html。


普通H5游戲會使用html,或是創建一個新的2D canvas標簽,定位在原本的webgl canvas上面,同時使用2D canvas的接口就可以畫出HUD的內容。但微信小游戲不支持這樣做。所以在三維世界中要實現HUD,需要在一個畫布上實現。


所以在三維世界中要實現HUD,則必須在這個唯一的畫布上實現。


如何使用三維平面模擬HUD?


對于圖像,webgl可以通過紋理貼圖來展示圖像。開發者可將圖片作為的紋理貼圖,貼在一個三維矩形平面上,使平面一直正對相機,來模擬HUD。



對于文字,微信小游戲三維的canvas是使用webgl作為context的。但是webgl卻無法像2D的context能直接畫文字。開發者如果直接用webgl畫出文字,需要導入文字模型的頂點數據,但由于文字比較復雜,頂點數量多,相當于渲染了一個復雜的3D物體,這種方式無論是從文件大小還是性能上,都會有損體驗。



那么是否可以使用2D canvas 繪好文字,再作為紋理貼在三維平面上呢?


雖然微信小游戲只能渲染一個canvas,但是開發者可以創建多個的canvas實例。


Step1:開發者可創建一個離屏的2D canvas,再使用2D的接口繪制文字、圖片等;


Step2:開發者可將這個離屏canvas傳給webgl,當成一個texture,貼到一個三維的平面物體上,使其永遠都在相機的正前方,通過這樣模擬HUD 。


補充

webgl支持直接將canvas作為紋理;

void gl.texImage2D(target, level, internalformat, format, type, HTMLCanvasElement? pixels)。




相機變化導致HUD產生位移縮放


游戲場景中的相機是會改變的,比如說吃雞游戲中的第一人稱和第三人稱視角轉化。我們發現了一個問題:當相機的可視范圍變化的時候,HUD就會發生形變。



那是因為視野看的越廣,映射到屏幕上的時候,同一個物體就顯得越小。


我們需要保證HUD在任何視角下位置大小都是正確無誤的。那么如何才能做到呢?


要解決這個問題就需要明白計算機是如何把三維場景畫到二維的屏幕上的。這個畫的過程也就是計算機圖形渲染管線幫我們完成的。


如何用圖形渲染管線解決上述問題?


畫一個三維物體到二維平面可以分為三個階段:


●“準備數據” (應用程序階段)

●“畫點” (幾何階段)

●“畫像素” (光柵化階段)



一個HUD實際上是一個矩形的平面物體,通過矩形的4個頂點就可以描述出來一個平面的位置、大小。為了讓平面的位置,大小看起來沒問題,我們需要修改“畫點”階段的邏輯。這個階段又可以進行如下的細分。



與攝影機相關的邏輯,是視點變換還有投影階段。我們可以通過修改這兩者的邏輯來達到我們的目的。


繪制場景時視點變化與投影階段的問題


1.視點變化階段的問題


我們需要繪制攝像機看到的世界,而攝像機可以處在任意位置觀察這個世界。視點變化本質是就是根據攝像機看的方向來旋轉物體,從而讓三維空間的物體正確旋轉到觀察者看到的樣子。圖片中標注的文字理解:原本是擺正放的物體,由于觀察者的視角問題(歪著看),所以顯示出來物體最終也是歪的。



通過在應用程序階段定義相機的視點、觀察目標點以及上方向等數據,我們可以得到一個叫做視圖矩陣(View Matrix)的矩陣。把這個矩陣與物體的位置做矩陣乘法就可以得到物體變化后的新位置。


因為游戲世界中,攝像機的位置是不停變化的,而我們的物體卻需要一直出現在攝像機正前方。所以游戲場景中的視覺矩陣(View Matrix)在每一幀的渲染中,可能都在變化。這里我們只要將HUD原本一直在變化的視覺矩陣(View Matrix)替換為我們需要的,并且保持不變就好了。


2.投影階段的問題


投影其實是把透視攝像機原本的可視范圍,壓縮成一個單位立方體。



再通過屏幕映射,就會出現如下的效果出來。



這一個過程中,會通過攝像機定義的數據(比如長寬比,視場,近截面,遠截面),來生成一個叫做投影矩陣(Projection Matrix)的矩陣。將這個矩陣與位置信息進行矩陣乘法,再進行一些歸一化操作,就會得到單位立方體內的位置。


和視覺矩陣(View Matrix)一樣,對于HUD的物體,我們也不能使用透視攝像機生成的矩陣,否則就會可能導致大小變化。我們替換成正視攝像機的矩陣。這樣算出來的位置就是永遠都是正常的,不需要擔心游戲中更新了相機的數據。


如何使用頂點著色器解決上述問題?


現在我們要用頂點著色器來修改視點變換還有投影的邏輯。


頂點著色器與片元著色器都是 webgl 提供給我們用來操作渲染管線的能力。讓我們可以使用glsl 這種編程語言來對 GPU 的能力進行編程。



頂點著色器運行在“畫點”階段(幾何階段),也就是對每個三維物體的頂點進行計算。片元著色器運行在“畫像素”階段(光柵化階段),把頂點圍起來的像素(其實是片元)畫上顏色。


我們可以通過頂點著色器,修改視點變換與投影的邏輯,最后達到我們的效果。


總結


由于微信小游戲支持一個單獨的畫布,開發者想要在任何游戲場景下繪制正常的HUD,可以通過頂點著色器的能力,去修改視點變換與投影的所用到的矩陣,最終來解決這個問題。


微信小游戲還有很多與H5游戲、客戶端游戲不一樣的設計理念與特點,我們會在后續的文章里繼續分享微信小游戲背后的小故事。

掃二維碼打開公告

{article_up.url}

{article_down.url}

0 個回答

,全世界都等著看你的驚世評論!

Copyright 2009-2017 我愛廣告任務網 版權所有  粵ICP備11078991號-1  ICP證:粵B2-20130544   

×

我愛官方微信二維碼

打開微信,點擊右上角的“魔法棒”,選擇“掃一掃”功能,對準下方二維碼即可。

免費注冊 收藏本站 官方新人群
返回頂部
三肖中特牛虎鼠