計算機圖形學三:光柵化渲染與深度緩衝
本章內容:(未完待續)
圖像、像素與幾何
採樣 Sampling
深度緩衝 Z-buffering
第三章 光柵化渲染與深度緩衝 Raster Images&Z-buffer
上一章節內容:
三維變換 3D transformations
觀測變換 viewing tranformation
具體代碼實現
上一章難度較大,數學推導過程較為複雜,理論理解也有一定難度。這一章難度較低。
本章學習內容:
光柵概述
深度緩衝 Z-buffer
簡述:
光柵化渲染(Rasterization)是一種在電腦圖形學中常用的渲染技術,它將3D模型的幾何形狀和材質投影到2D畫面上,並根據每個像素的位置、光照和材質等信息進行計算,最終生成2D畫面。這種渲染技術的運作原理是將3D模型中的三角形面片按照其在視角中的位置關係進行排序,然後利用像素著色器對每個像素進行顏色填充。由於光柵化渲染運算速度快、容易實現,因此在遊戲和實時圖形應用中得到廣泛應用。
光柵化渲染過程主要分為三個步驟:幾何著色、光照計算和像素著色。在幾何著色階段,將3D模型中的每個三角形面片變換到視角空間中,並進行視錐體剪裁,去除不在視錐體內的面片。然後,計算每個面片的法向量和材質,以便在光照計算階段進行使用。在光照計算階段,對每個面片進行簡單的光照計算,以決定每個面片上各點的亮度和顏色。在像素著色階段,將每個面片的像素投影到屏幕上,然後對每個像素進行插值和紋理映射,計算其最終顏色。最後,將所有像素的顏色存儲到顯示器的顯存中,顯示到屏幕上,完成渲染過程。
儘管光柵化渲染速度快,但其精度和真實感相對較低,且對於大型場景和複雜物體的渲染能力也較有限。因此,在許多應用中,例如電影、動畫等專業領域,更多地採用基於物理的渲染技術,例如光線追蹤(Ray Tracing)等。
3.1 圖像、像素與幾何 Images, Pixels, and Geometry
這一章的內容只需了解,不用太深入。
3.1.1 屏幕像素表示 Coordinates of Pixel
屏幕的每一個像素座標都是整數
一般來說,如果屏幕有 $i\cdot j$ 個像素,則:
左下角是 $(0,0)$ ,右上角是 $(i-1,j-1)$
每一個像素的中心是: $(x,y)$
某些圖形API中, $y$ 軸可能是向下的。
3.1.2 像素值 Pixel Value
目前來說,一個邏輯像素只代表一種顏色
8位图像中,每一個像素可能的數值 $0, 1/255, 2/255,. . . , 254/255, 1$
至於高動態範圍(HDR)的像素,將在最後兩個章節詳細討論
3.1.3 三角形 Fundamental Shape Primitives
為什麼三角形被認為是一種基本的形狀基元?
三角形是二維平面中最簡單的多邊形
容易判斷某點是否在三角形內:只需做三次叉積
3.2 用像素近似三角形 Pixel Values Approximate a Triangle
其中一個簡單的方法就是:採樣。
3.2.1 採樣
在某個點對函數求值就是採樣(Sampling)。
偽代碼如下:
對下面整個平面進行遍歷掃描(也就是每一個正方形),規定:
若某個正方形的中心在三角形內部,則這個正方形像素=1;反之
偽代碼實現如下:
具體怎麼判斷某個點是否在三角形內呢?也就是這個inside函數怎麼實現?
inside(tri, x, y)實現原理:
三次叉積。三次作叉積就可以判斷$Q$點是否在三角形 $P_0 P_1 P_2$ 內
我們一般隨意處理點在線上的問題。
3.2.2 優化採樣
3.2.1 的採樣方法是對整個平面每一個像素做inside()。
我們真的需要對每一個像素採樣嗎??
答案:不需要。我們可以使用最簡單的方法邊框盒子法(Bounding Box)。
簡單的說,就是用一個盒子框住三角形,沒被盒子覆蓋的像素,肯定也不會被三角形覆蓋,所以一定不用渲染。如下圖所示。
3.3 深度緩衝 Z-buffer
簡而言之,為了保證3D場景中物體的深度排序正確,我們可以使用Z-buffer算法。
當渲染一個場景時,每個物體都有一個與鏡頭距離的深度值。在沒有深度排序的情況下,有些物體可能會被渲染在其他物體的前面,導致視覺上的錯誤。為了避免這種情況,z-buffer算法通過維護一個深度緩衝區(也就是z-buffer)來跟踪每個像素的深度值。當渲染一個像素時,系統會檢查其深度值是否比已經渲染的像素的深度值更靠前。如果是,則這個像素將被渲染;否則,它將被丟棄,因為它被後面的物體遮擋住了。
注意,在這一步,我們把所有深度值都看成正數!!
也就是說,z小 -> 靠近攝像頭
算法步驟:
將 $m*n$ 深度緩衝區全部設置為無窮大 $∞$
(c++中的無窮大是:
std::numeric_limits<float>::infinity()
)遍歷所有三角形
遍歷所有在三角形內的像素
如果這個像素的深度小於緩衝區的,則取代他。
否則,不動。
偽代碼:
圖示:
算法時間複雜度:$O(n)$
3.4 coding
Reference
[1] Fundamentals of Computer Graphics 4th
[2] GAMES101 Lingqi Yan