LearnOpenGL学习笔记(二)——着色器简单理解
着色器在OpenGL中发挥着重要作用,它就像一个画笔,将输入的数据流,转为数学坐标,再将三维坐标变成二维坐标(针对我们现在用的二维显示器,全息显示器肯是三维的),再把二维坐标实际的像素点位置(这里面肯定存在的粗略的误差,比如(3.423,234.232)肯定在实际像素中不存在,要转换成邻近的),然后再往里面填充色彩,透明度之类的参数。 准确来说其实就是两步工作1.确定位置2.填充色彩。 处于输入输出与处理接口分开的原则,我们不考虑输入的数据具体是什么,这里只讨论如何去处理数据。
这里先上一张图,着色器程序分为六个小着色器部分,每个负责一部分
这里先解释一个专业术语“图形渲染管线”,这个就是上图显示的,像生产线一样的一条“管道”,进去数据流,出来一个像素画面。
当然咱们只可以编写三个着色器阶段,其中顶点着色器和片段着色器没有默认的,所以我们一开始只需要编写这两个简单的就可以了。
注意着色器严格来讲不是用c语言去编写的,而是一种GLSL的类c语言,它是c语言的变种,我们常把写好的着色器程序作为一个字符串,再运行的时候用一个函数(c语言编译器肯定没法编译glsl,需要一个函数进行转换)动态编译,然后将机器码放在GPU显存上运行。
接下来我们讨论如何去写着色器:
一个典型的着色器有下面的结构:
#version version_number//版本声明。一般版本必须和opengl一致,此外还有模式声明
in 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;
}
看得出着色器语言的程序,关键在于1.得到上一阶段的数据2,将数据处理3,把数据交给下一阶段
对于实现第一步和第三步,GLSL语言都有方便手段,就是IN,OUT关键字。只要在main函数前面声明的out 都将自动传递给接下来的着色器
同样着色器必须接受相同的in 同名变量数据输入。
也就是说,如果在顶点着色器声明了一个out vec3 aaa变量,那么接下来在片段着色器声明一个in vec aaa变量,那么自动这两个变量都会链接在一
起,数据自动传递过来。
//注意在着色器程序中,六个着色器都是独立的,in out是它们的通讯手段,它们本身是六个独立的小程序,变量都是独立的,传递是一种赋值
手段。
Uniform: 在程序中,我们想要实现动画,也就是说每次渲染都有变化,这种变化是连续的,那么我们就需要程序CPU和着色器(渲染),相互配合,在每次渲染中都改变,也就是我们需要一种可以在着色器程序和CPU程序相互交流的工具。所以我们需要一种独立于六个小程序,处于着色器程序的全局变量用来交流,否则我们无法告知CPU的程序如何去联系位于哪个小着色器上的变量(别忘了,我们在构建好着色器程序后,就删除了六个小程序编译的码)。
uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你
把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。我们可以在任何着色器中定义它们,而无需通过顶点着
色器作为中介。
#version 330 core
out vec4 FragColor;
uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量
void main() {
FragColor = ourColor;
} 接下来我们跳出来,在CPU上改变我们的数据,然后再传入着色器里好了。
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
这个函数得到了着色器这个变量的索引,我们用它就可以修改着色器上的uniform了。
glUseProgram(shaderProgram); //先启动这个着色器
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
//glUniform函数就是用来修改的,4f是因为c语言不存在重载,所以我们只能命名n个类似函数名函数了 我们加入一些随时间改变的量,在每次渲染时都改变一点颜色(一秒钟五十次),就可以看到这样动画了。
float timeValue = glfwGetTime();
float greenValue = sin(timeValue) / 2.0f + 0.5f;
int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
uniform对于设置一个在渲染迭代中会改变的属性是一个非常有用的工具,它也是一个在程序和着色器间数据交互的很好工具
LearnOpenGL学习笔记(二)——着色器简单理解的更多相关文章
- Android学习笔记二:activity的理解
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7513290.html 一:activity定义了app的页面 一个app有很多个页面组成,一个页面其实就是一个 ...
- spring in action 学习笔记二:aop的理解
一: aop的思想的来在哪里? 一个系统一般情况下由多个组件组成,而每一个组件除了干自己的本职工作以外,有时还会干一些杂活(如:日志(logging).事务管理(transaction manager ...
- Html学习笔记(二) 简单标签
标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
- muduo学习笔记(二)Reactor关键结构
目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...
- HTML DOM(学习笔记二)
嗯,在HTML DOM(学习笔记一)中简单描述了一下HTML DOM 是什么,这一篇将记录下来有关HTML DOM的内容! 1:DOM节点 首先,再来看一下HTML DOM的树状结构,如下图所示: 这 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring
接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...
随机推荐
- Powershell 脚本判断制定路径下文件是否存在(来源于网络-转载)
$filelist=gc "file.txt" #获取要检查的文件列表 $csvs= new-object collections.arraylist #创建一个arraylist ...
- mybatis电子商务平台b2b2c
技术解决方案 开发语言: java.j2ee 数据库:mysql JDK支持版本: JDK1.6.JDK1.7.JDK1.8版本 核心技术:分布式.云服务.微服务.服务编排等. 核心架构: 使用Spr ...
- PowerShell 脚本中调用密文密码
1. 把密码转变为加密的字符串.使用命令 ConvertFrom-SecureString Read-Host "Enter Password" -AsSecureString | ...
- jquery 表单校验
<link type="text/css" href="<%=basepath%>css/form/validate.css" rel=&qu ...
- java中date日期格式的各种转换
示例 Date dt =new Date(); System.out.println(dt); //格式: Wed Jul 06 09:28:19 CST 2016 //格式:2016-7-6 Str ...
- 【轻松前端之旅】CSS盒子模型
盒子模型,也叫框模型,在CSS里是很重要的概念. 每个元素都可以看做一个盒子.盒子包含四个部分:外边距(margin).边框(border).内边距(padding).元素内容(element con ...
- LOJ-10106(有向图欧拉回路的判断)
题目链接:传送门 思路: (1)将每个单词视为有向路径,单词的起始字母是起始节点,末尾字母是终止节点,然后找由字母建立的有向图 是否是欧拉图或者半欧拉图. (2)先用并查集判断是否连通,再判断入度与出 ...
- ABP框架系列之十七:(Data-Filters-数据过滤)
Introduction It's common to use the soft-deletepattern which is used to not delete an entity from da ...
- nginx unit的初探
安装介绍: https://www.oschina.net/p/nginx-unit 可以看到,unit还是很强大的,居然特么都支持go 还有python 在/etc/yum.repos.d/unit ...
- Codeforces Round #541--1131F. Asya And Kittens(基础并查集)
https://codeforces.com/contest/1131/problem/F #include<bits/stdc++.h> using namespace std; int ...