日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GAMES101-现代计算机图形学学习笔记(作业02)

發(fā)布時間:2023/12/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GAMES101-现代计算机图形学学习笔记(作业02) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

GAMES101-現(xiàn)代計算機(jī)圖形學(xué)學(xué)習(xí)筆記(作業(yè)02)

Assignment 02

    • GAMES101-現(xiàn)代計算機(jī)圖形學(xué)學(xué)習(xí)筆記(作業(yè)02)
  • 作業(yè)
    • 作業(yè)描述
    • 需要補(bǔ)充的函數(shù)
    • 思路
    • 結(jié)果

原課程視頻鏈接以及官網(wǎng)
b站視頻鏈接: link.
課程官網(wǎng)鏈接: link.

作業(yè)

作業(yè)描述

在上次作業(yè)中,雖然我們在屏幕上畫出一個線框三角形,但這看起來并不是 那么的有趣。所以這一次我們繼續(xù)推進(jìn)一步——在屏幕上畫出一個實(shí)心三角形, 換言之,柵格化一個三角形。上一次作業(yè)中,在視口變化之后,我們調(diào)用了函數(shù) rasterize_wireframe(const Triangle& t)。但這一次,你需要自己填寫并調(diào)用函數(shù) rasterize_triangle(const Triangle& t)。

提高篇:用 super-sampling 處理 Anti-aliasing : 你可能會注意到,當(dāng)我們放大圖像時,圖像邊緣會有鋸齒感。我們可以用 super-sampling 來解決這個問題,即對每個像素進(jìn)行 2 * 2 采樣,并比較前后的結(jié)果 (這里 并不需要考慮像素與像素間的樣本復(fù)用)。需要注意的點(diǎn)有,對于像素內(nèi)的每一個樣本都需要維護(hù)它自己的深度值,即每一個像素都需要維護(hù)一個 sample list。最后,如果你實(shí)現(xiàn)正確的話,你得到的三角形不應(yīng)該有不正常的黑邊。

需要補(bǔ)充的函數(shù)

rasterize_triangle(): 執(zhí)行三角形柵格化算法
static bool insideTriangle(): 測試點(diǎn)是否在三角形內(nèi)。你可以修改此函 數(shù)的定義,這意味著,你可以按照自己的方式更新返回類型或函數(shù)參數(shù)。

思路

①三角形柵格算法

作業(yè)要求已經(jīng)給出了*rasterize_triangle()*函數(shù)的工作流程:

  • 創(chuàng)建三角形的 2 維 bounding box。
  • 遍歷此 bounding box 內(nèi)的所有像素(使用其整數(shù)索引)。然后,使用像素中心的屏幕空間坐標(biāo)來檢查中心點(diǎn)是否在三角形內(nèi)。
  • 如果在內(nèi)部,則將其位置處的插值深度值 (interpolated depth value) 與深度 緩沖區(qū) (depth buffer) 中的相應(yīng)值進(jìn)行比較。
  • 如果當(dāng)前點(diǎn)更靠近相機(jī),請設(shè)置像素顏色并更新深度緩沖區(qū) (depth buffer)。
  • 老師這里要求實(shí)現(xiàn)的是Barycentric Algorithm(三角形柵格化),下面幾個點(diǎn)可能需要注意一下:
    ①尋找三角形的bounding box:根據(jù)三角形的三個坐標(biāo),找出最大x,最小x,最大y,最小y坐標(biāo)即可,注意最小x,y坐標(biāo)需要取比原數(shù)小,最大x,y坐標(biāo)需要取比原數(shù)大
    ②點(diǎn)是否在三角形內(nèi):只需要連接點(diǎn)和三角形個點(diǎn),形成一系列向量,然后判斷它們的叉乘結(jié)果的z值是否統(tǒng)一即可
    ③MSAA 4X 深度:把一個點(diǎn)看成一個格子,判斷里面4個小點(diǎn)是否落在三角形內(nèi),然后找到其中插值的最小z值,和幀緩沖中的z值進(jìn)行比較替換即可。
    ③MSAA 4X 顏色
    判斷有4個小點(diǎn)中有幾個小點(diǎn)落入三角形,然后按比例對顏色進(jìn)行采樣即可。

    光柵化函數(shù):

    //Screen space rasterization void rst::rasterizer::rasterize_triangle(const Triangle& t) {auto v = t.toVector4();// bounding boxfloat min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));float max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));float min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));float max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));min_x = (int)std::floor(min_x);max_x = (int)std::ceil(max_x);min_y = (int)std::floor(min_y);max_y = (int)std::ceil(max_y);bool MSAA = false;//MSAA 4Xif (MSAA) {// 格子里的細(xì)分四個小點(diǎn)坐標(biāo)std::vector<Eigen::Vector2f> pos{{0.25,0.25},{0.75,0.25},{0.25,0.75},{0.75,0.75},};for (int x = min_x; x <= max_x; x++) {for (int y = min_y; y <= max_y; y++) {// 記錄最小深度float minDepth = FLT_MAX;// 四個小點(diǎn)中落入三角形中的點(diǎn)的個數(shù)int count = 0;// 對四個小點(diǎn)坐標(biāo)進(jìn)行判斷 for (int i = 0; i < 4; i++) {// 小點(diǎn)是否在三角形內(nèi)if (insideTriangle((float)x + pos[i][0], (float)y + pos[i][1], t.v)) {// 如果在,對深度z進(jìn)行插值auto tup = computeBarycentric2D((float)x + pos[i][0], (float)y + pos[i][1], t.v);float alpha;float beta;float gamma;std::tie(alpha, beta, gamma) = tup;float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();z_interpolated *= w_reciprocal;minDepth = std::min(minDepth, z_interpolated);count++;}}if (count != 0) {if (depth_buf[get_index(x, y)] > minDepth) {Vector3f color = t.getColor() * count / 4.0;Vector3f point(3);point << (float)x, (float)y, minDepth;// 替換深度depth_buf[get_index(x, y)] = minDepth;// 修改顏色set_pixel(point, color);}}}}}else {for (int x = min_x; x <= max_x; x++) {for (int y = min_y; y <= max_y; y++) {if (insideTriangle((float)x + 0.5, (float)y + 0.5, t.v)) {auto tup = computeBarycentric2D((float)x + 0.5, (float)y + 0.5, t.v);float alpha;float beta;float gamma;std::tie(alpha, beta, gamma) = tup;float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();z_interpolated *= w_reciprocal;if (depth_buf[get_index(x, y)] > z_interpolated) {Vector3f color = t.getColor();Vector3f point(3);point << (float)x, (float)y, z_interpolated;depth_buf[get_index(x, y)] = z_interpolated;set_pixel(point, color);}}}}} }

    判斷點(diǎn)是否位于三角形內(nèi)函數(shù)

    static bool insideTriangle(double x, double y, const Vector3f* _v) { // TODO : Implement this function to check if the point (x, y) is inside the triangle represented by _v[0], _v[1], _v[2]Eigen::Vector2f p;p << x, y;Eigen::Vector2f AB = _v[1].head(2) - _v[0].head(2);Eigen::Vector2f BC = _v[2].head(2) - _v[1].head(2);Eigen::Vector2f CA = _v[0].head(2) - _v[2].head(2);Eigen::Vector2f AP = p - _v[0].head(2);Eigen::Vector2f BP = p - _v[1].head(2);Eigen::Vector2f CP = p - _v[2].head(2);// 判斷每個z坐標(biāo)是否統(tǒng)一return AB[0] * AP[1] - AB[1] * AP[0] > 0 && BC[0] * BP[1] - BC[1] * BP[0] > 0&& CA[0] * CP[1] - CA[1] * CP[0] > 0; }

    結(jié)果

    以下是結(jié)果:

    以下依次是沒有做MSAA 4X的結(jié)果和做了MSAA 4X的結(jié)果:

    這個光柵化算法其實(shí)是比較慢的,一個是自己實(shí)現(xiàn)的問題,第二個是從bounding box來看,會掃描很多多余的像素。這里貼幾個鏈接,里面提到了其他的光柵化算法,以后有機(jī)會可以改成其他光柵化的算法來實(shí)現(xiàn):
    鏈接: http://www.sunshine2k.de/coding/java/TriangleRasterization/TriangleRasterization.html#algo1.
    https://www.thecrazyprogrammer.com/2017/01/bresenhams-line-drawing-algorithm-c-c.html.
    https://blog.csdn.net/cppyin/article/details/6232453.

    總結(jié)

    以上是生活随笔為你收集整理的GAMES101-现代计算机图形学学习笔记(作业02)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。