Dust3D项目实训六 | 基于modelshaderprogram类的模型材质分析

2021SC@SDUSC

目录

分析概述

模块功能

着色器概述

关键代码分析

modelshaderprogram.h

modelshaderprogram.cpp

uniform变量

shader装载

ModelShaderProgram()分析


分析概述

模块功能

该模块主要用于载入着色器模块以及进行顶点、片段着色器的绑定以及属性的绑定

着色器概述

1.着色器介绍

着色器是为数字图像添加纹理的重要工具,分为顶点着色器和片段着色器。

顶点着色器使用VertexBuffer来定义构成几何图形的三角形,包含了一系列顶点数据。来自 VertextBuffer中的顶点数据作为输入传递给着色器,在着色器中可以处理这些数据。GPU将顶点着色器的输出数据组装为三角形,并进行光栅化处理。

片段着色器中的片段是一种简单的数据格式,每一个片段包含一个三角形在屏幕上能显示的所有像素,片段着色器是针对于每个像素点的,所以片段着色器的输出,就是该像素点应该显示的颜色值。片段中的数据内容通常由顶点着色器决定:顶点着色器可以将顶点属性参数作为自己的输出。光栅化负责将着色器输出的顶点数据在三角形上进行颜色插值,使片段上的每个像素都得到正确的属性值。

2.着色器应用过程

顶点着色器执行,获得三角形的顶点坐标并存放在图形的装配区

装配图形

将图形转化为片段(像素点)

片段着色器开始逐片操作

关键代码分析

modelshaderprogram.h

class ModelShaderProgram : public QOpenGLShaderProgram
{
public:
    ModelShaderProgram(bool isCoreProfile);
    int projectionMatrixLoc();//投影矩阵定位
    int modelMatrixLoc();//模型矩阵定位
    int normalMatrixLoc();//法线矩阵定位
    int viewMatrixLoc();//视图矩阵定位
    int eyePosLoc();
    int textureIdLoc();//纹理ID定位
    int textureEnabledLoc();//是否启用纹理定位
    int normalMapEnabledLoc();//是否启用法线映射定位
    int normalMapIdLoc();//法线映射Id定位
    int metalnessMapEnabledLoc();//判断金属性定位
    int roughnessMapEnabledLoc();//判断启用粗糙度定位
    int ambientOcclusionMapEnabledLoc();//环境光遮挡贴图定位
    int metalnessRoughnessAmbientOcclusionMapIdLoc();//金属粗糙度环境光遮挡贴图Id
    int mousePickEnabledLoc();//鼠标是否点击定位
    int mousePickTargetPositionLoc();//鼠标拾取目标位置
    int mousePickRadiusLoc();//鼠标拾取半径定位
    int environmentIrradianceMapIdLoc();//环境辐照度贴图定位
    int environmentIrradianceMapEnabledLoc();//判断其用环境辐照度贴图定位
    int environmentSpecularMapIdLoc();//环境镜面反射贴图定位
    int environmentSpecularMapEnabledLoc();//启用环境镜面反射贴图定位
    int toonShadingEnabledLoc();//阴影可见性定位
    int renderPurposeLoc();//渲染目的定位
    int toonEdgeEnabledLoc();//边缘启用定位
    int screenWidthLoc();//模型宽度定位
    int screenHeightLoc();//屏幕高度定位
    int toonNormalMapIdLoc();//法线图Id定位
    int toonDepthMapIdLoc();//深度图Id定位
    bool isCoreProfile();//判断是否核心轮廓
    static const QString &loadShaderSource(const QString &name);
private:
    bool m_isCoreProfile = false;
    int m_projectionMatrixLoc = 0;
    int m_modelMatrixLoc = 0;
    int m_normalMatrixLoc = 0;
    int m_viewMatrixLoc = 0;
    int m_eyePosLoc = 0;
    int m_textureIdLoc = 0;
    int m_textureEnabledLoc = 0;
    int m_normalMapEnabledLoc = 0;
    int m_normalMapIdLoc = 0;
    int m_metalnessMapEnabledLoc = 0;
    int m_roughnessMapEnabledLoc = 0;
    int m_ambientOcclusionMapEnabledLoc = 0;
    int m_metalnessRoughnessAmbientOcclusionMapIdLoc = 0;
    int m_mousePickEnabledLoc = 0;
    int m_mousePickTargetPositionLoc = 0;
    int m_mousePickRadiusLoc = 0;
    int m_environmentIrradianceMapIdLoc = 0;
    int m_environmentIrradianceMapEnabledLoc = 0;
    int m_environmentSpecularMapIdLoc = 0;
    int m_environmentSpecularMapEnabledLoc = 0;
    int m_toonShadingEnabledLoc = 0;
    int m_renderPurposeLoc = 0;
    int m_toonEdgeEnabledLoc = 0;
    int m_screenWidthLoc = 0;
    int m_screenHeightLoc = 0;
    int m_toonNormalMapIdLoc = 0;
    int m_toonDepthMapIdLoc = 0;
};

modelshaderprogram.cpp

uniform变量

Uniform是变量类型的一种修饰符,是着色器中的常量值,使用存储各种着色器需要的数据,其中,uniformLocation()用于存储着色器中的属性位置。

uniform 的空间被顶点着色器和片段着色器分享,一个在顶点着色器中声明的uniform,相当于在片段着色器中也声明过了。当应用程序装载uniform 时,它的值在顶点着色器和片段着色器都可用。(参考:OpenGL ES 3.0之Uniform详解 - ForrestWoo - 博客园 (cnblogs.com)

 this->bind();
    m_projectionMatrixLoc = this->uniformLocation("projectionMatrix");
    m_modelMatrixLoc = this->uniformLocation("modelMatrix");
    m_normalMatrixLoc = this->uniformLocation("normalMatrix");
    m_viewMatrixLoc = this->uniformLocation("viewMatrix");

shader装载

shader代码可以在文件夹中用文本文件保存,也可以在程序中用字符串保存,但最终还是必须在程序中以字符串的形式传入Shader对象中,传输过程如下:

1.创建Shader对象

2.把shader代码传入shader对象

3.编译Shader对象

4.通过一个名为shaderProgram的对象与shader交互,通过此对象连接到应用程序中

5.把之前创建的shaders,连接到shaderProgram对象上

6.链接shaderProgram

if (isCoreProfile) {
        this->addShaderFromSourceCode(QOpenGLShader::Vertex, loadShaderSource(":/shaders/default.core.vert"));
        this->addShaderFromSourceCode(QOpenGLShader::Fragment, loadShaderSource(":/shaders/default.core.frag"));
        m_isCoreProfile = true;
    } else {
        this->addShaderFromSourceCode(QOpenGLShader::Vertex, loadShaderSource(":/shaders/default.vert"));
        this->addShaderFromSourceCode(QOpenGLShader::Fragment, loadShaderSource(":/shaders/default.frag"));

ModelShaderProgram()分析

ModelShaderProgram::ModelShaderProgram(bool isCoreProfile)
{//设置模型着色器
    if (isCoreProfile) {//如果是核心部分
        //从源代码中添加顶点着色器
        this->addShaderFromSourceCode(QOpenGLShader::Vertex, loadShaderSource(":/shaders/default.core.vert"));
        //从源代码中添加片段着色器
        this->addShaderFromSourceCode(QOpenGLShader::Fragment, loadShaderSource(":/shaders/default.core.frag"));
        m_isCoreProfile = true;
    } else {
        this->addShaderFromSourceCode(QOpenGLShader::Vertex, loadShaderSource(":/shaders/default.vert"));
        this->addShaderFromSourceCode(QOpenGLShader::Fragment, loadShaderSource(":/shaders/default.frag"));
    }
    //为不同属性绑定属性位置
    this->bindAttributeLocation("vertex", 0);//顶点
    this->bindAttributeLocation("normal", 1);//法线
    this->bindAttributeLocation("color", 2);//颜色
    this->bindAttributeLocation("texCoord", 3);
    this->bindAttributeLocation("metalness", 4);//金属性贴图
    this->bindAttributeLocation("roughness", 5);//粗糙度
    this->bindAttributeLocation("tangent", 6);//切线
    this->bindAttributeLocation("alpha", 7);//阿尔法
    this->link();

    this->bind();
    
    m_projectionMatrixLoc = this->uniformLocation("projectionMatrix");
    m_modelMatrixLoc = this->uniformLocation("modelMatrix");
    m_normalMatrixLoc = this->uniformLocation("normalMatrix");
    m_viewMatrixLoc = this->uniformLocation("viewMatrix");
    m_eyePosLoc = this->uniformLocation("eyePos");
    m_textureIdLoc = this->uniformLocation("textureId");
    m_textureEnabledLoc = this->uniformLocation("textureEnabled");
    m_normalMapIdLoc = this->uniformLocation("normalMapId");
    m_normalMapEnabledLoc = this->uniformLocation("normalMapEnabled");
    m_metalnessMapEnabledLoc = this->uniformLocation("metalnessMapEnabled");
    m_roughnessMapEnabledLoc = this->uniformLocation("roughnessMapEnabled");
    m_ambientOcclusionMapEnabledLoc = this->uniformLocation("ambientOcclusionMapEnabled");
    m_metalnessRoughnessAmbientOcclusionMapIdLoc = this->uniformLocation("metalnessRoughnessAmbientOcclusionMapId");
    m_mousePickEnabledLoc = this->uniformLocation("mousePickEnabled");
    m_mousePickTargetPositionLoc = this->uniformLocation("mousePickTargetPosition");
    m_mousePickRadiusLoc = this->uniformLocation("mousePickRadius");
    m_toonShadingEnabledLoc = this->uniformLocation("toonShadingEnabled");
    m_renderPurposeLoc = this->uniformLocation("renderPurpose");
    m_toonEdgeEnabledLoc = this->uniformLocation("toonEdgeEnabled");
    m_screenWidthLoc = this->uniformLocation("screenWidth");
    m_screenHeightLoc = this->uniformLocation("screenHeight");
    m_toonNormalMapIdLoc = this->uniformLocation("toonNormalMapId");
    m_toonDepthMapIdLoc = this->uniformLocation("toonDepthMapId");
    if (m_isCoreProfile) {
        m_environmentIrradianceMapIdLoc = this->uniformLocation("environmentIrradianceMapId");
        m_environmentIrradianceMapEnabledLoc = this->uniformLocation("environmentIrradianceMapEnabled");
        m_environmentSpecularMapIdLoc = this->uniformLocation("environmentSpecularMapId");
        m_environmentSpecularMapEnabledLoc = this->uniformLocation("environmentSpecularMapEnabled");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值