顶点着色器+片段着色器

一: 着色器

  1. 着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。
  2. 在最简配置下,至少都得有两个着色器:一个叫顶点着色器(vertex shader),它将作用于每个顶点上;另一个叫片段着色器(fragment shader),它将作用于每一个采样点。我们采用4倍抗锯齿,因此每个像素有四个采样点。
  3. 如果我们打算从一个着色器向另一个着色器发送数据,我们必须在发送方着色器中声明一个输出,在接收方着色器中声明一个类似的输入。当类型和名字都一样的时候,OpenGL就会把两个变量链接到一起,它们之间就能发送数据了(这是在链接程序对象时完成的)。

二: 顶点着色器

  1. 顶点着色器应该接收的是一种特殊形式的输入,否则就会效率低下。顶点着色器的输入特殊在,它从顶点数据中直接接收输入。
  2. 为了定义顶点数据该如何管理,我们使用location这一元数据指定输入变量,这样我们才可以在CPU上配置顶点属性。比如:layout (location = 0)。顶点着色器需要为它的输入提供一个额外的layout标识,这样我们才能把它链接到顶点数据。
  3. 为了设置顶点着色器的输出,我们必须把位置数据赋值给预定义的gl_Position变量,它在幕后是vec4类型的。在main函数的最后,我们将gl_Position设置的值会成为该顶点着色器的输出。由于我们的输入是一个3分量的向量,我们必须把它转换为4分量的。我们可以把vec3的数据作为vec4构造器的参数,同时把w分量设置为1.0f(我们会在后面解释为什么)来完成这一任务
  4. 将更多的属性数据如颜色等添加进顶点数据中:
    4.1 调整顶点着色器,使它能够接收颜色值作为一个顶点属性输入。需要注意的是我们用layout标识符来把aColor属性的位置值设置为1。
    4.2 因为我们添加了另一个顶点属性,并且更新了VBO的内存,我们就必须重新配置顶点属性指针。

三: 片段着色器

  1. 片段着色器(Fragment Shader)是第二个也是最后一个我们打算创建的用于渲染三角形的着色器。片段着色器所做的是计算像素最后的颜色输出。
  2. 片段着色器需要一个vec4颜色输出变量,因为片段着色器需要生成一个最终输出的颜色。如果你在片段着色器没有定义输出颜色,OpenGL会把你的物体渲染为黑色(或白色)。
  3. 片段着色器中进行的所谓片段插值(Fragment Interpolation)的结果。当渲染一个三角形时,光栅化(Rasterization)阶段通常会造成比原指定顶点更多的片段。光栅会根据每个片段在三角形形状上所处相对位置决定这些片段的位置。
  4. 基于这些位置,它会插值(Interpolate)所有片段着色器的输入变量。比如说,我们有一个线段,上面的端点是绿色的,下面的端点是蓝色的。如果一个片段着色器在线段的70%的位置运行,它的颜色输入属性就会是一个绿色和蓝色的线性结合;更精确地说就是30%蓝 + 70%绿。
  5. 这也就是为什么只设置了顶点的颜色,画出来的三角形都有颜色了。即:我们有3个顶点,和相应的3个颜色,从这个三角形的像素来看它可能包含50000左右的片段,片段着色器为这些像素进行插值颜色。如果你仔细看这些颜色就应该能明白了:红首先变成到紫再变为蓝色。片段插值会被应用到片段着色器的所有输入属性上。

四: uniform变量

  1. 首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
  2. 第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。
  3. 如果你声明了一个uniform却在GLSL代码中没用过,编译器会静默移除这个变量,导致最后编译出的版本中并不会包含它,这可能导致几个非常麻烦的错误。
  4. 给uniform变量添加数据:我们首先需要找到着色器中uniform属性的索引/位置值。当我们得到uniform的索引/位置值后,我们就可以更新它的值了。
  5. 我们用glGetUniformLocation查询uniform ourColor的位置值。我们为查询函数提供着色器程序和uniform的名字(这是我们希望获得的位置值的来源)。如果glGetUniformLocation返回-1就代表没有找到这个位置值。
  6. 最后,我们可以通过glUniform4f函数设置uniform值。注意,查询uniform地址不要求你之前使用过着色器程序,但是更新一个uniform之前你必须先使用程序(调用glUseProgram),因为它是在当前激活的着色器程序中设置uniform的。

原文地址:https://www.cnblogs.com/GarrettWale/p/11335361.html

时间: 2024-10-11 01:47:48

顶点着色器+片段着色器的相关文章

Vertex and FragmentShader顶点与片段着色器

一.顶点与片段着色器简介 Vertex and FragmentShader:最强大的Shader类型,也是本系列的重点,下文中简称V&FShader,属于可编程渲染管线.使用的是CG/HLSL语法.分为2个部分vertex顶点部分和Fragment像素部分.下面依然通过写几个简单的Shader来学习. 二. CG语言一些关键词和常用函数解释 1.Cg顶点程序必须在结构中传递顶点数据.几种常用的顶点结构定义在文件UnityCG.cginc中.在大部分情况下仅仅使用它们就够了.结构如下: 1.ap

UnityShader之顶点片段着色器Vertex and Fragment Shader【Shader资料】

顶点片段着色器 V&F Shader:英文全称Vertex and Fragment Shader,最强大的Shader类型,也是我们在使用ShaderLab中的重点部分,属于可编程管线,使用的是CG/HLSL语法.分为vertex顶点部分和Fragment像素部分. 本篇的末尾讲述顶点函数传入的结构体类型的参数appdata_base. Shader "Custom/Exam1" { Properties { _MainTex ("Texture", 2D

OpenGL ES 3.0片段着色器(四)

片段着色器流程图 片段着色器(fragment shader)实现了一个通用的可编程操作片段的方法.片段着色器执行由 光栅化生成的每个片段. • Shader program(着色器程序)—片段着色器程序源码或描述将在该片段上可以执行的操作. • Input variables(输入变量)—光栅化阶段使用插补技术为片段着色器产生顶点着色器的输出 • Uniforms—片段着色器的常量数据 • Samplers—Uniforms使用的具体类型,在纹理(Texture)中被片段着色器使用 片段着色可

opengl绘图,画一个旋转的四边形和一个旋转的三角形,平滑着色和单一着色

opengl单一着色和平滑着色,以及图形的旋转 package com.example.zp.myapplication;   import java.nio.FloatBuffer;     import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10;   import android.opengl.GLSurfaceView.Renderer;   publi

JVM垃圾收集器-G1收集器

G1收集器是当前收集器技术发展的最前沿成果,在JDK1.6_Updata14中提供了Early Access版本的G1收集器以供适用.G1收集器是垃圾收集器理论进一步发展的产物,它与前面的CMS收集器相比有两个显著的改进:一是G收集器是基于"标记-整理"算法实现的收集器,也就是说它不会产生碎片,这对于长时间运行的应用系统来说比较重要.二是它可以非常精确地控制停顿,既能让使用者明确指定爱一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java的垃圾收集

流之阅读器和书写器(简介)

Java的内置字符集是Unicode的UTF-16编码.Java提供了一组API来读/写字符.注意这里是字符而不是字节.java.io.Reader类指定读取字符的API.java.io.Writer指定写字符的API.字节流与字符流相互转换的地方,就会使用到阅读器和书写器.Reader和Writer的具体子类允许读取特定的源和写入特定的目标.另外,过滤器阅读器和书写器可以附加到其他阅读器或书写器上,以提供额外的服务或接口. Reader和Writer最重要的具体子类是 InputStreamR

java类加载器-----用户自定义类加载器实现

java类加载器主要分为如下几种: jvm提供的类加载器 根类加载器:底层实现,主要加载java核心类库(如:java.lang.*) 扩展类加载器:使用java代码实现,主要加载如:jre/lib/ext/ 下的扩展类库.(父类加载器为根类加载器) 系统类加载器(应用类加载器):使用java代码实现,加载classpath目录下的类.(父类加载器为扩展类加载器) 用户自定义类加载器:去继承ClassLoader类实现自定义类加载器. 类加载器负责将java字节码文件加载到虚拟机内存中也就是类的

ROS 自定义消息发布器和订阅器测试 +代码详解(入门级)

既对ros tutorial 上的例子有了一定的了解之后,今天对发布器和订阅器代码(http://wiki.ros.org/cn/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29)进行了研究,同时稍作改动进行了验证, 发布器-------------------------------------------------------------------------------------------------------------

流之阅读器和书写器(过滤器阅读器和过滤器书写器)

InputStreamReader和OutputStreamWriter类就是相当于输入和输出流之上的装饰器,把面向字节的接口改为面向字符的接口.完成之后,就可以在它们之上使用面向字符的过滤器阅读器或过滤器书写器.与过滤器流一样,有很多子类可以完成特定的过滤工作,包括: BufferedReader BufferedWriter LineNumberReader PushbackReader PrintWriter BufferedReader和BufferedWriter类是基于字符的,对应于