LearnOpenGL之高级GLSL

高级GLSL


一、GLSL的内建变量

内建变量均以"gl_"为前缀

1.顶点着色器的内建变量

(1)gl_PointSize

用来改变顶点,点的大小,通常用于粒子系统

# 记得开启
glEnable(GL_PROGRAM_POINT_SIZE);

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);    
    gl_PointSize = gl_Position.z;    
}

(2)gl_VertexID

每个顶点的ID
如果使用glDrawElements绘制,则是当前顶点索引
如果使用glDrawArrays绘制,则是当前绘制顶点数的计数

2.片段着色器的内建变量

(1)gl_FragCoord

gl_FragCoord.xy代表每个片段的窗口坐标,原点在左下角
例如:gl_FragCoord的x和y分量是片段的窗口空间(Window-space)坐标,其原点为窗口的左下角。我们已经使用glViewport设定了一个800x600的窗口了,所以片段窗口空间坐标的x分量将在0到800之间,y分量在0到600之间。

gl_FragCoord.z代表了只可以读取的像素深度

(2)gl_FrontFacing

是一个bool变量,代表了面片的正反方向

(3)gl_FragDepth

代表了可以写的像素深度
从OpenGL 4.2起,我们仍可以对两者进行一定的调和,在片段着色器的顶部使用深度条件(Depth Condition)重新声明gl_FragDepth变量:

layout (depth_<condition>) out float gl_FragDepth;

二、接口块

用于着色器之间批量数据通信

形式为:块名(VS_OUT)要一样
顶点着色器:

out VS_OUT
{
    vec2 TexCoords;
} vs_out;

片段着色器

in VS_OUT
{
    vec2 TexCoords;
} fs_in;

三、Uniform缓冲对象

用于批量Uniform变量传递到着色器

1.在着色器形式为uniform块:

layout (std140) uniform Matrices
{
    mat4 projection;
    mat4 view;
};

2.Uniform块布局有三种:

共享布局(shared):默认的,内存布局在每个声明了这个Uniform块的程序中是不一致的,共享
std140布局:内存布局在每个声明了这个Uniform块的程序中是一致的,共享
紧凑布局(packed):省内存、但非共享

3.std140布局规则

layout (std140) uniform ExampleBlock
{
                     // 基准对齐量       // 对齐偏移量
    float value;     // 4               // 0 
    vec3 vector;     // 16              // 16  (必须是16的倍数,所以 4->16)
    mat4 matrix;     // 16              // 32  (列 0)
                     // 16              // 48  (列 1)
                     // 16              // 64  (列 2)
                     // 16              // 80  (列 3)
    float values[3]; // 16              // 96  (values[0])
                     // 16              // 112 (values[1])
                     // 16              // 128 (values[2])
    bool boolean;    // 4               // 144
    int integer;     // 4               // 148
}; 

4.使用Uniform缓冲(以绑定投影和观察矩阵为例)

在这里插入图片描述

(1)定义每个着色器的Uniform块
layout (std140) uniform Matrices
{
    mat4 projection;
    mat4 view;
};
(2)每个着色器的Uniform块绑定到绑定点0
unsigned int uniformBlockIndexRed    = glGetUniformBlockIndex(shaderRed.ID, "Matrices");
unsigned int uniformBlockIndexGreen  = glGetUniformBlockIndex(shaderGreen.ID, "Matrices");
unsigned int uniformBlockIndexBlue   = glGetUniformBlockIndex(shaderBlue.ID, "Matrices");
unsigned int uniformBlockIndexYellow = glGetUniformBlockIndex(shaderYellow.ID, "Matrices");  

glUniformBlockBinding(shaderRed.ID,    uniformBlockIndexRed, 0);
glUniformBlockBinding(shaderGreen.ID,  uniformBlockIndexGreen, 0);
glUniformBlockBinding(shaderBlue.ID,   uniformBlockIndexBlue, 0);
glUniformBlockBinding(shaderYellow.ID, uniformBlockIndexYellow, 0);
(3)创建Uniform缓冲对象,并绑定到绑定点0
unsigned int uboMatrices
glGenBuffers(1, &uboMatrices);

glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));
(4)在绑定点0创建内存空间,并生成数据
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)width/(float)height, 0.1f, 100.0f);
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), glm::value_ptr(projection));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
glm::mat4 view = camera.GetViewMatrix();           
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), sizeof(glm::mat4), glm::value_ptr(view));
glBindBuffer(GL_UNIFORM_BUFFER, 0);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值