GLSL Opengl着色器着色语言

目录

1,典型结构,输入输出

GLSL中包含 C 等其他语言大部分的默认基础数据类型

int , float ,double ,uint ,和 bool。

.

GLSL 有两种容器类型:

  • 向量(Vector)

    向量各类型解释(n 代表分量数量,可取 2、3、4):

  • vecn:单精度浮点向量(最常用,如 vec2/vec3/vec4)

  • bvecn:布尔向量(bvec2/bvec3/bvec4,元素是 bool)

  • ivecn:有符号整数向量(ivec2/ivec3/ivec4)

  • uvecn:无符号整数向量(uvec2/uvec3/uvec4)

  • dvecn:双精度浮点向量(dvec2/dvec3/dvec4)

javascript 复制代码
vec2  vect = vec2(0.5,0.7);
vec4  result = vec4(vect,0.0,0.0);
vec4  otherResult = vec4(result.xyz,1.0);

【示例】 :

//顶点着色器

javascript 复制代码
#version 330 core
layout(location = 0) in vec3 aPos;
out  vec4  vertexColor;
void main(){
	gl_Position = vec4(aPos,1.0);
	vertexColor = vec4(0.5,0.0,0.0,1.0);
}

//片段着色器

javascript 复制代码
#version 330 core
out  vec4  FragColor;
in vec4 vertexColor;
void main(){
	FragColor = vertexColor;
}

2,Layout

顶点着色器接收的是一种特殊形式的输入,否则就会效率低下。

从顶点数据中直接接收输入。为了定义顶点数据该如何管理,可以使用 loaction 指定输入变量。这样就可以在 CPU 上配置顶点属性。

例如:layout (location = 0) , layout 这个标识能把它链接到顶点数据。

【示例】:

javascript 复制代码
//顶点坐标 + 顶点颜色(每个顶点 6 个 float:前 3 个位置,后 3 个颜色)
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  // 顶部:蓝
};

const char* vertexShaderSource = "#version 330 core\n"
                                 "layout (location = 0) in vec3 aPos;\n"
                                 "layout (location = 1) in vec3 aColor;\n"
                                 "out vec3 ourColor;\n"
                                 "void main()\n"
                                 "{\n"
                                 "gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
                                 "ourColor = aColor;\n"
                                 "}\0";

const char* fragmentShaderSource = "#version 330 core\n"
                                   "in vec3 ourColor;\n"
                                   "out vec4 FragColor;\n"
                                   "void main()\n"
                                   "{\n"
                                   "FragColor = vec4(ourColor, 1.0f);\n"
                                   "}\0";

unsigned int shaderProgram;

void MyOpenGLWidget::initializeGL()
{
    // 初始化当前 OpenGL 上下文的函数指针
    // QOpenGLFunctions_3_3_Core::initializeOpenGLFunctions()
    // 如果上下文不是 3.3 Core,会返回 false
    bool ok = initializeOpenGLFunctions();
    qDebug() << "initializeOpenGLFunctions:" << ok;
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    // VAO:保存顶点属性配置信息(怎么解析VBO里的数据)
    // VBO:GPU显存缓冲区,用来存放顶点原始坐标数据


    glGenVertexArrays(1, &VAO);         // 生成1个顶点数组对象VAO,把返回的ID存入变量VAO
    glGenBuffers(1, &VBO);              // 生成1个顶点缓冲对象VBO,把返回的ID存入变量VBO
    glBindVertexArray(VAO);             // 绑定VAO到当前上下文,之后所有顶点属性配置都会记录进这个VAO
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // 绑定VBO到当前上下文,之后所有顶点属性配置都会记录进这个VBO


    //将数据传入显存
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 把顶点数据复制到当前绑定到的 VBO
    //告知显卡如何解析:位置属性 location=0,从第 0 个 float 开始,步长 6 个 float
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
    //开启位置属性
    glEnableVertexAttribArray(0);
    //告知显卡如何解析:颜色属性 location=1,从第 3 个 float 开始,步长 6 个 float
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
    //开启颜色属性
    glEnableVertexAttribArray(1);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    //编译顶点着色器
    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    //编译片段着色器
    unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    //link shaders
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // 链接成功后可以删除着色器对象
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

查看上面的代码。

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);

这段代码表示,将 vertices\[\] 数组,划分为多个顶点,每个顶点有 6 个 float

这几个顶点分别是 -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 。

每个顶点从 第 0 个开始,数三个,摘取出来做成一个集合,并将这个集合定义为 index = 0 。

.

.

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));

这个和上面不同的是,摘取每个顶点从 第 3 个开始,数三个,摘取出来做成一个集合,并将这个集合定义为 index = 1

两个集合就是

复制代码
-0.5f, -0.5f, 0.0f,  
0.5f, -0.5f, 0.0f, 
0.0f,  0.5f, 0.0f,  

1.0f, 0.0f, 0.0f, 
0.0f, 1.0f, 0.0f, 
0.0f, 0.0f, 1.0f 
javascript 复制代码
const char* vertexShaderSource = "#version 330 core\n"
                                 "layout (location = 0) in vec3 aPos;\n"
                                 "layout (location = 1) in vec3 aColor;\n"
                                 "out vec3 ourColor;\n"
                                 "void main()\n"
                                 "{\n"
                                 "gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
                                 "ourColor = aColor;\n"
                                 "}\0";

const char* fragmentShaderSource = "#version 330 core\n"
                                   "in vec3 ourColor;\n"
                                   "out vec4 FragColor;\n"
                                   "void main()\n"
                                   "{\n"
                                   "FragColor = vec4(ourColor, 1.0f);\n"
                                   "}\0";

上面这段 GLSL 代码中

layout (location = 0) in vec3 aPos;

layout (location = 1) in vec3 aColor;

这段代码表示 aPos 向量映射 index = 0 的顶点数据。

aColor 向量映射 index = 1 的顶点数据。

"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"

这段代码就表示 index = 0 也就是 aPos 数据定性为位置数据。

相关推荐
Hello_Pyhx3 天前
SCSKiller v1.3.2 使用流程:从着色器预编译到检查缓存状态
缓存·着色器
ly_Enhs12 天前
从曲面细分到计算着色器:我的 Vulkan 实验记录
着色器·vulkan图形渲染c/c++
刻BITTER14 天前
LocalLow 乱码文件排查 Intel INSC着色器缓存文件
缓存·哈希算法·着色器
茉莉玫瑰花茶1 个月前
OpenGL [ GLSL 着色器基础 ]
着色器
李小白杂货铺1 个月前
“正在编译着色器“ 耗时原理解析
着色器·技术原理·技术解析·原理解析·编译着色器·正在编译着色器·耗时原理
爱上网的小舟1 个月前
着色器缓存大小设置多少合适?N卡A卡缓存路径与清理方法
缓存·着色器
灵境(虚幻知音)2 个月前
WebGL 不支持>1px的线绘制,那 Cesium 的带宽度的线是怎么画出来的?
webgl·cesium·着色器
破竹152 个月前
OpenGL ES调试汇总
图形渲染·着色器
小小数媒成员2 个月前
合并阶段和计算着色器【图文解释】
着色器