《两个礼拜入门opengl -Day5》 着色器

本文介绍了GPU着色器的概念,着色器是运行在GPU上用于图形渲染的小程序,通常使用GLSL语言编写。着色器之间通过输入和输出变量传递数据,统一变量(uniform)允许在程序运行时动态改变颜色等属性。文章通过顶点着色器和片段着色器的示例,展示了如何处理颜色数据,并讨论了如何通过location定位数据源。此外,还提及了将颜色数据直接嵌入顶点数据中进行处理的方法。
摘要由CSDN通过智能技术生成
着色器
  • 着色器(Shader)是运行在GPU上的小程序
  • 这些小程序为图形渲染管线的某个特定部分而运行。
  • 从基本意义上来说,着色器只是一种把输入转化为输出的程序。
  • 着色器也是一种非常独立的程序,因为它们之间不能相互通信(应该是说只能单向数据传递,所以不算通·信?);
  • 它们之间唯一的沟通只有通过输入(in)和输出(out)
着色器语言
  • 着色器是使用一种叫GLSL的类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;
}
  • 不同的着色器之间。
    • 每个着色器都有输入和输出
    • 只要输出和下一个着色器输入匹配,就会自动传递
    • 当变量类型和名字都一样的时候,OpenGL就会把两个变量(前一个in, 后一个out)链接到一起,它们之间就能发送数据了(这是在链接程序对象时完成的)
    • 顶点着色器传递给片段着色器
//顶点着色器
#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); // 把输出变量设置为暗红色
}
//片段着色器
#version 330 core
out vec4 FragColor;

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

void main()
{
    FragColor = vertexColor;
}
Uniform (让硬编码着色器内部变量可变)

为片段着色器指定一个颜色输出,使用了out vec4 vertexColor变量;
并且, vertexColor = vec4(0.5, 0.0, .0., 1.0) 指定颜色,那肯定也存在在程序运行过程中动态改变这个变量的值的方式。

  • uniform vec4 ourColor;
    • uniform 关键字,声明变量ourColor为全局
      全局变量就可以通过OpenGL提供的函数进行值的变更了。
#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");
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
设置颜色的第二种方式
  • 颜色数据放进顶点一起
float vertices[] = {
    // 位置              // 颜色
     0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   // 右下
    -0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   // 左下
     0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    // 顶部
};
  • 设置数据解析方式
// 位置属性 glVertexAttribPointer参数1 就是location (= 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// 颜色属性 glVertexAttribPointer参数1 就是location (= 1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
glEnableVertexAttribArray(1);
  • 告诉着色器,数据来源处理方式
//顶点着色器预读取数据
#version 330 core
layout (location = 0) in vec3 aPos;   // 位置变量的属性位置值为 0 
layout (location = 1) in vec3 aColor; // 颜色变量的属性位置值为 1

out vec3 ourColor; // 向片段着色器输出一个颜色

void main()
{
		//这个gl_Position 就是坐标,而且应该是个OpenGL变量
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor; // 将ourColor设置为我们从顶点数据那里得到的输入颜色
}

//片段着色器计算颜色
#version 330 core
out vec4 FragColor;  
in vec3 ourColor;

void main()
{
    FragColor = vec4(ourColor, 1.0);
}
location (location = x) 这个是什么意思
  • 查询属性位置值(Location)
  • 这个在数据解析的时候作为函数glVertexAttribPointer(),的第一个参数,可以用来区分数据里面,哪些是点的数据,哪些是颜色的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值