前往
大廳
主題

GAMES101-現代電腦圖形學入門-作業二

楓之焰 | 2024-01-03 10:14:09 | 巴幣 0 | 人氣 91

目標

rasterize_triangle(): 執行三角形柵格化演算法
• static bool insideTriangle(): 測試點是否在三角形內。 你可以修改此函
數的定義,這意味著,你可以按照自己的方式更新返回類型或函數參數。
• 加分題: 用 super-sampling 處理 Anti-aliasing 。

實作

• static bool insideTriangle(): 測試點是否在三角形內

透過dot()cross()得知任一點是否在三角形內
因為三角形已經在螢幕座標內,所以只要簡單判斷z是否相同即可

rasterize_triangle(): 執行三角形柵格化演算法


接下來要寫光柵化的處理,首先要取得三角形的BoundingBox。
在BoundingBox內遍歷所有像素,裡面用剛剛寫的insideTriangle()判斷點是否在三角形內部
找到哪些點在三角型內部後,要計算像素的深度,這部分老師已經先幫我們寫好了
我只要比較深度緩衝區內對應的像素深度,若大於目前像素深度則代表目前像素距離比較近必須渲染出來
編譯執行後三角形就畫出來了

• 加分題: 用 super-sampling 處理 Anti-aliasing

上圖可以看到藍色三角形有明顯的鋸齒,接下來就嘗試做抗鋸齒,用的方法是超級採樣抗鋸齒
為什麼會產生鋸齒呢?因為解析度不夠高,所以導致沒辦法完整呈現整個圖形
如上圖,這個三角形非常小,像素的密度遠大於三角形,左下角很明顯應該顯示但因為像素點沒有覆蓋而被捨棄
那麼該如何解決這個問題?
超級採樣的方法簡單暴力,既然像素不夠,那就增加更多像素吧~也就是增加採樣頻率
2x2超級採樣將每個像素點又分成了四個子像素,能發現三角形畫得比較像了
可是實際上螢幕的像素是固定的啊,該怎麼辦呢?
只要對子像素在像素中佔的比例做插值就好
以上圖為例:假設有三個子像素在三角形內,那我們就把這個三角形的顏色乘以3/4
假設有一個子像素在三角形內,那我們就把這個三角形的顏色乘以1/4
原本空白的像素就有了一點點顏色,雖然還是長得不像三角形,但像素就這麼多也沒辦法
此方法缺點也很明顯,將一個像素的工作量分四次做,效能直接變四倍,所以還有別的方式來抗鋸齒如(FXAA、TAA)
程式碼這邊我先從最左下的子像素開始遍歷,若在三角形內則依比例增加覆蓋率,最後回傳覆蓋率
疑?鋸齒雖然有改善一點,但藍色跟綠色的交界卻多出奇怪的黑邊,這是為什麼?
這是因為在像素覆蓋率很低時,顏色值接近黑色導致的
這邊簡單修改一下,當覆蓋顏色時取frame buffer的顏色做插值
可以發現鋸齒明顯改善了,但運行速度也明顯慢很多...

最後試一下3x3 SSAA是什麼樣子
在3x3 SSAA下已經幾乎看不見鋸齒了

結尾

因為對C++還不是很熟,指針跟浮點轉換不像C#那樣方便碰到好多坑
還好現在有ChatGPT可以幫忙Debug...以前做遊戲的人直接寫C++真他媽硬

創作回應

更多創作