彭人杰 段華瓊
摘要:該文介紹了計(jì)算機(jī)圖形學(xué)中基本的光照效果,講解了基本的蘭伯特光照模型與其改進(jìn)方案半蘭伯特光照模型。給出了實(shí)際運(yùn)用在uniIy游戲開發(fā)中的場景光照解決方案。
關(guān)鍵詞:unity;計(jì)算機(jī)圖形學(xué);光照模型
中圖分類號:TP393 文獻(xiàn)標(biāo)識碼:A
文章編號:1009-3044(2020)14-01 12-02
游戲是計(jì)算機(jī)等電子產(chǎn)品設(shè)備普及以來產(chǎn)生的一種娛樂方式,隨著硬件技術(shù)的進(jìn)步,人們對游戲體驗(yàn)的要求也越來越高,對游戲的畫面要求也大大提升。一款游戲的畫面質(zhì)量,很大程度上取決于其貼圖紋理和場景光照的效果。本文通過介紹基本的光照模型,并運(yùn)用到實(shí)際開發(fā)流程中所要做出的改進(jìn)模型,以此實(shí)現(xiàn)提升玩家游玩體驗(yàn)的光照效果。
1基本的蘭伯特光照模型
蘭伯特光照模型,于1760年由JohannHeinrich Lambea提出的,在其著作Photometria中,蘭伯特光照模型定義了一個(gè)理想的無光澤表面或漫反射表面,無論觀察視角如何改變,這個(gè)表面的亮度永遠(yuǎn)不變。也就是說,該光照模型是符合各向同性的。這個(gè)模型是由表面法線向量和光線向量所決定的。計(jì)算二者夾角的余弦值得到物體表面反射光線的強(qiáng)度。公式如下:
該光照模型以表面法線和光源方向做向量點(diǎn)乘運(yùn)算,但是,這兩個(gè)向量的夾角有可能為鈍角,比如,光線照不到的地方,那么該點(diǎn)乘運(yùn)算結(jié)果則是負(fù)值,這樣的結(jié)果就會造成不符合現(xiàn)實(shí)的場景出現(xiàn)在我們的游戲中,比如物體會被后面射來的光照亮,破壞了游戲場景的逼真度。為此,我們對向量點(diǎn)乘的運(yùn)算結(jié)果進(jìn)行一個(gè)截取,使其計(jì)算結(jié)果為非負(fù)值。如代碼中的max函數(shù),取0和點(diǎn)乘結(jié)果的最大值,若點(diǎn)乘為負(fù),值取0。圖1為著色器代碼在uniIv引擎中運(yùn)行的結(jié)果。
2改進(jìn)后的半蘭伯特光照模型
將上述的蘭伯特定律在unity中以shader文件進(jìn)行實(shí)現(xiàn)后,我們就得到了一個(gè)簡單的基于蘭伯特定律的漫反射光照模型,如圖2所示。但是,在這些模型的背面,是完全黑的,沒有任何的明暗變化,這就導(dǎo)致了該光照模型在光照無法到達(dá)的區(qū)域看起來宛如一個(gè)平面一樣,模型沒有任何細(xì)節(jié),游戲畫面顯得突兀,死板。這種光照要是運(yùn)用到游戲中,會大幅度消減玩家的游玩體驗(yàn)。
對于上述的畫面問題,人們提出了一些解決方案,例如間接光照。在現(xiàn)實(shí)生活中,即使有物體沒有被光源直接照射,人的肉眼還是可以看見它。這就是因?yàn)楣獾姆瓷湓斐傻拈g接光照。在現(xiàn)在的計(jì)算機(jī)圖形學(xué)中,可以通過環(huán)境光系數(shù)來統(tǒng)一代表間接光,或者是采用更加復(fù)雜,對硬件要求更高,畫面更加寫實(shí)的光線追蹤技術(shù)來渲染間接光。
但在某些情況下,比如在早期的游戲制作中,當(dāng)時(shí)的計(jì)算機(jī)技術(shù)遠(yuǎn)遠(yuǎn)沒有現(xiàn)在的成熟,沒有條件實(shí)現(xiàn)間接光照。就催生出一種基于蘭伯特定理的改進(jìn)模型,即半蘭伯特光照模型,該模型既保證了蘭伯特模型計(jì)算出來的光照結(jié)果大于0,又整體提升了亮度,使非直接受光面不是單純的置為黑色。這里運(yùn)用了一個(gè)在圖形學(xué)領(lǐng)域經(jīng)常有的變換,區(qū)間轉(zhuǎn)化——將另一個(gè)區(qū)間上的問題,轉(zhuǎn)化為已知公式的區(qū)間上去,并借助已知的公式或函數(shù)性質(zhì),使問題得到解決。在建立蘭伯特模型的時(shí)候,我們就將值范圍從(-1,1)化為(0,1)防止物體的背光面被從后面射來的光線照亮。那么蘭伯特光照模型的視覺改進(jìn)型——半蘭伯特光照模型,也是如此。它的本質(zhì)就是一個(gè)區(qū)間轉(zhuǎn)化,將值范圍縮小,使其背光面不要太黑。
半蘭伯特光照模型的公式如下:
將半蘭伯特應(yīng)用于unity中,我們就得到了圖3,可以看到,此時(shí)的背光面視角已經(jīng)改善了不少。雖然這種視覺加強(qiáng)技術(shù)并不一定符合現(xiàn)實(shí)物理規(guī)律,但它可以被應(yīng)用于不少的實(shí)際開發(fā)中,市場上不少二次元風(fēng)格的手游會應(yīng)用到這種節(jié)約資源的視覺光照技術(shù)。
3基于unity實(shí)現(xiàn)半蘭伯特光照的過程
3.1編程接口
我們這里采用unity shader這個(gè)unity內(nèi)置的編程接口來實(shí)現(xiàn)我們所需要的光照模型,shader,意為著色器。著色器是一種渲染圖形的一門技術(shù),也是渲染流水線的一個(gè)環(huán)節(jié)。
3.2渲染流水線基礎(chǔ)
渲染流水線也稱為渲染管線,是顯示芯片內(nèi)部處理圖像信號相互獨(dú)立的并行處理單元。它將儲存在計(jì)算機(jī)內(nèi)部的圖像數(shù)據(jù)轉(zhuǎn)化為肉眼可見的圖形,渲染流水線的工作原理與生活中的生產(chǎn)流水線相符,其效率都是由最耗費(fèi)時(shí)間的環(huán)節(jié)決定。一般情況下有三個(gè)階段:應(yīng)用階段,幾何階段和光柵化階段。應(yīng)用階段的任務(wù)是輸出渲染圖元(即完成渲染工作所需要的幾何信息);幾何階段將應(yīng)用階段得到的圖形頂點(diǎn)坐標(biāo)從模型空間轉(zhuǎn)換為屏幕空間,再將數(shù)據(jù)傳遞給光柵化階段;光柵化階段決定了各個(gè)像素的繪制位置等。
3.3 CPU與渲染流水線
渲染流水線中的每一步輸入信息都是由上一步處理后得到的,而渲染流水線的輸人則是由CPU完成的。通過CPU將數(shù)據(jù)從硬盤加載到系統(tǒng)內(nèi)存中,之后從內(nèi)存加載到顯存。CPU還會將一個(gè)命令發(fā)送給GPU并指令GPU通過頂點(diǎn)數(shù)據(jù)和渲染狀態(tài)完成各個(gè)網(wǎng)格的渲染工作,輸出最終像素。這個(gè)命令是由CPU調(diào)用圖形編程接口完成的(也稱為DrawCall)。
3.4 GPU處理渲染流水線
GPU以流水線的形式高效地完成了渲染工作,如圖4。
其中,頂點(diǎn)著色器,曲面細(xì)分著色器,幾何著色器和片元著色器是可以由開發(fā)者編程控制的(除了頂點(diǎn)著色器,其余都是可選的)。頂點(diǎn)著色器主要實(shí)現(xiàn)頂點(diǎn)的空間變換和逐頂點(diǎn)光照,所有的頂點(diǎn)都要調(diào)用一次頂點(diǎn)著色器,該著色器最重要的一個(gè)功能是,將頂點(diǎn)從模型空間變換至齊次裁剪空間中,方便后續(xù)的計(jì)算。曲面細(xì)分著色器和幾何著色器分別負(fù)責(zé)細(xì)分圖元和圖元著色工作。片元著色器(DirectX中被稱為“像素著色器”)將得到的位于齊次裁剪坐標(biāo)下的頂點(diǎn)數(shù)據(jù)進(jìn)行計(jì)算,計(jì)算出每個(gè)像素的最終顏色和深度以及丟棄無需的片元。該著色器可以多次訪問紋理內(nèi)存,并以任意方式結(jié)合所讀取的值。在這次對于半蘭伯特光照的實(shí)現(xiàn)中,我們就要重點(diǎn)完成頂點(diǎn)著色器和片元著色器的代碼編寫。
3.5利用unity的ShaderLab實(shí)現(xiàn)著色器編程
Unity中的所有著色器文件都是使用名為ShaderLab的聲明性語言來編寫。在文件中,嵌套大括號語法聲明了描述著色器的各種內(nèi)容,比如使用哪種混合模式,是否使用前向光照,在材質(zhì)面板顯示哪些屬性等等。這種語言并不只是著色器代碼,而是包含了一個(gè)游戲?qū)ο蟮牟馁|(zhì)所需包含的全部信息。
Unity引擎會根據(jù)運(yùn)行的平臺來把我們編寫的uniIv shader編譯成真正的代碼和著色器文件。我們僅需要完成ShaderLab的編程設(shè)計(jì)。
3.6 CG代碼實(shí)現(xiàn)
Unity shader我們采用ShaderLab編寫,而里面的頂點(diǎn)著色器和片元著色器,則使用CG,HLSL,GLSL這類著色語言編寫,因?yàn)镃G和HLSL十分類似,所以在unity里,CG和HLSL是等價(jià)的,實(shí)現(xiàn)代碼如下:
4結(jié)束語
本文論述了以unitv引擎為基礎(chǔ)實(shí)現(xiàn)的半蘭伯特光照模型,通過借助對基本的蘭伯特定律推斷出來的漫反射光照模型進(jìn)行區(qū)間轉(zhuǎn)化,將值范圍修改至符合人體視覺感受的光照效果范圍,并且GPu無需太大的消耗。該光照實(shí)現(xiàn)方案可運(yùn)用于Cel-shading、Toon-Shading和漸變紋理中。