OpenGL学习整理------着色器

摘要:
但在顶点和片段着色器中会有点不同。你也可以忽略layout标识符,通过在OpenGL代码中使用glGetAttribLocation查询属性位置值,但是我更喜欢在着色器中设置它们,这样会更容易理解而且节省你的工作量。如果你在片段着色器没有定义输出颜色,OpenGL会把你的物体渲染为黑色(或白色)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。

1.着色器

着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上说,着色器

只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能互相通信;

着色器之间唯一的沟通只有通过输入和输出;

2.GLSL

着色器是用一种叫GLSL(OpenGL Shader Luanguage) 的类C语言写成的。

典型的着色器结构如下

    #version version_number
    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;
    }

特别对于顶点着色器,每个输入变量也叫顶点属性(Vertex Attribute)。我们能声明的顶点属性是有上限的,一般由硬件决定。

OpenGL确保至少有16个包含4分量的顶点属性可用,有些硬件或许允许更多的顶点属性,可以查询GL_MAX_VERTEX_ATTRIBS来获取具体上限:

    intnrAttributes;
    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &nrAttributes);
    std::cout << "Maximum nr of vertex attributes supported: " << nrAttributes << std::endl;

3.数据类型

GLSL有数据类型可以来指定变量的种类。

数据类型: int、float、double、uin(unsigned int )t、bool;

容器类型: Vector、Matrix;

4.向量

GLSL中的向量是一个可以包含有1、2、3或者4个分量的容器,分量的类型可以是前面默认基础类型的任意一个。它们可以是下面的形式(n代表分量的数量):

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

大多数时候我们使用vecn,因为float足够满足大多数要求了。

5.输入输出

我们希望每个着色器都有输入和输出,这样才能进行数据交流和传递。

GLSL定义了inout关键字专门来实现这个目的。每个着色器使用这两个关键字设定输入和输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下去。

但在顶点和片段着色器中会有点不同。

顶点着色器应该接收的是一种特殊形式的输入,否则就会效率低下。顶点着色器的输入特殊在,它从顶点数据中直接接收输入。

为了定义顶点数据该如何管理,我们使用location这一元数据指定输入变量,这样我们才可以在CPU上配置顶点属性。

我们已经在前面的教程看过这个了,layout (location = 0)顶点着色器需要为它的输入提供一个额外的layout标识,这样我们才能把它链接到顶点数据。

你也可以忽略layout (location = 0)标识符,通过在OpenGL代码中使用glGetAttribLocation查询属性位置值(Location),但是我更喜欢在着色器中设置它们,这样会更容易理解而且节省你(和OpenGL)的工作量。

另一个例外是片段着色器,它需要一个vec4颜色输出变量,因为片段着色器需要生成一个最终输出的颜色。

如果你在片段着色器没有定义输出颜色,OpenGL会把你的物体渲染为黑色(或白色)。

6.Uniform

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

首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的而且它可以被着色器程序的任意着色器在任意阶段访问

第二无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。

顶点着色器中不需要这个uniform,所以我们不用在那里定义它。

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

当我们在着色器中定义了Uniform后,我们还没有给它添加任何数据,所以下面我们就做这件事。

我们首先需要找到着色器中uniform属性的索引/位置值。当我们得到uniform的索引/位置值后,我们就可以更新它的值了。

这次我们不去给像素传递单独一个颜色,而是让它随着时间改变颜色:

float timeValue =glfwGetTime();
  float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
  int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
  glUseProgram(shaderProgram);
  glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);

免责声明:文章转载自《OpenGL学习整理------着色器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇XAML学习笔记——Layout(四)读书心得3:去功利化&amp;amp;推荐两本书 转时寒冰下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

export 设置当次登陆的环境变量

Linux export 命令用于设置或显示环境变量。 在 shell 中执行程序时,shell 会提供一组环境变量。export 可新增,修改或删除环境变量,供后续执行的程序使用。export 的效力仅限于该次登陆操作 语法 export [-fnp][变量名称]=[变量设置值] 参数说明: -f  代表[变量名称]中为函数名称。 -n  删除指定的变...

第6章 约束满足问题CSP

第六章 约束满足问题CSP 一、问题定义 问题定义 状态空间,状态被定义为在值域Di中的变量Xi; 当前状态; 转移模型; 目标测试,每个变量都有自己的赋值同时满足约束条件; 评估函数。 三个成分 X是变量集合 [{X_1,...,X_n} ] D是值域集合 [{D_1,...,D_n} ] ,每个变量都有自己的值域。 C是描述变量取值的约束集合...

变量的命名规则及命名规范

变量的命名规则如下: 1、组成:52个应为字母(A-Z、a~z)、10个数字(0~9)、下划线(_)、除此之外不能含有其他的字符。 2、开头:只能以字母或下划线开头。 3、不能使用的:不能是C#中的关键字 变量命名规范如下: 1、变量的名称要有意义,尽量用对应的英文命名,具有见名知意的作用。比如一个变量代表姓名,不能使用aa、bb等,要使用name。 2、...

BUAA_2019_MATLAB基础与应用_期末复习纲要

Matlab复习提纲 一、概述 1. Matlab(Matrix Laboratory)概述 1980年,由美国的 Clever Moler 博士开发; 是一款 科学与工程计算软件; 第四代智能计算机语言。 2. 功能与特点 开放性强、可扩展性强,兼容性强,直观灵活; MATLAB提供了丰富的矩阵运算处理功能,是基于矩阵运算的处理工具; 矩阵运...

JDK安装

转自:http://www.cnblogs.com/smyhvae/p/3788534.html 【正文】 1、安装JDK开发环境 下载网站:http://www.oracle.com/ 开始安装JDK: 修改安装目录如下: 确定之后,单击“下一步”。 注:当提示安装JRE时,可以选择不要安装。 2、配置环境变量: 对于Java程序开发而言,主要...

python_14(js)

第1章 图片方法 1.1 设置背景图:1.2 背景图问题:1.3 background-repeat; noa-repe 1.4 background-attachment: fixed1.5 background-position 1.6 background-position-x 1.7 截取局部1.7.1 透明色第2章 定位 2.1 定义形式2.2...