着色器的一些归纳总结
来源:互联网 发布:淘宝退货怎么寄件 编辑:程序博客网 时间: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.x
、vec.y
、vec.z
、vec.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定义了in
和out
关键字来实现着色器的输入输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下棋,但在顶点和片段着色器中会有点不同
顶点着色器的输入特殊在它从顶点数据中直接接收输入。为了定义定点数据该如何管理,使用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 函数需要3个float作为它的值fv 函数需要一个float向量/数组作为它的值
本文的代码可在这里找到,如果对您有所帮助,不妨点个赞。☺
- 着色器的一些归纳总结
- Java读文件的一些归纳总结
- SQL语言的一些归纳总结
- Java中一些知识的归纳总结
- 关于工作流(Workflow Foundation)的一些总结归纳
- 关于工作流(Workflow Foundation)的一些总结归纳
- 针对简历做一些知识点的总结与归纳
- log4j 的 一些归纳
- OpenGL着色器的使用总结
- c++的总结归纳
- Shader Effects 一些着色器的额外功能
- 介绍了表面着色器的基本概念和一些写法
- 介绍了表面着色器的基本概念和一些写法
- linux的一些常识归纳
- 关于Yarn的一些归纳
- 关于flexible的一些归纳
- 关于百分比的一些归纳
- 对java中一些关键的,容易迷惑的知识点的归纳总结
- Python的Pexpect库
- HDU 5046 Airport (DLX可重复覆盖+二分)
- js+jquery实现增加或删除表格中的一行数据
- Cloudera Manager 5升级(官方翻译整理,企业级实战验证)
- HDU 1003 注意初始化
- 着色器的一些归纳总结
- 51nod 1413 权势二进制
- Struts学习
- 【AngularJS】解决ng-if中的ng-model值无效的问题
- OSVR-Vive
- 获取XML文件内容
- Junit hamcrest相关问题
- LSTM中隐层神经元的传播机制
- 未知:数列1——题解