Horse3D游戲引擎研發筆記(六):在QtOpenGL環境下,仿Unity的材質管理Shader繪制四邊形

在上一篇筆記中,我們已經實現了基于QtOpenGL的BufferGeometry管理VAO和EBO繪制四邊形的功能。這一次,我們將深入探討材質管理系統的實現,包括Shader的加載與編譯、材質的創建與使用,以及如何通過材質系統繪制帶有自定義Shader效果的四邊形。


一、Horse3D引擎的材質管理系統

在現代三維引擎中,材質管理系統是渲染系統的核心模塊之一。它負責管理模型表面的視覺效果,包括顏色、紋理、光照響應等。在Horse3D引擎中,我們參考了Unity和Three.js的材質系統設計,實現了以下功能:

  1. 材質的定義與加載:通過JSON格式的材質文件定義材質屬性,包括頂點著色器、片段著色器、紋理資源等。
  2. Shader的編譯與管理:支持 Shader 的動態加載與編譯,通過Builder模式管理Shader程序的創建與緩存。
  3. 材質的實例化與使用:通過Material類管理材質的OpenGL狀態,并提供統一的接口綁定材質進行渲染。

二、關鍵技術與實現細節

1. 材質文件的定義

在Horse3D中,材質通過JSON文件進行定義。以下是一個典型的材質文件示例:

{"Attributes": [{"Name": "a_position","Dimension": 3},{"Name": "a_texcoord","Dimension": 2}],"Uniforms": [{"Name": "u_fragColor","Type": "Color","Value": "#FFFF00"},{"Name": "u_texture_fei","Type": "Texture2D","Value": "Materials/Test/fei.jpg"},{"Name": "u_texture_tang","Type": "Texture2D","Value": "Materials/Test/tang.jpeg"}],"Shaders": [{"ShaderEnum": "Vertex","SourceFile": "Materials/Test/Test.vert"},{"ShaderEnum": "Fragment","SourceFile": "Materials/Test/Test.frag"}]
}

該文件定義了材質的頂點屬性、Uniform變量以及Shader程序。通過這種方式,我們可以靈活地配置材質的視覺效果。這一部分的設計靈感來源于Unity與OpenGL中的材質系統詳解。

2. Shader程序的加載與編譯

在Horse3D中,Shader程序的加載與編譯通過MaterialBuilder類實現。該類采用Builder模式,負責解析材質文件、加載Shader代碼、編譯Shader程序并緩存編譯結果。

Shader代碼的解析與加載

MaterialBuilder類中,getShaderProgramCode方法負責從材質文件中提取Shader代碼。通過解析Shaders數組,我們可以獲取頂點著色器和片段著色器的源代碼路徑,并將其加載到內存中。

std::map<QOpenGLShader::ShaderTypeBit, QString> MaterialBuilder::getShaderProgramCode(const QJsonValue& shadersValue)
{static std::map<QString, QOpenGLShader::ShaderTypeBit> shaderTypeMap = {{ "Vertex", QOpenGLShader::Vertex },{ "Fragment", QOpenGLShader::Fragment }};std::map<QOpenGLShader::ShaderTypeBit, QString> shaderProgramCode;for (const QJsonValue& shaderValue : shadersValue.toArray()){const QJsonObject& shaderObject = shaderValue.toObject();QOpenGLShader::ShaderTypeBit shaderType = shaderTypeMap[shaderObject["ShaderEnum"].toString()];QString sourcePath = QHutu::applicationDirPath(shaderObject["SourceFile"].toString());shaderProgramCode.insert(std::pair<QOpenGLShader::ShaderTypeBit, QString>(shaderType, QHutu::readTextFile(sourcePath)));}return shaderProgramCode;
}

Shader程序的編譯與鏈接

createShaderProgram方法中,我們通過QOpenGLShaderProgram類編譯和鏈接Shader程序。具體步驟如下:

  1. 創建頂點著色器和片段著色器對象。
  2. 加載并編譯Shader源代碼。
  3. 將編譯后的Shader添加到Shader程序中。
  4. 鏈接Shader程序并驗證其有效性。
QOpenGLShaderProgram* MaterialBuilder::createShaderProgram(const QString& key)
{std::map<QString, QOpenGLShaderProgram*>::iterator iter = m_shaderPrograms.find(key);if (iter != m_shaderPrograms.end()){return iter->second;}std::map<QString, std::map<QOpenGLShader::ShaderTypeBit, QString>>::iterator iterator = m_shaderProgramCodes.find(key);if (iterator == m_shaderProgramCodes.end()){return nullptr;}QOpenGLShaderProgram* shaderProgram = new QOpenGLShaderProgram();std::map<QOpenGLShader::ShaderTypeBit, QString> shaderProgramCode = iterator->second;for (std::pair<QOpenGLShader::ShaderTypeBit, QString> shaderCode : shaderProgramCode){QOpenGLShader* shader = new QOpenGLShader(shaderCode.first);shader->compileSourceCode(shaderCode.second);shaderProgram->addShader(shader);}bool result = shaderProgram->link() && shaderProgram->bind();if (result){m_shaderPrograms.insert(std::pair<QString, QOpenGLShaderProgram*>(key, shaderProgram));}else{return nullptr;}return shaderProgram;
}

通過這種方式,我們可以動態地創建和管理多個Shader程序。這一部分的實現參考了深入理解OpenGL Shader與GLSL:基礎知識與優勢分析。

3. 材質的創建與使用

Material類中,我們封裝了材質的OpenGL狀態管理功能。通過createOpenGLState方法,我們可以為當前材質創建OpenGL狀態(如綁定Shader程序)。通過useMaterial方法,我們可以綁定當前材質并進行渲染。

void Material::createOpenGLState(IScreen* screen)
{m_shaderProgram = MaterialBuilder::materialBuilder()->createShaderProgram(m_key);
}bool Material::useMaterial()
{if (m_shaderProgram == nullptr){return false;}m_shaderProgram->bind();return true;
}

三、繪制四邊形的實現

在Horse3D中,繪制四邊形的過程可以分為以下幾個步驟:

1. 初始化材質與幾何體

FerghanaScreen類的構造函數中,我們創建了材質和四邊形對象:

Material* material;
Quadrangle* quadrangle;FerghanaScreen::FerghanaScreen(QWidget* parent): IScreen(parent)
{quadrangle = new Quadrangle();material = createMaterial("Materials/Test/Test.material");
}

2. 創建OpenGL狀態

initializeGL方法中,我們初始化OpenGL環境,并為材質和幾何體創建OpenGL狀態:

void FerghanaScreen::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.2f, 0.3f, 0.3f, 1.0f);quadrangle->createOpenGLState(this);material->createOpenGLState(this);
}

3. 渲染四邊形

paintGL方法中,我們綁定材質并繪制四邊形:

void FerghanaScreen::paintGL()
{glClear(GL_COLOR_BUFFER_BIT);material->useMaterial();quadrangle->useGeometry(this);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
}

這一部分的實現參考了之前的開發筆記在QtOpenGL環境下,仿three.js的BufferGeometry管理VAO和EBO繪制四邊形。


四、結果與分析

通過上述實現,我們可以在QtOpenGL環境下成功繪制帶有自定義Shader效果的四邊形。以下是本次實現的關鍵點總結:

  1. 材質管理系統的實現:通過Material類和MaterialBuilder類,我們實現了材質的動態加載與管理,支持Shader程序的編譯與緩存。
  2. Shader程序的動態加載:通過解析JSON格式的材質文件,我們實現了Shader程序的動態加載與編譯,支持靈活的Shader配置。
  3. 四邊形的繪制:通過結合材質系統和幾何體管理模塊,我們實現了帶有自定義Shader效果的四邊形的繪制。

五、項目介紹

Horse渲染內核基于Qt與OpenGL開發,是一款三維引擎。本項目將不提供編輯器,以SDK的形式對外提供接口。本項目將參考Three.js與Unity等眾多渲染引擎的API設計,致力于開發出一款具有競爭力的渲染引擎內核。

地址:

  • Gitee
  • GitHub

六、總結與展望

在本次開發中,我們成功實現了Horse3D引擎的材質管理系統,并通過該系統繪制了帶有自定義Shader效果的四邊形。這為后續的三維模型渲染奠定了基礎。

未來,我們計劃在以下方面進一步完善材質管理系統:

  1. 支持更多的Shader類型:如幾何著色器、曲面細分著色器等。
  2. 優化Shader程序的緩存機制:通過更高效的緩存策略減少Shader編譯的開銷。
  3. 支持更多的材質屬性:如光照模型、反射模型等。

通過不斷優化和擴展,我們希望將Horse3D引擎打造成為一款具有競爭力的三維渲染引擎內核。


七、參考文獻

  1. 深入理解OpenGL Shader與GLSL:基礎知識與優勢分析
    https://blog.csdn.net/2503_92624912/article/details/150076191

  2. Unity與OpenGL中的材質系統詳解
    https://blog.csdn.net/2503_92624912/article/details/150432587

  3. Three.js 材質系統深度解析
    https://blog.csdn.net/2503_92624912/article/details/150448417

  4. 應用Builder模式在C++中進行復雜對象構建
    https://blog.csdn.net/2503_92624912/article/details/149831961

  5. Horse3D游戲引擎研發筆記(一):從使用Qt的OpenGL庫繪制三角形開始
    https://blog.csdn.net/2503_92624912/article/details/150006641

  6. Horse3D游戲引擎研發筆記(二):基于QtOpenGL使用仿Three.js的BufferAttribute結構重構三角形繪制
    https://blog.csdn.net/2503_92624912/article/details/150063706

  7. Horse3D游戲引擎研發筆記(三):使用QtOpenGL的Shader編程繪制彩色三角形
    https://blog.csdn.net/2503_92624912/article/details/150114327

  8. Horse3D游戲引擎研發筆記(四):在QtOpenGL下仿three.js,封裝EBO繪制四邊形
    https://blog.csdn.net/2503_92624912/article/details/150235885

  9. Horse3D游戲引擎研發筆記(五):在QtOpenGL環境下,仿three.js的BufferGeometry管理VAO和EBO繪制四邊形
    https://blog.csdn.net/2503_92624912/article/details/150400945

Horse3D游戲引擎研發筆記(七):在QtOpenGL環境下,使用改進的Uniform變量管理方式繪制多彩四邊形 (相較于Unity、Unreal Engine與Godot引擎)

Pomian語言處理器 研發筆記(一):使用C++的正則表達式構建詞法分析器

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

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

相關文章

MySQL-分庫分表(Mycat)

目錄 1.介紹? 概述 拆分策略 垂直拆分? 水平拆分? 實現技術? shardingJDBC: MyCat: 2.Mycat概述 環境準備? 分片配置 schema.xml? server.xml 啟動服務? 分片測試? 3.MyCat配置 schema.xml? schema標簽 datanode標簽 ?datahost標簽? rule.xml …

Dubbo 的 Java 項目間調用的完整示例

1. 項目結構假設項目分為三個模塊&#xff1a;api&#xff1a;定義服務接口provider&#xff1a;服務提供者consumer&#xff1a;服務消費者2. 依賴配置在 pom.xml 中添加 Dubbo 和注冊中心&#xff08;如 Nacos&#xff09;的依賴&#xff1a;<dependency><groupId&g…

Python進行中文分詞

1. jieba庫概述 jieba&#xff08;“結巴”&#xff09;是Python中最流行的中文分詞庫&#xff0c;采用基于前綴詞典實現的高效分詞算法&#xff0c;支持多種分詞模式&#xff0c;是中文自然語言處理(NLP)的基礎工具。 核心特性 精確模式&#xff1a;試圖將句子最精確地切開&am…

JavaScript 性能優化實戰:從原理到落地的完整指南

一、引言&#xff1a;為什么 JavaScript 性能優化至關重要&#xff1f;性能與用戶體驗的強關聯數據支撐&#xff1a;加載延遲每增加 1 秒&#xff0c;用戶轉化率下降 7%&#xff08;來自 Google 研究&#xff09;核心痛點&#xff1a;現代 Web 應用中 JS 代碼體積膨脹、運行時卡…

前端自動化部署

摘要&#xff1a;前端自動化部署是通過工具和流程自動化實現前端代碼從開發完成到線上發布的全流程&#xff0c;減少人工操作、提高效率并降低出錯風險。核心目標減少重復操作&#xff1a;自動化構建、測試、部署等步驟&#xff0c;替代手動上傳服務器等低效方式。提升發布效率…

peewee中db.create_tables(tables, safe=True),safe=True作用

db.create_tables(tables, safeTrue) 中的 safeTrue 參數的作用是 防止在表已經存在的情況下引發錯誤。 具體來說&#xff1a; 當 safeTrue 時&#xff1a;Peewee 會在生成的 SQL 語句中加入 IF NOT EXISTS 子句&#xff08;例如&#xff1a;CREATE TABLE IF NOT EXISTS my_tab…

2025年計算機視覺與圖像國際會議(ICCVI 2025)

2025年計算機視覺與圖像國際會議| 視界創新&#xff0c;圖領未來 2025年計算機視覺與圖像國際會議&#xff08;ICCVI 2025&#xff09;將在中國東莞盛大召開。這不僅是一次匯聚全球頂尖科學家、工程師和學者的盛會&#xff0c;更是一個探索計算機視覺和圖像處理領域前沿技術與未…

Temu美國站大規模掃號封店:虛假本土店遭批量封禁,如何規避?

2025年8月&#xff0c;Temu平臺針對美國站再次掀起大規模掃號風暴。大量店鋪因注冊信息違規被判定為“高風險”&#xff0c;不僅店鋪被凍結&#xff0c;商品也被下架并禁止補貨。這一輪清掃&#xff0c;讓不少依靠“資料店”快速起盤的賣家遭遇重創。事實上&#xff0c;Temu的風…

航空發動機葉片yolov8模型訓練和轉換(包含適配rk3588-pt轉onnx轉rknn)

前言&#xff1a; 1.訓練在windows進行&#xff0c;因為電腦沒有顯卡&#xff0c;所以純cpu訓練&#xff0c;生成pt后轉onnx 2.onnx轉需要在Ubuntu虛擬機上運行 3.數據集標定快捷鍵 &#xff08;模型訓練時不需要&#xff09;官方地址和下載pt權重&#xff1a;鏈接&#xff…

PyTorch如何修改模型(魔改)?/替換模型,一般除了注意輸入輸出一致,還有其他要修改的嗎?

一、PyTorch如何修改模型&#xff08;魔改&#xff09;? 可以參考這個鏈接&#xff0c;看了一下還不錯&#xff1a; PyTorch如何修改模型&#xff08;魔改&#xff09;_模型魔改-CSDN博客 二、替換模型&#xff0c;一般除了注意輸入輸出一致&#xff0c;還有其他要修改的嗎?…

Pycharm Debug詳解

Pycharm Debug詳解看這個工具欄就是 PyCharm 調試器的“步進/斷點”按鈕區。常用按鈕和作用&#xff08;從左到右一般是這些&#xff09;&#xff1a; Resume / 繼續運行&#xff08;F9&#xff09;&#xff1a;從當前斷點繼續跑&#xff0c;直到下一個斷點或程序結束。Step Ov…

將SSL配置遷移到Nacos的步驟

將SSL配置遷移到Nacos的步驟 要將SSL配置從本地application.yml遷移到Nacos配置中心&#xff0c;需要完成以下幾個步驟&#xff1a; 1. 創建Nacos配置文件 在Nacos中創建一個新的配置文件&#xff08;例如application-ssl.yml&#xff09;&#xff0c;內容如下&#xff1a; ser…

HTTP請求參數類型及對應的后端注解

在Java后端開發中&#xff0c;HTTP請求的不同部分需要使用不同的注解來處理。以下是四種主要請求參數類型及其對應的Spring注解&#xff1a;1. 請求頭(Headers)??位置??&#xff1a;HTTP請求的頭部信息??常用場景??&#xff1a;認證信息(Token)、客戶端信息、內容類型等…

服務器硬件電路設計之 SPI 問答(一):解密 SPI—— 從定義到核心特性

在服務器硬件電路設計中&#xff0c;SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外設接口&#xff09;是一種關鍵的通信總線。它由摩托羅拉公司開發&#xff0c;是全雙工、同步串行通信總線&#xff0c;主要用于微控制器與外圍設備之間的通信&#xff0c;憑借…

【2025CVPR-目標檢測方向】OW-OVD:統一的開放世界和開放詞匯對象檢測

研究背景與動機? ?問題?:傳統目標檢測器(封閉集)需預定義所有類別,無法適應動態開放環境。現有研究多獨立解決開放詞匯檢測(OVD)或開放世界檢測(OWOD),未結合兩者優勢: ?OVD?:通過文本-視覺嵌入匹配實現零樣本泛化,但無法主動發現未知對象。 ?OWOD?:可主動…

基于Python的就業信息推薦系統 Python+Django+Vue.js

本文項目編號 25011 &#xff0c;文末自助獲取源碼 \color{red}{25011&#xff0c;文末自助獲取源碼} 25011&#xff0c;文末自助獲取源碼 目錄 一、系統介紹二、系統錄屏三、啟動教程四、功能截圖五、文案資料5.1 選題背景5.2 國內外研究現狀 六、核心代碼6.1 查詢數據6.2 新…

el-date-picker type=daterange 日期范圍限制

html &#xff08;組件&#xff1a;element-ui&#xff09;重點&#xff1a; :picker-options"pickerOptions"<template><el-date-pickerv-model"form.dateRange"type"daterange" value-format"yyyy-MM-dd"range-separator&q…

【38頁PPT】關于5G智慧園區整體解決方案(附下載方式)

篇幅所限&#xff0c;本文只提供部分資料內容&#xff0c;完整資料請看下面鏈接 https://download.csdn.net/download/2501_92808811/91694207 資料解讀&#xff1a;《關于5G智慧園區整體解決方案》 詳細資料請看本解讀文章的最后內容。 智慧園區行業理解與建設目標 智慧園…

Kafka的ISR、OSR、AR詳解

Kafka中的ISR、OSR和AR是副本管理機制的核心概念&#xff0c;它們共同保障了Kafka的高可用性和數據一致性。下面我將詳細解釋這些概念及其相互關系。 1. 基本概念 1.1 AR (Assigned Replicas) - 分配副本 定義&#xff1a;一個分區的所有副本集合稱為AR&#xff0c;即Kafka為主…

第一階段C#基礎-13:索引器,接口,泛型

1_索引器&#xff08;1&#xff09;索引器是C#中一個強大而實用的特性&#xff0c;允許像訪問數組一樣訪問類的成員&#xff08;2&#xff09;索引器&#xff1a;一種可以讓我們使用索引來訪問對象的一種方法&#xff0c;是一組get,set訪問器&#xff0c;與屬性類似&#xff0c…