GLSL着色器

着色器语言是一种叫GLSL的类C语言。着色器的开头总是要声明版本,接着是输入和输出变量、uniform和main函数。每个着色器的入口点都是main函数,在这个函数中我们处理所有的输入变量,并将结果输出到输出变量中。

当我们特别谈论到顶点着色器的时候,每个输入变量也叫顶点属性(Vertex Attribute)。

1 数据类型

GLSL中包含C等其它语言大部分的默认基础数据类型:int,float,double,uint,bool,vector和Matrix。

每个着色器使用这两个关键字设定输入和输出,只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下去。但在顶点和片段着色器中会有点不同。

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

顶点着色器需要为它的输入提供一个额外的layout标识,这样我们才能把它链接到顶点数据。

顶点着色器:

#version 330 core

layout (location = 0

in vec3 aPos; // 位置变量的属性位置值为0 

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

void main() {

gl_Position = vec4(aPos, 1.0); // 注意我们如何把一个vec3作为vec4的构造器的参数 

vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 把输出变量设置为暗红色

}

片段着色器,它需要一个vec4颜色输出变量,因为片段着色器需要生成一个最终输出的颜色。如果你在片段着色器没有定义输出颜色,OpenGL会把你的物体渲染为黑色(或白色)。

片段着色器:

#version 330 core

out vec4 FragColor; 

in vec4 vertexColor; // 从顶点着色器传来的输入变量(名称相同、类型相同) void main()

FragColor = vertexColor; 

}

Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。

#version 330 core

out vec4 FragColor; 

uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量

void main()

FragColor = ourColor; 

}

当我们得到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,ES知识点)