OpenGL中的着色器(GLSL)

本文详细介绍了OpenGL中的着色器语言GLSL,包括顶点着色器和片段着色器的使用,以及Uniform变量的管理和更新。通过示例代码展示了如何定义和操作向量、顶点属性和Uniform,同时提出了一种封装成自定义着色器类的方法,以简化shader的管理和使用。
摘要由CSDN通过智能技术生成

OpenGL中的着色器(Shader)语言,也就是GLSL。可以把它们看作是一个独立的小程序,这个小程序有输入,然后处理输入,然后将处理的结果输出,两个Shader通过输入和输出进行通信,GLSL为此还有专门的关键字:in和 out 。shader发送方将输出规定为特定的类型,shader的接收方接收相同的类型作为自己的输入,这样两个shader就联系了起来。

shader的格式基本固定,首先声明版本,然后定义输入输出的格式以及变量,接着是Uniform和main函数,和C语言一样,shader的入口都是main函数,main函数里面我进行数据的处理,然后将处理的数据传给输出变量。

OpenGL的shader里面支持C语言中的大部分的基础数据结构,int,float,double,bool等,然后shader里面还有自己的容器,分别是:向量(veector)和矩阵(matrix)。

向量:

vec2、vec3、vec4分别可以定义一个二维,三维,四维的向量。

三维向量可以使用二维向量进行填充,四维向量可以使用三维向量进行填充。

他们的分量也可以使用.x   .y    .z进行访问。

也可以使用一个向量的某些分量去合并成一个新的向量。

vec2 one = vec2(0.2,0.5);
vec3 two = vec3(one,0.8);
vec4 three = vec4(two,1.0);

// 使用three向量的x分量初始化four向量的四个分量
vec4 four = three.xxxx
// 使用four向量的y,y,x,z向量分别初始化five向量的四个分量 
vec4 five = four.yyxz;

顶点着色器

顶点着色器从顶点数据中直接接收输入,为了便于顶点数据的管理,OpenGL的shader通过location这一元数据指定输入变量,指定好输入变量之后,为我们才能再CPU上配置顶点属性。顶点着色器需要给他一个特殊的标识:layout,才能将这个标识链接到顶点数据上:layout(location = 0)

片段着色器

片段着色器的输出是vec4的颜色变量,如果你没有在片段着色器在中设置输出变量的话,OpenGL就会把你的物体渲染成黑色.

现在我们准备使用一个着色器向另外一个着色器进行传输数据。在发送方声明一个类型的输出和输出变量,然后在接收方声明一个相同的类型的,相同名字的输入变量。这样两个就可以协同工作了。

顶点着色器的代码:

#version 330 core
// 位置变量的属性位置值为0
// 因为现在顶点数组里面只有顶点的位置信息,所以定义这么一个就行
layout (location = 0) in vec3 aPos;

out vec4 vertexColor; // 为片段着色器指定一个颜色输出


void main()
{
    gl_Position = vec4(aPos,1.0);
    // 把输出的颜色变量赋值为暗红色
    veetexColor = vec4(0.5,0.0,0.0,0.0);
}

片段着色器的代码:

#version 300 core

// 此时的输入变量就是顶点着色器传的输出变量
in  vec4 vertexColor;
out vec4 ForgeColor;

void main()
{
    ForgeColor = vertexColor;
}

Uniform

Uniform和顶点属性有所不同,Uniform是cpu向gpu传送数据的一种格式,Uniform定义的变量是全局的,这就意味着定义好这个变量之后,在任何着色器的任何阶段都可以去访问这个变量,而且对于每一个着色器片段都是独一无二的,也就是同名的Uniform变量只能定义一次 。

但当你把Uniform定义好之后,Uniform会一直保存他的数据,直至你去更新或者重置他,因为 Uniform是全局的,所以他的生命周期和整个程序的声明周期是一样的。

像下面这样,我们在片段着色器中声明了一个uniform变量,那么他在全局都是可用的,此时就不需要通过顶点着色器作为中介了。

Tip:如果你在GLSL中定义了一个Uniform变量,但是没有使用它,那么编译器会默认的将他移除,导致编译好的版本不会有它,可能会引起一些麻烦,但是文档没有说什么麻烦,注意就ok了。

#version 300 core
out vec4 OutColor;


uniform vec4 ForgeColor;

void main()
{
    OutColor = ForgrColor;
}

此时我们怎么在代码中查找对应Uniform的值以及设置他呢?

// 我们使用指令获取运行的时间:s
float timevalue = glfwGetTime();
// 使用sin函数,使得这个值在1.0到0.0之间变化
float greenValue = (sin(timeValue) / 2.0f) + 0.5f;
// 我们使用指令获取Unifo
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值