天天看點

遊戲開發面試題 -- 圖形學篇

圖形學和3D數學篇,收錄了幾十道面試真題,也歡迎小夥伴後續提供以便繼續更新。

因第二篇内容主要來源于網上,未原創發表在公衆号,文章連結如下。

遊戲開發面試答案篇(二)-- Unity篇   https://zhuanlan.zhihu.com/p/554529423

1. 渲染管線

(1). 渲染管線就是一堆原始圖形資料經過各種變化處理最終出現在螢幕的過程。

渲染管線可分為三個階段,應用程式階段,幾何階段,和光栅化階段

(2). 應用程式階段由CPU主要負責。CPU将GPU渲染需要的燈光、模型準備好,并設定好渲染狀态,為GPU渲染做好準備。

(3). 幾何階段把輸入的3D資料轉換成2D資料。包括頂點着色器、圖元裝置、裁剪和螢幕映射幾個過程。

頂點着色器主要進行頂點坐标變換。将輸入的模型空間頂點坐标變換到裁剪空間頂點坐标。

圖元裝配将頂點裝配成指定圖元的形狀。

幾何着色器改變圖元。通過産生新頂點構造出新的圖元來生成其他形狀。

(4). 光栅化階段把圖元映射為最終螢幕上顯示的顔色。包括光栅化,片段着色,深度測試和混合。

光栅化将頂點轉為螢幕上的像素。

片段着色器計算每個像素的最終顔色。

深度測試通過深度資訊判斷像素的遮擋關系。

混合階段通過透明度将像素進行混合。

(5). 最終渲染好的顔色先被送入後置緩沖,随後再替換前置緩沖,顯示在螢幕上

2. 什麼是depth buffer

深度緩沖也稱z-buffer,用來存儲深度值以及在深度測試時确定一個片段是否被其他片段遮擋。

深度緩沖由視窗系統自動建立并将其深度值存儲為 16、 24 或 32 位浮點數。在大多數系統中深度緩沖區為24位。

當深度測試啟用的時候,如果此測試通過,深度緩沖内的值将被設為新的深度值。如果深度測試失敗,則丢棄該片段。

3. 提前深度測試

提前深度測試(Early depth testing)是一個由圖形硬體支援的功能。

提前深度測試允許深度測試在片段着色器之前運作。可以更早地踢掉一些片段永遠可見的片元,節省GPU資源 。

4. phong和billin-phong

Phong光照模型将光照分為三部分:環境光(Ambient)、漫反射光(Diffuse)和鏡面(Specular)光照。

環境光即來自其它物體,而非直接光源的光照。在Phong模型中是一個常數。

漫反射即粗糙物體表面均勻的反射光線到各個方向所産生的光照效果。

鏡面光照也稱高光反射,由光滑物體表面平行地向一個方向反射出來的光照效果。

Phong光照模型中,視線向量和反射向量的角度不允許大于90度。如果大于90度的話,點乘的結果就會是負數,鏡面的貢獻成分就會變成0。

Blinn-Phong鏡面反射的計算引入了半程向量(halfway vector)向量,半程向量是視線方向和反射向量之間的夾角。通過測量法線和半程向量之間的角度計算鏡面反射。

5. 前向渲染和延遲渲染的差別

前向渲染對于每一個需要渲染的物體,都要逐光源渲染,每個光源都會帶來一定的渲染成本。

延遲渲染将計算量非常大的渲染(如光照)延時到後期進行處理。包含兩個處理階段(Pass):在幾何處理階段中,先渲染場景一次,之後擷取對象的各種幾何資訊,并儲存在G緩沖(G-buffer)的紋理中。随後在光照處理階段中使用G緩沖内的紋理資料對每一個片段計算場景的光照。

延遲渲染隻需要對每一個像素執行一次光照運算,能夠渲染大量的光源而不消耗大量的性能。

延遲渲染不能進行混合(Blending),因為G緩沖中所有的資料都是從一個單獨的片段中來的,而混合需要對多個片段的組合進行操作。

延遲渲染需要大記憶體開銷,沒有MSAA。

延遲渲染對小且沒有很多的光源的場景,并不一定會更快。

延遲渲染不支援半透明物體渲染。

6. 透明物體和不透明物體渲染順序

先渲染所有的不透明物體,開啟深度寫入和深度測試

再渲染半透明物體,按由遠到近排序,先渲染遠處的物體,再渲染近處的。開啟深度測試,開啟混合,關閉深度寫入。

7. 如何優化shader

計算量優化

将計算從像素着色器移動到頂點着色器

在腳本中計算并傳遞給着色器,使用紋理讀取的方式減輕運算量

代碼優化

盡量使用系統自帶的内建函數,因為很多是硬體支援的

簡單的重複不多的計算,不應該将這種計算封裝成函數,直接用代碼計算即可

選擇合适的資料精度,盡量使用低精度

盡量不要使用if分支語句,可以使用step函數替代

8. shader中的if會造成性能影響以及如何優化

if的效率問題是會導緻多個分支重複執行。

在大多數沒有标明關鍵字的情況下,編譯器預設生成的是 flatten 形式的指令,flatten 把分支所有側的邏輯都執行一遍,根據判斷條件舍棄掉錯誤結果,選擇其中一個結果。

優化:

從關系運算符和邏輯運算符兩個角度,進行分支合并,轉換為非分支形式。或者使用内置指令代替内置指令替代。如等于不等于可轉換如下

遊戲開發面試題 -- 圖形學篇

9. 線性空間和srgb空間是怎麼反映的

線上性空間實體世界中的顔色和光照規律是光強度增加了一倍,亮度也增加一倍

顯示器顯示圖像的時候,電壓增加一倍,亮度增加2.2次幂的非線性關系,線性的顔色顯示在螢幕上相當于降低了2.2次幂的亮度

遊戲開發面試題 -- 圖形學篇

使顔色整體會偏暗,即顯示器的輸出在伽馬Gamma2.2空間

sRGB格式相當于對實體空間的顔色做了一次伽馬(gamma)校正

gamma校正将把線性顔色空間轉變為srgb空間(Gamma0.45空間),即

遊戲開發面試題 -- 圖形學篇

伽馬校正和顯示器輸出平衡之後,結果就是Gamma1.0的線性空間。

10. gamma correction是怎麼實作的

gamma 校正将線性空間變換到Gamma0.45空間,在數學上是一個約為0.45的幂運算

遊戲開發面試題 -- 圖形學篇

11. 頂點着色器實作光照會怎麼樣

逐頂點光照,也稱為高洛德着色,在頂點着色器中對每一個頂點進行光照計算,然後會在渲染圖元内部進行線性插值,最後輸出成像素着色。

逐頂點光照的性能開銷遠遠小于逐像素,因為頂點數遠遠要小于像素數。但是由于逐頂點的像素依賴于頂點的線性插值來取得效果,是以隻要是非線性的光照計算使用逐像素光照都會或多或少的産生有問題的效果。(效果不一定正确)

12. 頂點着色器作用,包括什麼工作

頂點着色器,是對頂點進行一系列操作的着色器,對物體頂點進行控制,如位置改變。能實作各類效果如布類仿真,進階别動畫,實時修改透視效果

13. 頂點着色器到片元着色器中間流程

頂點着色器到偏遠着色器需要經過:圖元裝配、幾何着色器、光栅化

圖元裝配:将頂點裝配成指定圖元的形狀(如三角形)。

幾何着色器:改變圖元。通過産生新頂點構造出新的圖元來生成其他形狀。外殼着色器和域着色器可程式設計,鑲嵌器是由硬體管理。

光栅化:把圖元映射為最終螢幕上相應的像素(把三角型切分成一個個像素)。

14. 幾何着色器的作用,頂點着色器傳輸給幾何着色器什麼資料

幾何着色器在頂點和片段着色器之間,是一個可選的可程式設計的着色器。它能夠将頂點變換為完全不同的圖元,并且還能生成比原來更多的頂點。

以一個或多個表示為一個單獨基本圖形的頂點作為輸入,如一個點、線、或三角形

15. EBO存儲的資料是什麼,有什麼好處

索引緩沖對象(Element Buffer Object,EBO,也叫Index Buffer Object,IBO),專門存儲頂點的索引。

EBO節省了頂點數組的size,減少了重複儲存頂點資料

16. G-Buffer的底層結構

G緩沖(G-buffer)是對所有用來儲存光照相關的資料,并在最後的光照處理階段中使用的所有紋理的總稱。本質就算一個幀緩沖對象。

17. Drawcall 原理以及如何減少DrawCall

DrawCall是對底層圖形繪制接口的調用指令,調用GPU進行渲染。CPU往GPU發送渲染指令,GPU接受并執行相對應的渲染指令。

優化:

UI方面:使用圖集,批渲染

将一些渲染狀态一緻的物體合成一個大物體,把圖集轉移到一張大圖檔,一次送出給gpu進行繪制。

 模型方面:

每一幀把可以進行批處理的模型網格進行合并,再把合并後模型資料傳遞給GPU,然後使用同一個材質對其渲染。

18.光栅化的作用?

光栅化是把頂點資料轉換成片元的過程,即将幾何圖元變成二維圖像的過程,将三維場景投影到二維平面。

19. 實時陰影如何實作、生成

陰影有硬陰影和軟陰影。實時硬陰算法為shadowmap及其變種CSM、SSSM。

實時軟陰影算法包括PCF、PCSS、VSSM、SDF陰影。

(1). shadow map将深度資訊渲染到深度圖上,并在運作時通過深度對比檢測物體是否在陰影中的算法。

shadow map是一個2-pass的算法

pass1:從Light視角看向場景,記錄每個像素的最淺深度,輸出一個深度紋理圖。

pass2:從camera視角出發,檢測目前物體深度是否大于深度紋理中深度值,判斷是否在陰影裡

shadow map會産生自遮擋和走樣現象。

(2). PCF(percentage Closer Filtering)

PCF能解決shadow map的鋸齒塊和硬邊問題,産生柔和軟陰影。

核心思想是從深度貼圖中多次采樣,每一次采樣的紋理坐标都稍有不同(比如采樣像素周圍一圈範圍)。每個獨立的樣本可能在也可能不在陰影中。所有的次生結果接着結合在一起,最終通過樣本的總數目将深度結果平均化。

(3). PCSS

PCSS為了實作更真實的軟陰影,達到離遮擋物距離近的時候硬,遠的時候軟的效果。

1. 算每個區塊深度(shadow map上,隻算被遮擋點的平均深度)

2. 通過深度估算需要采樣範圍多大(curDepth - AvgDepth) / AvgDepth

3. PCF在shadow map上采樣,範圍由第二步确定

(4). VSSM (Variance Soft Shadow Mapping)

解決PCSS(第一步和)第三步慢的問題,優化了第三步範圍查詢shadow map得到平均深度值,直接使用切比雪夫進行猜測。

第一步:對shadow map進行區域平均深度計算平均深度的平方,并使用記錄

第三步:根據記錄查詢的方內插補點,根據目前點深度,用切比雪夫得到平均深度

(5). SDF(Disatance field soft shadows)

有向距離場SDF記錄了空間中任何一點到定義該場的物體之間的最小距離。将SDF距離作為安全距離,判斷光線是否與物體相交,可以加速光線步進。

SDF陰影原理:以采樣點為起點,沿着光線來的方向,發射另一根射向光源的射線,并通過SDF加速光線步進。如果這根射線也擊中了某個物體的表面,則證明該采樣點處于陰影之中,并使用目前步進的長度和上一步步進的長度計算軟陰影。

原理細節參考games202視訊​​https://www.bilibili.com/video/BV1YK4y1T7yY?p=3&vd_source=247e85b9b80345fa83fa152be97c604e​​

20. shadowmap實作原理

shadow map将深度資訊渲染到深度圖上,并在運作時通過深度對比檢測物體是否在陰影中的算法。

shadow map是一個2-pass的算法

pass1:從Light視角看向場景,記錄每個像素的最淺深度,輸出一個深度紋理圖

pass2:從camera視角出發,檢測目前物體深度是否大于深度紋理中深度值,判斷是否在陰影裡

21. 螢幕空間的陰影算法原理

  1. 渲染shadow map
  2. 渲染得到螢幕視角的場景深度紋理。
  3. 繪制場景物體,對片元采樣螢幕空間的陰影圖

22. PBR的了解

基于實體的渲染(Physically Based Rendering),指的是一些在不同程度上都基于與現實世界的實體原理更相符的基本理論所構成的渲染技術的集合。

判斷一種PBR光照模型是否是基于實體的,必須滿足以下三個條件

  1. 基于微平面(Microfacet)的表面模型。
  2. 能量守恒。
  3. 應用基于實體的BRDF。

參考​​https://learnopengl-cn.github.io/07%20PBR/01%20Theory/​​

23. 哪些描邊的技術以及有啥優缺點

法線外擴法:Vertex Shader階段将頂點向頂點法線方向移動一定距離

問題:描邊出現斷裂、無粗細變化、額外的空間存儲模型、額外一個Pass

菲涅爾方程描邊:描邊就發生在物體的邊緣上,而越靠近邊緣時頂點法線與錄影機向量間的點乘越靠近0,判斷這個點乘結果來判斷是否為描邊

問題:效果太不穩定了,尤其是平面會出現大片的描邊,适用于球型物體

基于貼圖的描邊:描邊直接畫在貼圖上

問題:對貼圖分辨率有着更高的要求,容易産生鋸齒

基于SDF描邊:到處描邊貼圖,将貼圖制作成SDF圖,渲染時将SDF圖還原成原貼圖

問題:需要多采樣一張SDF圖

24. 色調映射,HDR與LDR的差別

HDR(High Dynamic Range, 高動态範圍):顯示器被限制為隻能顯示值為0.0到1.0間的顔色,但是在光照方程中卻沒有這個限制。HDR使片段的顔色超過1.0,得到一個更大的顔色範圍。HDR渲染可以保證在明亮和黑暗區域無細節損失。

LDR(Low Dynamic Range,低動态範圍):将所有HDR值轉換成在[0.0, 1.0]範圍。

色調映射(Tone Mapping):轉換HDR值到LDR值的過程。

25. 為什麼延遲渲染對MSAA支援不好

因為延時渲染丢失了幾何資訊。

1、MSAA本質上是一種發生在光栅化階段的技術,也就是幾何階段後,着色階段前,用這個技術需要用到場景中的幾何資訊

2、延遲渲染因為需要節省光照計算的原因,事先把所有資訊都放在了GBuffer上,着色計算的時候已經丢失了幾何資訊

3、正常的延遲渲染相容不了MSAA,因為GBuffer丢了幾何資訊,如果一定要相容那麼就想辦法在GBuffer那一層把幾何資訊也記錄下來

​​https://zhuanlan.zhihu.com/p/135444145​​

26. BRDF與蘭伯特模型的聯系是什麼

蘭伯特光照模型是經驗模型,主要用來模拟粗糙物體表面的光照現象,被用作漫反射的模型

蘭伯特光照模型的BRDF函數是一個常量,它表示入射到物體表面之後反射的光在任意的反射方向上都具有同樣的能量

27. 球諧光照的了解

球諧光照實際上是一種對光照的簡化,通過球諧函數,将複雜的光照信号投影到基函數上存儲,然後在使用的時候再将基函數上的資料加起來重建光照信号。達到用的簡單的系數表示複雜的光照,節省時間空間。

28. 對伽馬校正的了解

RGB值與功率并非簡單的線性關系,而是幂函數關系,這個函數的指數稱為Gamma值,一般為2.2,而這個換算過程,稱為Gamma校正。

29. 螢幕空間陰影映射技術的優點

優化對陰影的overdraw。

30. 卡通渲染思路

卡通渲染(Cel-shading)是一種非真實感的渲染技術(NPR),卡通渲染的目的是使圖像呈現出手繪效果。

卡通渲染可以分為了三個部分,描邊、着色、卡通渲染風格。其中最核心的兩個部分是描邊和着色。描邊包括外輪廓和内輪廓。着色包括多色階降為低色階、冷色調和暖色調處理。

31. 如何渲染半透明物體

先在CPU中對需要渲染的半透明物體進行距離排序,然後與相機距離由遠及近逐個物體渲染、像素混合

32. 為什麼要用FrameBuffer

幀緩沖能夠實作很多後期處理效果

33. 紋理坐标?雙線性插值怎麼做的

紋理坐标(Texture Coordinate),用來标明該從紋理圖像的哪個部分采樣,紋理坐标在x和y軸上,範圍為0到1之間。

雙線性插值基于紋理坐标附近的紋理像素,計算出一個插值,近似出這些紋理像素之間的顔色。一個紋理像素的中心距離紋理坐标越近,那麼這個紋理像素的顔色對最終的樣本顔色的貢獻越大。

34. mipmap有什麼缺點

占用顯存

35. LOD怎麼做的

靜态Lod:在預處理過程中産生一個物體的幾個離散的不同Lod模型。實時繪制時根據特定的标準選擇合适的Lod模型來表示物體。

動态Lod:在動态Lod算法中生成一個資料結構,在實時繪制時可以從這個資料結構中抽取出所需的Lod模型。從這個資料結構中可以得到大量不同分辨率的Lod模型。

36. Bloom怎麼做的

Bloom和HDR結合使用。

先渲染一個有光場景,提取出場景的HDR顔色緩沖以及隻有這個場景明亮區域可見的圖檔。

再将提取的帶有亮度的圖檔模糊處理。

最後将結果添加到HDR場景上面。

37. 動态模糊怎麼做的

先将圖檔進行最大程度的模糊處理,再将原圖放置在模糊後的圖檔上面,通過不斷改變原圖的透明度(Alpha值)來實作動态模糊效果。

38. opengl與openglES

OpenGL ES是OpenGL的嵌入式裝置版本,OpenGL ES相對OpenGL删減了一切低效能的操作方式

沒有double型資料類型,但加入了高性能的定點小數資料類型。

沒有glBegin/glEnd/glVertex。

沒有實時将非壓縮圖檔資料轉成壓縮貼圖的功能。

39. 後處理了解嗎

後期處理是在3D渲染完成後,在輸出最終效果之前,對渲染完成的圖像再進行一定的處理。

40. 抗鋸齒方法的種類,各自優缺點

抗鋸齒方案可分為三類,時間抗鋸齒、空間抗鋸齒、圖像抗鋸齒。

時間抗鋸齒使用TAA(Temporal Anti-Aliasing),将過去幀中采樣的像素與在目前幀中采樣的像素混合以産生抗鋸齒圖像。在快速移動的鏡頭中容易出現鬼影問題。

空間抗鋸齒以較低分辨率表示高分辨率圖像。主要使用MSAA(多重采樣抗鋸齒)。使用多倍的螢幕分辨率大小的背景緩沖區和深度緩沖區,如4xMSAA使用4倍螢幕分辨率。需要多倍緩沖區,在延時渲染管線中難以支援。

圖像抗鋸齒也稱後處理抗鋸齒。主要使用FXAA(快速近似抗鋸齒),通過将圖像一定程度的模糊處理。是一種低消耗的抗鋸齒技術,但效果一般。

41、遮擋剔除算法種類

遮擋剔除是剔除被其他物體遮擋住而不在錄影機的可視範圍内物體,不對其進行渲染的技術。

包括離線和實時方案。離線方案常用PVS,通過預計算場景中哪些物體時可見的,并記錄下來,運作時通過查詢該位置可見物體進行渲染。但是無法處理動态物體。

實時方案包括SoftWare Occlsion(SOC)、Hierarchical Z-Buffering、GPU-Driven、硬體遮擋剔除。

42、光線追蹤的原理及大緻流程

原理:光線追蹤是通過跟蹤與光學表面發生互動作用的光線進而得到光線經過路徑的模型。

過程:光線跟蹤沿着到達視點的光線的反方向跟蹤,從螢幕上每一個相素出發,找出與視線相交的物體表面點P0,并繼續跟蹤,找出影響P0點光強的所有光源,進而算出P0點上精确的光線強度。

數學相關

1. MVP矩陣空間變換過程

模型變換M、視圖變換V、投影變換P,統稱MVP

MVP 變換将3維模型映射到螢幕2維坐标中, 參與 MVP 變換的資訊包括點、矢量、法線、切線等

模型變換(Model):物體本身的平移、旋轉、縮放,将模型空間轉換到世界空間

觀察變換(View):将世界空間轉換到觀察空間

投影變換(Projection):将觀察空間轉換到裁剪空間

最後要擷取螢幕坐标還需要一步:螢幕映射,擷取對應螢幕的 2D 坐标,又叫視口變換

2. M矩陣中旋轉、平移、縮放順序,分别在M矩陣的哪個部分

模型變換不同順序有不同的結果,一般地,先進行線性變換,再進行非線性變換,即縮放-> 平移-> 旋轉

平移對應第四列,縮放對應主對角線,旋轉對應前三行三列

3. 四元數的了解,如何從兩個向量判斷四元數(四個參數的代表内容)

四元數是四維空間中一個超球上面的點,滿足w²+x²+y²+z²=1,将三維空間無法解決的問題就映射到四維空間。

常用于解決3D旋轉問題,如歐拉角産生的萬向節死鎖

4. 變換矩陣裡每一列代表什麼

前三列代表縮放和旋轉,最後一列代表平移

5. 為什麼MVP矩陣是 4*4

多一個w分量,可以很友善的在3D向量上進行位移

6. 點乘叉乘幾何意義,用處

點乘是向量的内積,結果是一個實數,表示兩個向量的長度與它們夾角餘弦的積。即一個向量在另一個向量方向上的投影,也用于判斷兩個向量是否同向。

叉乘是向量的外積,結果是一個向量,用于生成第三個垂直于a,b的法向量,或者建構坐标系。也等于向量a和向量b構成的平行四邊形的面積

7. 點到平面的距離如何計算

需要給定平面上一點P,過P做平面的發向量,該點與P的連線向法向量投影,距離即為投影長度

8. 幾何階段的矩陣變換都有哪些

MVP

9. 如何判斷一個點是否在一個凸多邊形内

方法很多:

(1)面積和判别法:判斷目标點與多邊形的每條邊組成的三角形面積和是否等于該多邊形,相等則在多邊形内部。

(2)夾角和判别法:判斷目标點與所有邊的夾角和是否為360度,為360度則在多邊形内部。

(3)引射線法:從目标點出發引一條射線,看這條射線和多邊形所有邊的交點數目。如果有奇數個交點,則說明在内部,如果有偶數個交點,則說明在外部。

10. 旋轉有哪幾種方式?歐拉角會有什麼問題?講一下四元數

歐拉旋轉、矩陣旋轉、四元數旋轉

歐拉旋轉

優點:很容易了解,形象直覺;表示更友善,隻需要3個值(分别對應x、y、z軸的旋轉角度);但按我的了解,它還是轉換到了3個3*3的矩陣做變換,效率不如四元數;

缺點:之前提到過這種方法是要按照一個固定的坐标軸的順序旋轉的,是以不同的順序會造成不同的結果;會造成萬向節鎖(GimbalLock)的現象。這種現象的發生就是由于上述固定坐标軸旋轉順序造成的。理論上,歐拉旋轉可以靠這種順序讓一個物體指到任何一個想要的方向,但如果在旋轉中不幸讓某些坐标軸重合了就會發生萬向節鎖,這時就會丢失一個方向上的旋轉能力,也就是說在這種狀态下我們無論怎麼旋轉(當然還是要原先的順序)都不可能得到某些想要的旋轉效果,除非我們打破原先的旋轉順序或者同時旋轉3個坐标軸。

四元數旋轉

優點:可以避免萬向節鎖現象;隻需要一個4維的四元數就可以執行繞任意過原點的向量的旋轉,友善快捷,在某些實作下比旋轉矩陣效率更高;可以提供平滑插值;

缺點:比歐拉旋轉稍微複雜了一點點,因為多了一個次元;了解更困難,不直覺;

11. 為什麼使用齊次坐标

在MVP矩陣變換中為了将線性變換和非線性變換統一成一個線性變換

在3維到2維的過程中用于支援投影矩陣

繼續閱讀