2021SC@SDUSC
目录
分析概述
模块功能
该模块主要用于载入着色器模块以及进行顶点、片段着色器的绑定以及属性的绑定
着色器概述
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对象上
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");
}
}