3.10[A]cv

核心模塊

  • rasterizer:光柵化器,負責三角形遍歷和像素繪制
  • Shader:包含頂點著色器和多種片元著色器
  • Texture:紋理處理模塊

頂點著色器的計算量一般遠小于片元著色器。因為組成三角形的頂點相對有限,而片元需要基于頂點組成的三角形進行插值。

比如,一個100 * 100大小的矩形平面,有四個頂點,計算四次,但是片元著色器需要計算10000次。

也比較簡單,模型自帶了法線。注意,法線取值范圍[-1, 1],需要映射到[0,1],再轉換到[0, 255]

網格數據遍歷與三角形構建

  • 外層循環for(auto mesh:Loader.LoadedMeshes)遍歷模型的所有網格(Mesh),每個網格代表一個獨立幾何體(如物體的一個部件)

內層循環for(int i=0; ... i+=3)以步長3遍歷頂點,將每三個頂點組成一個三角形面片(每個三角形由3個頂點構成)

該代碼段是3D模型加載的核心邏輯,它將.obj模型文件中存儲的頂點、法線、紋理坐標等原始數據轉換為渲染管線可處理的三角形對象集合。這些數據為后續的MVP矩陣變換、光照計算(依賴法線)、紋理貼圖(依賴紋理坐標)提供了輸入基礎

**newtri**

  • 這是經過MVP矩陣變換?(Model-View-Projection)和視口變換后的三角形對象,其頂點坐標已處于屏幕空間
  • 包含以下處理后的屬性:
    • ?頂點坐標:通過MVP矩陣變換和齊次除法后,再經過視口變換映射到屏幕坐標系

法線向量:通過逆變換矩陣將模型空間法線轉換到視圖空間,用于后續光照計算

*viewspace_pos**

  • 表示三角形頂點在視圖空間(觀察空間)??中的坐標,即經過?view * model?變換后的位置。
  • 用于光照計算中的視線方向計算(如Phong著色中的鏡面反射分量)

光照模擬機制
通過修改模型表面的法線方向,改變光線反射角度,使平面在渲染時呈現凹凸、劃痕等細節效果。例如:

  • 當光線照射到法線貼圖標記的“凹陷”區域時,法線方向改變導致陰影和高光位置變化,從而欺騙人眼感知

雙線性插值作用于片段著色器階段的紋理采樣過程。當紋理坐標(u,v)為浮點數時(非整數像素中心坐標),需通過插值計算顏色值

光照函數

每個函數的實現步驟大致如下:

  1. phong_fragment_shader:遍歷光源,計算環境、漫反射、高光,累加結果。
  2. texture_fragment_shader:采樣紋理顏色作為kd,其余同phong。
  3. bump_fragment_shader:計算TBN矩陣,擾動法線,更新法線后計算光照。
  4. displacement_fragment_shader:調整頂點位置,更新法線,再計算光照。

Blinn-Phong模型由環境光、漫反射和高光組成,其中高光部分使用半程向量(halfway vector)來計算。環境光是簡單的常數乘以光強,漫反射是法線方向與光線方向的點積,而高光則是半程向量與法線的點積的冪次方。我需要遍歷所有光源,計算每個光源的這三個分量,并累加到結果顏色中。要注意歸一化各個向量,例如光線方向、視線方向和半程向量。

texture_fragment_shader,需要在Blinn-Phong的基礎上將紋理顏色作為漫反射系數kd。

實現

void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) 
{// 獲取三角形頂點坐標(屏幕空間)auto v = t.toVector4();// 計算包圍盒邊界(網頁1、網頁4)float min_x = std::min(v[0].x(), std::min(v[1].x(), v[2].x()));float max_x = std::max(v[0].x(), std::max(v[1].x(), v[2].x()));float min_y = std::min(v[0].y(), std::min(v[1].y(), v[2].y()));float max_y = std::max(v[0].y(), std::max(v[1].y(), v[2].y()));// 轉換為整數像素范圍(網頁4)int x_min = std::floor(min_x);int x_max = std::ceil(max_x);int y_min = std::floor(min_y);int y_max = std::ceil(max_y);// 遍歷包圍盒內所有像素(網頁4)for (int x = x_min; x <= x_max; ++x) {for (int y = y_min; y <= y_max; ++y) {// 檢查像素中心是否在三角形內(網頁3)if (insideTriangle(x + 0.5, y + 0.5, t.v)) {// 計算重心坐標(網頁1)auto [alpha, beta, gamma] = computeBarycentric2D(x + 0.5, y + 0.5, t.v);// 深度插值計算(網頁1、網頁4)float Z = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());float zp = alpha * v[0].z()/v[0].w() + beta * v[1].z()/v[1].w() + gamma * v[2].z()/v[2].w();zp *= Z;// 深度測試(網頁4)if (zp < depth_buf[get_index(x, y)]) {// 更新深度緩沖區depth_buf[get_index(x, y)] = zp;// 屬性插值(網頁1、網頁2)auto interpolated_color = interpolate(alpha, beta, gamma, t.color[0], t.color[1], t.color[2], 1.0f);auto interpolated_normal = interpolate(alpha, beta, gamma,t.normal[0], t.normal[1], t.normal[2], 1.0f).normalized();auto interpolated_texcoords = interpolate(alpha, beta, gamma,t.tex_coords[0], t.tex_coords[1], t.tex_coords[2], 1.0f);auto interpolated_shadingcoords = interpolate(alpha, beta, gamma,view_pos[0], view_pos[1], view_pos[2], 1.0f);// 構造著色器輸入(網頁1)fragment_shader_payload payload(interpolated_color,interpolated_normal,interpolated_texcoords,texture ? &*texture : nullptr);payload.view_pos = interpolated_shadingcoords;// 調用片段著色器(網頁2)Eigen::Vector3f pixel_color = fragment_shader(payload);// 寫入像素顏色(網頁4)set_pixel(Eigen::Vector2i(x, y), pixel_color);}}}}
}

圖形渲染管線

?

處理邏輯

在shader當中,是在shader.hpp中定義了片著色器的payload,然后在渲染的時候,是把插值后的屬性傳遞給Payload,再把payload傳遞給一開始定義的r.set_fragment_shader(active_shader);

    for(auto mesh:Loader.LoadedMeshes){for(int i=0;i<mesh.Vertices.size();i+=3){Triangle* t = new Triangle();for(int j=0;j<3;j++){t->setVertex(j,Vector4f(mesh.Vertices[i+j].Position.X,mesh.Vertices[i+j].Position.Y,mesh.Vertices[i+j].Position.Z,1.0));t->setNormal(j,Vector3f(mesh.Vertices[i+j].Normal.X,mesh.Vertices[i+j].Normal.Y,mesh.Vertices[i+j].Normal.Z));t->setTexCoord(j,Vector2f(mesh.Vertices[i+j].TextureCoordinate.X, mesh.Vertices[i+j].TextureCoordinate.Y));}TriangleList.push_back(t);}}

是在一開始讀取模型的時候,就按照網面設置好了三角形,并把三角形裝進TriangleList中了,然后在最后繪制的時候,就是去繪制這個三角形

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/71921.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/71921.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/71921.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mac使用Homebrew安裝miniconda(mac搭建python環境),并在IDEA中集成miniconda環境

一、安裝Homebrew mac安裝brew 二、使用Homebrew安裝miniconda brew search condabrew install miniconda安裝完成后的截圖&#xff1a; # 查看是否安裝成功 brew list環境變量&#xff08;無需手動配置&#xff09; 先執行命令看能不能正常返回&#xff0c;如果不能正常…

多視圖幾何--相機標定--從0-1理解張正友標定法

1基本原理 1.1 單應性矩陣&#xff08;Homography&#xff09;的建立 相機模型&#xff1a;世界坐標系下棋盤格平面&#xff08;Z0&#xff09;到圖像平面的投影關系為&#xff1a; s [ u v 1 ] K [ r 1 r 2 t ] [ X Y 1 ] s \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} K…

WWDG窗口看門狗原理

WWDG&#xff08;窗口看門狗&#xff09;在窗口期喂狗 作用&#xff1a; 原理&#xff1a; 框圖 WWDG寄存器&#xff1a; WWDG_CR控制寄存器 WWDG_CFR配置寄存器 狀態寄存器WWDG_SR 超時時間計算公式 最小最大超時值 HAL配置函數&#xff1a; 1. IWDG 和 WWDG 的區別 IWDG&…

無公網IP也能遠程控制Windows:Linux rdesktop內網穿透實戰

文章目錄 前言1. Windows 開啟遠程桌面2. Linux安裝rdesktop工具3. Win安裝Cpolar工具4. 配置遠程桌面地址5. 遠程桌面連接測試6. 設置固定遠程地址7. 固定地址連接測試 前言 如今遠程辦公已經從一種選擇變成了許多企業和個人的必修課&#xff0c;而如何在Linux系統上高效地訪…

Pygame實現射擊鴨子游戲3-2

2 鴨子類Target的創建 2.1 __init__()函數 Target類的__init__()函數代碼如圖5所示。 圖5 __init__()函數代碼 其中&#xff0c;第18行將Target類聲明為pygame.sprite.Sprite類的子類&#xff1b;第19行代碼中&#xff0c;__init__()函數的img_path參數表示鴨子圖片的文件名…

利用Java爬蟲獲取衣聯網商品詳情:實戰指南

在電商領域&#xff0c;獲取商品詳情是數據分析和市場研究的重要環節。衣聯網作為知名的電商平臺&#xff0c;提供了豐富的服裝商品資源。本文將詳細介紹如何利用Java編寫爬蟲程序&#xff0c;通過商品ID獲取衣聯網商品詳情。 一、準備工作 &#xff08;一&#xff09;環境搭…

五、OpenGL中Shader與C++數據傳輸

文章目錄 一、概述二、Shader 代碼文件的基本格式三、Shader的向量語法介紹四、Shader之間的數據傳輸五、Shader與C的數據傳輸uniform六、完整示例 一、概述 在 OpenGL 中&#xff0c;Shader&#xff08;著色器&#xff09;使用 GLSL&#xff08;OpenGL Shading Language&…

【3DMAX插件】3DMAX建筑大師插件MasterBuilder使用方法

3DMAX建筑大師插件是一款專為3DMAX設計的程序化&#xff08;參數化&#xff09;建筑建模工具&#xff0c;其最大特點是能夠一鍵生成建筑模型&#xff0c;極大地提升了工作效率。該插件配備了多種結構控制選項&#xff0c;涵蓋陽臺、門窗、欄桿、樓頂水塔等附屬建筑元素&#xf…

隱私保護在 Facebook 用戶身份驗證中的應用

在這個數字化的時代&#xff0c;個人隱私保護成為了公眾關注的焦點。社交媒體巨頭 Facebook 作為全球最大的社交平臺之一&#xff0c;擁有數十億用戶&#xff0c;其在用戶身份驗證過程中對隱私保護的重視程度直接影響著用戶的安全感和信任度。本文將探討 Facebook 在用戶身份驗…

Swift Package Manager (SPM) 創建并集成本地庫

在macOS 項目中&#xff0c;使用 Swift Package Manager (SPM) 創建并集成本地庫的完整步驟。 創建一個macos應用程序&#xff0c;選擇 swift、oc、swiftui都可以。 創建好應用之后&#xff0c;開始創建SPM本地庫。 打開終端app&#xff0c;進入項目根目錄&#xff0c;逐次輸…

滲透測試之利用sql拿shell(附完整流程+防御方案)【下】

導讀: 時刻保持謙遜,始終保持學習,探尋事物的本質,不要把事情復雜化 話不多說,書接上回 三、利用日志getshell 利用條件: 擁有網站的寫入權限知道網站的絕對路徑數據庫日志開啟 實際操作: (1)查看數據庫日志是否開啟以及路徑 show variables like %general%; (2…

LeetCode 熱題 100_每日溫度(72_739_中等_C++)(棧)(暴力破解;棧(從左到右);棧(從右到左))

LeetCode 熱題 100_每日溫度&#xff08;72_739&#xff09; 題目描述&#xff1a;輸入輸出樣例&#xff1a;題解&#xff1a;解題思路&#xff1a;思路一&#xff08;暴力破解法(雙重循環)&#xff09;&#xff1a;思路二&#xff08;棧&#xff1a;從左到右&#xff09;&…

【HarmonyOS Next之旅】DevEco Studio使用指南(二)

目錄 1 -> 工程模板介紹 2 -> 創建一個新的工程 2.1 -> 創建和配置新工程 2.1.1 -> 創建HarmonyOS工程 2.2.2 -> 創建OpenHarmony工程 1 -> 工程模板介紹 DevEco Studio支持多種品類的應用/元服務開發&#xff0c;預置豐富的工程模板&#xff0c;可以根…

unity3d 背景是桌面3d數字人,前面是web的表單

是可以實現的&#xff0c;但涉及多個技術棧的結合&#xff0c;包括 Unity3D、Web 技術&#xff08;HTML、JavaScript&#xff09;、以及可能的 WebGL 或 WebRTC 技術。大致有以下幾種實現方案&#xff1a; 方案 1&#xff1a;Unity 作為獨立應用&#xff08;桌面端&#xff0…

貓耳大型活動提效——組件低代碼化

1. 引言 貓耳前端在開發活動的過程中&#xff0c;經歷過傳統的 pro code 階段&#xff0c;即活動頁面完全由前端開發編碼實現&#xff0c;直到 2020 年接入公司內部的低代碼活動平臺&#xff0c;滿足了大部分日常活動的需求&#xff0c;運營可自主配置活動并上線&#xff0c;釋…

深度學習系列79:Text2sql調研

參考 https://github.com/topics/text-to-sql 這里是一些資源&#xff1a;https://github.com/eosphoros-ai/Awesome-Text2SQL/blob/main/README.zh.md 這里是綜述文章&#xff1a;https://zhuanlan.zhihu.com/p/647249972 1. 數據集 Spider: 一個跨域的復雜text2sql數據集&a…

Linux 系統負載過高的排查思路

技術探討&#xff1a;Linux系統負載過高的排查思路 在Linux服務器運行過程中&#xff0c;如果系統負載過高&#xff0c;可能會導致性能下降和服務不穩定。以下是針對Linux系統負載過高問題的排查思路和解決方法&#xff1a; 1. 查看系統負載&#xff1a; 使用uptime或top命令查…

【互聯網性能指標】QPS/TPS/PV/UV/IP/GMV/DAU/MAU/RPS

&#x1f4d5;我是廖志偉&#xff0c;一名Java開發工程師、《Java項目實戰——深入理解大型互聯網企業通用技術》&#xff08;基礎篇&#xff09;、&#xff08;進階篇&#xff09;、&#xff08;架構篇&#xff09;清華大學出版社簽約作家、Java領域優質創作者、CSDN博客專家、…

linux---天氣爬蟲

代碼概述 這段代碼實現了一個天氣查詢系統&#xff0c;支持實時天氣、未來天氣和歷史天氣查詢。用戶可以通過終端菜單選擇查詢類型&#xff0c;并輸入城市名稱來獲取相應的天氣信息。程序通過 TCP 連接發送 HTTP 請求&#xff0c;并解析返回的 JSON 數據來展示天氣信息。 #in…

Java高頻面試之集合-08

hello啊&#xff0c;各位觀眾姥爺們&#xff01;&#xff01;&#xff01;本baby今天來報道了&#xff01;哈哈哈哈哈嗝&#x1f436; 面試官&#xff1a;詳細說說CopyOnWriteArrayList CopyOnWriteArrayList 詳解 CopyOnWriteArrayList 是 Java 并發包&#xff08;java.util…