
簡介這是一份面向圖形學求職者與3D開發(fā)者的OpenGL面試題資料圍繞計算機圖形學核心考點整理適合準備圖形渲染、游戲引擎方向面試的中高級開發(fā)者查漏補缺。壓縮包內共1個doc文檔約19KB內容以問答形式覆蓋渲染對象矩陣、渲染流水線、ZBuffer深度緩沖、Alpha混合公式、3D動畫方式、顯卡優(yōu)化、硬件D3D燈光及GF4 MX與TI系列差異等知識點。文檔還包含四元數(shù)共軛、向量點乘叉乘、旋轉矩陣、相機參數(shù)設置、LOD、Vertex Shader、陰影判斷、MipMap等幾何與數(shù)學題目并附有渲染管線流程、骨骼旋轉矩陣、圖形引擎架構分析等簡答與分析題。已有1741人學習下載可幫助讀者系統(tǒng)梳理OpenGL與D3D面試高頻考點理解矩陣變換、混合與動畫實現(xiàn)原理并借助真題演練檢驗圖形學基礎與引擎設計思路。1. 渲染管線與矩陣這場 OpenGL 面試到底考什么很多人準備 OpenGL 面試第一反應是背 API結果一上來自我介紹完面試官直接甩一句“說說渲染管線里 w 切分之后發(fā)生了什么”當場卡殼。這場面試考的不是你會不會調glDrawArrays而是你對 3D 圖形學底層鏈路有沒有完整的認知框架。從檢索到的題目分布看矩陣變換、渲染流水線、ZBuffer、Alpha 混合、光照模型、幾何數(shù)學、性能分析這幾塊幾乎覆蓋了 80% 以上的面試分值。換句話說面試官想確認的是給你一個 Model Space 里的三角形你能不能一步步說清楚它怎么變成屏幕上的像素中間每一步在算什么、為什么這么算。適合誰看準備圖形學崗位、引擎開發(fā)、渲染方向或者筆試里突然出現(xiàn)四元數(shù)和矩陣逆的那批人。2. 矩陣與坐標系三個矩陣、四元數(shù)、逆矩陣的連環(huán)追問2.1 世界、視圖、投影矩陣到底各自在算什么面試官問“渲染對象時需要設置哪三個矩陣”不是讓你背名字而是想聽你講清楚每個矩陣把頂點從哪個空間變到哪個空間。世界矩陣負責把模型空間里的獨立物體擺到統(tǒng)一的世界坐標里組織成一個完整場景視圖矩陣由虛擬攝像機決定把世界坐標轉到觀察空間本質上是攝像機位置和朝向的逆變換投影矩陣把三維場景壓到二維平面上分為正交投影和透視投影透視投影會產生近大遠小的效果。這類題通常這么答先點明三個矩陣的名字和順序再補一句“世界矩陣管擺放視圖矩陣管觀察投影矩陣管成像”最后落到 MVP 變換的乘法順序上。面試官最想聽的是你知道矩陣是左乘還是右乘、列主序還是行主序以及為什么投影之后還要做透視除法。2.2 四元數(shù)共軛、逆、繞軸旋轉的真題演練真題里有一道寫出四元數(shù) Q(0.3, 0.7, 0.8, 0.9) 的共軛。四元數(shù)一般表示為 (w, x, y, z)共軛就是虛部取反所以結果是 (0.3, -0.7, -0.8, -0.9)。另一道是繞軸 (0.2, 0.5, 0.9) 旋轉 π/4寫出旋轉后的四元數(shù)。標準做法是先歸一化軸向量再代入四元數(shù)旋轉公式import math def quaternion_from_axis_angle(axis, angle): # 歸一化旋轉軸避免縮放影響旋轉結果 length math.sqrt(sum(c * c for c in axis)) ax [c / length for c in axis] half angle / 2.0 w math.cos(half) s math.sin(half) return (w, ax[0] * s, ax[1] * s, ax[2] * s) q quaternion_from_axis_angle([0.2, 0.5, 0.9], math.pi / 4) print(q)這段代碼的關鍵在于軸必須先歸一化否則旋轉角度會失真half 是把旋轉角除以 2因為四元數(shù)用的是半角公式。面試官追問“四元數(shù)的逆有什么意義”你要答單位四元數(shù)的逆等于共軛代表反向旋轉四元數(shù)與逆相乘得到單位四元數(shù) (1, 0, 0, 0)數(shù)值上就是無旋轉。矩陣的逆在 3D 中的作用類似用來把變換反向還原比如從世界空間回到模型空間做拾取計算。2.3 矩陣轉置、旋轉矩陣、相機參數(shù)設置的筆試題幾何部分??冀o一個 3×3 矩陣寫轉置、繞 X 軸旋轉寫旋轉矩陣、矩陣相乘寫代碼。繞 X 軸旋轉 θ 的矩陣是import math def rotation_x(theta): c math.cos(theta) s math.sin(theta) # 繞X軸旋轉只影響Y和Z分量X保持不變 return [ [1, 0, 0], [0, c, -s], [0, s, c] ]參數(shù)說明theta 是弧度制矩陣第三行第二列是 s第三行第三列是 c符號別寫反。相機參數(shù)設置題通常給 near distance 和 near 與 far 的距離要求寫出投影矩陣參數(shù)。透視投影矩陣里near 和 far 決定深度映射范圍near 太小會導致深度精度下降far 太大會讓遠處物體 z-fighting。這類題面試官想看的是你知不知道 near/far 比值對深度緩沖精度的影響而不是單純套公式。3. 渲染流水線與光柵化從頂點到像素的每一步3.1 渲染管線順序的真題與易混點真題里有一道選擇題渲染管道流程是哪個選項給了輸入組裝、頂點、圖元、像素的不同排列。正確答案是輸入組裝 - 頂點 - 圖元 - 像素。面試官問“一個在 Model Space 中的三角形經過渲染管線中的哪些計算步驟最后到屏幕輸出”完整的回答應該是局部空間 - 世界空間 - 觀察空間 - 背面消隱 - 光照計算 - 裁剪 - 投影變換 - 視口變換 - 光柵化。注意這里背面消隱和光照的順序在不同管線里可能略有差異但核心鏈路不能亂。這類題通常這么答先按空間變換順序說一遍再補一句“其中頂點著色器負責頂點變換和光照圖元組裝負責把頂點連成三角形光柵化負責把三角形變成像素片段像素著色器負責最終顏色計算”。面試官最想聽的是你知道每個階段在 GPU 的哪個單元執(zhí)行以及哪些階段是可編程的。3.2 ZBuffer、w 切分、視口變換的作用ZBuffer 是深度緩沖作用是確保多邊形按正確的深度顯示。面試官追問“渲染任何物體時是否都一定要打開 ZBuffer”你要答不一定。對于兩個物體以上的場景一般要求打開否則可能出現(xiàn)非正常的立體感觀但如果是純 2D 渲染或者已經手動排序好的半透明物體可以關閉 ZBuffer 或者把深度寫入關掉。w 切分發(fā)生在投影之后把齊次坐標除以 w得到歸一化設備坐標。視口變換把歸一化坐標映射到屏幕像素坐標。提示面試里如果被問到“為什么半透明物體要最后渲染并且關閉深度寫入”你要能接上因為半透明需要和背后已經渲染好的顏色做混合如果先渲染半透明并寫入深度后面的不透明物體就會被深度測試擋掉導致混合結果錯誤。3.3 光照計算與 diffuse 公式光照計算中 diffuse 的公式是diffuse lightColor * materialDiffuse * max(0, dot(normal, lightDir))。面試官問“pix 渲染時進行的光照計算”或者“渲染管道 pix 時采用硬件光照不會進行什么”你要注意硬件光照通常只做逐頂點或逐像素的光照計算陰影計算一般不在固定管線里自動完成。diffuse 計算的關鍵是法線和光線方向的點乘點乘結果為負說明光線在背面直接取 0。def diffuse_light(normal, light_dir, light_color, material_diffuse): # 法線和光線方向都需要歸一化 n normalize(normal) l normalize(light_dir) # 點乘為負說明光在背面取0避免負顏色 ndotl max(0.0, dot(n, l)) return [light_color[i] * material_diffuse[i] * ndotl for i in range(3)]參數(shù)說明normal 是表面法線light_dir 是從表面指向光源的方向light_color 是光源顏色material_diffuse 是材質漫反射系數(shù)。這段代碼的易錯點是忘記歸一化導致點乘結果不在 -1 到 1 之間光照強度會翻車。4. 紋理、混合與動畫Alpha、MipMap、骨骼動畫的考法4.1 Alpha 混合公式與混合方式Alpha 混合的公式是Color (源顏色 * 源系數(shù)) OP (目標顏色 * 目標系數(shù))。OP 有加、減、反減、取最小、取最大。面試官問“介紹你所有知道的紋理 Alpha 混合方式以及實際應用”你要能說出普通半透明用源 alpha 作為源系數(shù)、1 減源 alpha 作為目標系數(shù)疊加發(fā)光效果用加法混合陰影或者暗化效果用乘法混合。實際應用中半透明玻璃、火焰、煙霧、UI 淡入淡出都依賴 Alpha 混合。這類題通常這么答先寫公式再舉兩到三種混合方式對應的效果最后補一句“混合順序很重要不透明物體先渲染半透明物體按深度從遠到近排序渲染”。面試官最想聽的是你知道混合會破壞深度關系所以排序和深度寫入策略必須配合。4.2 MipMap 與 LOD 的優(yōu)缺點MipMap 是一組預先計算好的縮小版紋理作用是解決遠處紋理采樣時的走樣和性能問題。LOD 是細節(jié)層次根據物體距離或者屏幕占比選擇不同精度的模型。LOD 的優(yōu)點是減少遠處物體的三角形數(shù)量提升渲染性能缺點是切換時可能出現(xiàn)視覺跳變需要做淡入淡出或者 geomorphing。面試官問“LOD 是什么優(yōu)缺點”你要能結合場景說大規(guī)模地形和開放世界游戲里 LOD 幾乎是標配但 LOD 切換的閾值和過渡策略需要仔細調否則會出現(xiàn)模型突然變形的血淚經驗。4.3 骨骼動畫、關鍵幀動畫、關節(jié)動畫的對比3D 動畫方式主要有關節(jié)動畫、單一網格模型動畫關鍵幀動畫、骨骼動畫。關節(jié)動畫把角色分成若干獨立部分一個部分對應一個網格模型部分的動畫連接成整體動畫角色比較靈活但接縫處容易穿幫。單一網格模型動畫由一個完整網格構成在關鍵幀里記錄頂點位置及改變量然后插值運算實現(xiàn)動畫角色動畫較真實但頂點多了之后內存和計算開銷大。骨骼動畫集成了以上兩個方式的優(yōu)點骨骼按角色特點組成層次結構由關節(jié)相連皮膚作為單一網格蒙在骨骼之外每個頂點受骨骼影響從而實現(xiàn)完美動畫。面試官問“骨骼旋轉矩陣”怎么算你要答骨骼的旋轉矩陣由關節(jié)的局部變換逐級相乘得到最終影響蒙皮頂點的位置。蒙皮計算里每個頂點通常受 4 根骨骼影響權重之和為 1。5. 易錯點與失分點這些題一錯就直接掛5.1 渲染管線順序寫反錯在哪把圖元組裝寫在頂點處理前面或者把像素處理寫在光柵化前面。為什么錯管線順序是硬件固定的頂點處理完才能組裝圖元光柵化之后才有像素片段。怎么答對記住“輸入組裝 - 頂點 - 圖元 - 像素”這個主干再往里填空間變換、裁剪、視口變換。5.2 四元數(shù)共軛和逆搞混錯在哪把共軛寫成虛部不變、實部取反。為什么錯四元數(shù)共軛的定義是實部不變、虛部取反單位四元數(shù)的逆等于共軛但非單位四元數(shù)的逆還要除以模長平方。怎么答對先判斷是不是單位四元數(shù)再決定用共軛還是逆。5.3 ZBuffer 關閉時機答錯錯在哪說“任何物體都必須打開 ZBuffer”。為什么錯半透明物體渲染時通常要關閉深度寫入2D 渲染也可以關閉。怎么答對分場景說不透明物體開深度測試和寫入半透明物體開深度測試但關深度寫入并且從遠到近排序。5.4 diffuse 公式忘記取 max(0, dot)錯在哪直接寫 dot(normal, lightDir) 不取 0。為什么錯點乘為負時會產生負光照顏色變黑或者出現(xiàn)異常。怎么答對寫公式時帶上 max(0, ...)并說明這是為了剔除背面光照。5.5 相機 near/far 設置不合理錯在哪near 設得特別小far 設得特別大。為什么錯深度緩沖精度會急劇下降遠處物體出現(xiàn) z-fighting。怎么答對near 盡量遠far 盡量近保證場景完整的前提下壓縮深度范圍。6. 答題技巧從分析題到性能排查的押題思路分析題里有一道很典型有一段渲染fps 很低找出原因說一下思路。這種題沒有標準答案但面試官想聽的是你的排查路徑。我自己的習慣是強制走一遍“從 CPU 到 GPU、從提交到像素”的鏈路。先看 draw call 數(shù)量如果幾千個 draw call大概率是 CPU 提交瓶頸再看三角形數(shù)量如果單幀幾百萬三角形可能是頂點處理或者光柵化壓力再看紋理帶寬如果用了大量高分辨率紋理且沒有 MipMap采樣帶寬會爆再看 shader 復雜度逐像素光照、陰影計算、后處理疊加都會拉高像素階段耗時最后看混合和 overdraw半透明物體大面積重疊會導致像素反復著色。押題方向上渲染管線順序、MVP 矩陣、ZBuffer、Alpha 混合公式、diffuse 公式、LOD 和 MipMap、骨骼動畫原理、四元數(shù)共軛和逆、矩陣轉置和旋轉矩陣這幾塊幾乎每年都會換個問法出現(xiàn)。筆試里還可能讓你寫矩陣相乘的代碼、寫返回值為 float 輸入參數(shù)為 int 的函數(shù)指針、寫 class A 讓 set 合法的定義。函數(shù)指針的寫法是float (*func)(int)set 合法的關鍵是提供 operator 或者自定義比較器。// 返回值為float輸入參數(shù)為int的函數(shù)指針 float (*funcPtr)(int); // 讓setA合法需要定義operator class A { public: int id; bool operator(const A other) const { return id other.id; } };參數(shù)說明函數(shù)指針聲明里(*funcPtr)的括號不能省否則變成返回指針的函數(shù)。set 要求元素可比較operator 必須聲明為 const 成員函數(shù)否則 set 內部排序時會編譯失敗。線程時間片到了進入什么階段、this 指針放在哪個寄存器、傳遞常量寄存器的數(shù)據結構這些屬于操作系統(tǒng)和編譯原理的交叉題。線程時間片用完進入就緒狀態(tài)等待下一次調度this 指針通常放在 ECX 寄存器常量寄存器傳遞的數(shù)據結構一般是常量緩沖區(qū)。從那以后我每次遇到“fps 很低”的分析題都強制走一遍 draw call、三角形、紋理、shader、overdraw 這五步先定位瓶頸在 CPU 還是 GPU再往下拆。希望幫到你。本文還有配套的精品資源點擊獲取