前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >20.opengl高级-高级GLSL

20.opengl高级-高级GLSL

作者头像
公号sumsmile
发布2020-07-14 15:43:08
9830
发布2020-07-14 15:43:08
举报
这一章编程实践的内容不多,主要是glsl高级的语言特征。原教程写的很好了。learnopengl-高级glsl

这一节代码实践不多,阅读一遍,重在理解,做个笔记,加强记忆。

一、GLSL内建变量
1. 顶点着色器变量
  • gl_PointSize 设置顶点大小,默认禁用修改,DEMO:
代码语言:javascript
复制
// 主程序
glEnable(GL_PROGRAM_POINT_SIZE);

//着色器
void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);    
    gl_PointSize = gl_Position.z;    
}
  • gl_VertexID,基本没什么用,可读不可写,存储了正在绘制顶点的当前ID
2. 片段着色器变量
  • gl_FragCoord,x和y分量是片段的窗口控件坐标,原点在左下角,可以通过gl_FragCoord分量对输出颜色做些特殊处理,DEMO:
代码语言:javascript
复制
void main()
{             
    if(gl_FragCoord.x < 400)
        FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    else
        FragColor = vec4(0.0, 1.0, 0.0, 1.0);        
}

gl_FragCoord使用

  • gl_FrontFacing,判断正向还是背向,和面剔除有相同的功效,demo:
代码语言:javascript
复制
// 根据前脸还是后脸输出不同的纹理
#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D frontTexture;
uniform sampler2D backTexture;

void main()
{             
    if(gl_FrontFacing)
        FragColor = texture(frontTexture, TexCoords);
    else
        FragColor = texture(backTexture, TexCoords);
}

gl_FrontFacing使用

  • gl_FragDepth,这个稍微复杂点,可以用来修改片段的Z坐标,即深度值,如果没有设置gl_FragDepth,默认的回取gl_FragCoord.z。

gl_FragDepth有个缺陷,会导致提前深度测试冲突禁用,原理很好理解,因为只要到真正片段着色器运行才知道实际的深度值,提前深度测试没有意义。从4.2版本开始有个折中的方案,定义gl_FragDepth变量的规则,提供给提前深度测试参考,做个粗略的评估

代码语言:javascript
复制
layout (depth_<condition>) out float gl_FragDepth;

condition的值

demo:

代码语言:javascript
复制
#version 420 core // 注意GLSL的版本!
out vec4 FragColor;
layout (depth_greater) out float gl_FragDepth;

void main()
{             
    FragColor = vec4(1.0);
    gl_FragDepth = gl_FragCoord.z + 0.1;
}  
二、接口块

类似c语言中的struct,java中的类,不过多赘述,上代码,一看就明白,注意in和out的定义

代码语言:javascript
复制
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoords;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out VS_OUT
{
    vec2 TexCoords;
} vs_out;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);    
    vs_out.TexCoords = aTexCoords;
}  
三、Uniform缓冲对象

主要讲Uniform块,稍微复杂了点,可以简单理解为类的静态变量,所有类对象可以共享,在opengl特殊的编程环境下整的略复杂。重点是理解内存对齐的策略和绑定的关系。

1. 内存绑定关系,不同的shader可以绑定到相同的uniform缓冲对象上

内存绑定关系

分三步,创建uniform缓冲对象-->绑定shader对应uniform 字段到绑定点-->uniform缓冲对象绑定到相同的绑定点。关键代码:

代码语言:javascript
复制
// 生成uniform 缓冲对象
unsigned int uboExampleBlock;
glGenBuffers(1, &uboExampleBlock);
glBindBuffer(GL_UNIFORM_BUFFER, uboExampleBlock);
glBufferData(GL_UNIFORM_BUFFER, 152, NULL, GL_STATIC_DRAW); // 分配152字节的内存
glBindBuffer(GL_UNIFORM_BUFFER, 0);
代码语言:javascript
复制
// 将shader中的uniform字段绑定到相同的“绑定点”
unsigned int lights_index = glGetUniformBlockIndex(shaderA.ID, "Lights");   
glUniformBlockBinding(shaderA.ID, lights_index, 2);
代码语言:javascript
复制
// 有两种方式,第二种稍微灵活点,可以支持更多的复用和拓展场景
glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboExampleBlock); 
// 或
glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
2. 理解Uniform块的每个成员的对齐偏移量,理解下面这段代码就可以了。
代码语言:javascript
复制
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
}; 
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 这一章编程实践的内容不多,主要是glsl高级的语言特征。原教程写的很好了。learnopengl-高级glsl
  • 一、GLSL内建变量
    • 1. 顶点着色器变量
      • 2. 片段着色器变量
      • 二、接口块
      • 三、Uniform缓冲对象
        • 1. 内存绑定关系,不同的shader可以绑定到相同的uniform缓冲对象上
          • 2. 理解Uniform块的每个成员的对齐偏移量,理解下面这段代码就可以了。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档