着色器的一些归纳总结

来源:互联网 发布:淘宝退货怎么寄件 编辑:程序博客网 时间:2024/06/07 00:47

最近在学习OpenGL,把学习的一些过程写在这里,希望与大家共同分享讨论。欢迎光临我的个人网站Orient一起讨论学习。这里是我的GitHub,如果您喜欢,不妨点个赞?☺

着色器(shaders)

结构(structure)

#version version_numberin type in_variable_name;in type in_variable_name;out type out_variable_name;uniform type uniform_name;int main(){    // 处理输入并进行一些图形操作    ...    // 输出处理的结果到输出变量    out_variable_name = weird_stuff_we_processed;}

查询顶点属性上限

查询 GL_MAX_VERTEX_ATTRIBS 获取能申明的顶点属性上限(一般由硬件决定,OpenGL确保至少有16个包含4分量的顶点属性可用)

unsigned int nrAttributes;glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);std::cout << "Maximun nr of vertex attributes supported:" << nrAttributes << std::endl;

vector(大多时候我们使用vecn,float足够满足大多数要求)

vecn:包含n个float分量的默认向量bvecn:包含n个bool分量的向量ivecn:包含n个int 分量的向量uvecn:包含n个unsigned int分量的向量dvecn:包含n个double分量的向量

分量获取

向量的分量可通过vec.x这种方式获取,vec.xvec.yvec.zvec.w获取第1、2、3、4个分量。GLSL也允许对颜色使用rgba,或是对纹理坐标使用stpq访问相同的分量

向量重组(Swizzling)

vec2 someVec;vec4 differentVec = someVec.xyxx;vec3 anotherVec = differentVec.zyw;vec4 otherVec = someVec.xxxx + anotherVec.yxzy
vec2 vect = vec2(0.5, 0.7);vec4 result = vec4(vect, 0.0, 0.0);vec4 otherResult = vec4(result.xyz, 1.0);

输入与输出

GLSL定义了inout关键字来实现着色器的输入输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下棋,但在顶点和片段着色器中会有点不同

顶点着色器的输入特殊在它从顶点数据中直接接收输入。为了定义定点数据该如何管理,使用location这一元数据指定输入变量,这样就可以在CPU上配置顶点属性。顶点着色器需要为它的输入提供一个额外的layout标识,这样才能把它链接到顶点数据。

改动程序中的着色器

顶点着色器:

#version 410 corelayout (location = 0) in vec3 aPos; // 位置变量的属性值为0out vec4 vertexColor;   // 为片段着色器指定一个颜色输出void main(){    gl_Position = vec4(aPos, 1.0);  // 注意,这里把一个vec3作为vec4的构造器参数    vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 把输出变量设置为暗红色}

片段着色器:

#version 410 coreout vec4 FragColor;in vec4 vertexColor;    // 从顶点着色器传来的输入变量(名称、类型相同)void main(){    FragColor = vertexColor;}

这样完成了从顶点着色器向片段着色器发送数据,改变了三角形的颜色

Uniform

Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但它和定点属性有些不同。

1、Uniform是全局的,Uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
2、无论把Uniform值设置成什么,它会一直保存它们的数据,直到它们被重置或更新。

在一个着色器中添加Uniform关键字至类型和变量名前来生命一个GLSL的Uniform。

#version 410 coreout vec4 FragColor;uniform vec4 ourColor;  // 在OpenGL程序代码中设定这个变量void main(){    FragColor = ourColor;}

如果申明了一个uniform却在GLSL代码中没用过,编译器会静默移除这个变量,导致最后编译出的版本中不会包含它,这可能导致几个非常麻烦的错误!

接下来给uniform添加数据,使得三角形颜色随时间而改变

// 获取运行的秒数float timeValue = glfwGetTime();// sin函数(引入cmath)让颜色在0.0到1.0之间改变float greenValue = sin(timeValue) / 2.0f + 0.5f;// 查询uniform ourColor的位置值,如果返回-1则表示没有找到这个位置值int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");glUseProgram(shaderProgram);// 设置uniform值。glad_glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

注意,查询uniform地址不要求你之前使用过的着色器程序,但更新一个uniform之前必须先使用程序(调用glUseProgram),因为它是在当前激活的着色器中设置uniform的

因为OpenGL其核心是一个C库,所以它不支持类型重载,在函数参数不同的时候就要为其定义新的函数;glUniform就是一个典型的例子:

后缀  含义f    函数需要一个float作为它的值i    函数需要一个int作为它的值ui   函数需要一个unsigned int作为它的值3f   函数需要3float作为它的值fv   函数需要一个float向量/数组作为它的值

本文的代码可在这里找到,如果对您有所帮助,不妨点个赞。☺

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 写卷子的题目不认识怎么办? 2个月小猫尿床怎么办 安全教案鱼刺卡住了怎么办 被鱼刺卡住怎么办安全教案 小班健康教案生病了怎么办 被蜜蜂蛰了怎么办教案 走丢了怎么办大班反思 小孩吃了硬物怎么办 小孩吞了硬物怎么办 小学二年级孩子成绩不好怎么办 二年级孩子成绩不好怎么办 一年级学的不好二年级怎么办 17个月宝宝夜奶怎么办 小孩吃积食了吐怎么办 11个宝宝不会爬怎么办 5岁宝宝严重挑食怎么办 孩子吃菜口味重怎么办? 孩子挑食不吃菜不吃肉怎么办 微信新的朋友回复频繁怎么办 忘了闺蜜生日怎么办 把闺蜜生日忘了怎么办 忘了闺蜜的生日怎么办 一岁宝宝不吃菜怎么办 幼儿园教案虫子爬进耳朵怎么办 鼻子出血怎么办幼儿说课 英语记不住发音不准怎么办 幼儿园孩子拼音记不住怎么办 孩子总是记不住东西怎么办 走丢了怎么办小班教案 走丢了怎么办小班社会 数学加减个十分不清怎么办 孩子b和d分不清怎么办 小孩b和d分不清怎么办 高一的数学不会怎么办 农村小孩到市里上学怎么办 和外国人打官司输了怎么办 碰见爱说你的领导怎么办 小孩脾气爆一句话就生气怎么办 小孩眼睛哭肿了怎么办 大人吵架吓到宝宝了怎么办 小孩晚上睡觉不踏实怎么办