着色器在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学习笔记(二)——着色器简单理解的更多相关文章

  1. Android学习笔记二:activity的理解

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7513290.html 一:activity定义了app的页面 一个app有很多个页面组成,一个页面其实就是一个 ...

  2. spring in action 学习笔记二:aop的理解

    一: aop的思想的来在哪里? 一个系统一般情况下由多个组件组成,而每一个组件除了干自己的本职工作以外,有时还会干一些杂活(如:日志(logging).事务管理(transaction manager ...

  3. Html学习笔记(二) 简单标签

    标签的重点 标签的用途 标签在浏览器中的默认样式 <body>标签: 在网页上显示的内容 <p>标签: 添加段落 <hx>标签: 添加标题 标签一共有6个,h1.h ...

  4. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  5. muduo学习笔记(二)Reactor关键结构

    目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...

  6. HTML DOM(学习笔记二)

    嗯,在HTML DOM(学习笔记一)中简单描述了一下HTML DOM 是什么,这一篇将记录下来有关HTML DOM的内容! 1:DOM节点 首先,再来看一下HTML DOM的树状结构,如下图所示: 这 ...

  7. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  8. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  9. ES6学习笔记<二>arrow functions 箭头函数、template string、destructuring

    接着上一篇的说. arrow functions 箭头函数 => 更便捷的函数声明 document.getElementById("click_1").onclick = ...

随机推荐

  1. 搭建Fabric网络(三)artifacts是怎么生成的:cryptogen和configtxgen

    在first-network里,./byfn.sh generate可以生成artifacts文件. generate参数其实是使用了cryptogen和configtxgen这两个工具,这两个工具分 ...

  2. python 的面相对象编程--对应c++

    在python的面相对象编程中,我们常常在class中可以看到a(),  _b() ,  __c(), __d()__这样的函数. 由于我是看廖雪峰老师的教程,廖老师为了简单起见,没有引入太多概念,我 ...

  3. iis 发布mvc

    转载地址:https://www.cnblogs.com/Leo_wl/p/3866625.html

  4. Hdp安装问题杂解

    5.在安装的时候遇到的问题 5.1使用ambari-server start的时候出现ERROR: Exiting with exit code -1. 5.1.1REASON: Ambari Ser ...

  5. 关于HttpClient,HttpURLConnection,OkHttp的用法

    1 HttpClient入门实例 1.1发送get请求 /** * HttpClient发送get请求 * @param url 请求地址 * @return * @throws IOExceptio ...

  6. Git学习篇之git remote add origin错误

    提示出错信息:fatal: remote origin already exists. 解决办法如下: 1.先输入$ git remote rm origin 2.再输入$ git remote ad ...

  7. 请找出至少一个由递推关系 a(i) = a(i – 1) + a(i – 2) 生成的数列,使得当 n 趋于 (√5+1)/2的数列

    寻找前后两项比值趋于 (√5+1)/2的广义Fibonacci数列 找到了一个帖子:这个帖子 //待补充

  8. php 从2维数组组合为四维数组分析(项目中前台侧边栏导航三级分类显示)

    foreach函数(循环函数)内嵌套循环函数时,当内层完全循环完后,才会向上一级循环 数组要注意问题 array_merge----合并一个或多个数组 将一个或多个数组的单元合并起来,一个数组中的值附 ...

  9. 手动封装on,emit,off

    on 绑定 emit 触发 off 解绑 //存放事件eventList = {key:valhandle:[]} 1对多on(eventName,callback);handle:-------N多 ...

  10. 简单登录注册实现(Java面向对象复习)

    简单登录注册的实现(面向对象的复习) 需求: 设计用户类,包含用户名和密码两个属性 设计LoginDemo类设计用户登录方法 用户有三次登录机会,如果连续三次登录失败则退出程序 功能实现页面:     ...