一、在GLSL中使用Uniform Block
在GLSL渲染语言中,我们经常采用缓冲区来存储Uniform型的Block。
比如我们需要绘制下面这样的效果:
在这里我们绘制了一个圆,圆内部颜色和外部颜色不同,而且边缘部分,颜色是平滑过渡的。
我们这样来实现这一效果:
首先定义一个内径和外径。然后给这个正方形分配纹理坐标,然后通过纹理坐标离(0.5,0.5)的距离与内径和外径的关系来控制当前像素点的颜色。
我们要在Shader中提供这样的一些信息:圆的内径及外径、内部颜色和外部颜色。采用Block来将这些信息封装在一起是合适的选择。
采用Block的原因是:
如果你的程序中包含了多个着色器,而且这些着色器使用了相同的Uniform变量,你就不得不为每个着色器分别管理这些变量。Uniform变量的location是在程序链接的时候产生的,因此Uniform变量的location会随着着色器的不同而发生变化。因此,这些Uniform变量的数据必须重新产生,然后应用到新的location上。
而Uniform Block正是为了使在着色器间共享Uniform数据变得更加容易而设计的。有了Uniform Block,我们可以创建一个缓冲区对象来存储这些Uniform变量的值,然后将缓冲区对象绑定到Uniform Block。当着色器程序改变的时候,只需要将同样的缓冲区对重新绑定到在新的着色器中与之相关的Block即可。
Uniform Block的定义和C/C++中的struct很类似。在本文的例子中我们需要定义的Uniform Block为:
方法一:
或者是
方法二:
这样我们就定义了一个名为BlobSettings的Block,包含了4个uniform 变量。
在方法一中,Block中的变量依然是全局域的一部分,取用的时候不用Block名。
而在方法二中,Block中的变量则是在Blob名字域中,取用的时候需要加上Block名。
这两种方法在使用上有少许差别。
用来存储uniform数据的缓冲区对象称作UBO(uniform buffer object)。它只是一个绑定到特定location的缓冲区对象。
注意下面的代码是基于上述定义Block的方法二的基础之上的。
下面贴出完整的GLSL渲染器代码:
basic_block.vert:
basic_block.frag:
UBO的设置:
二、在Uniform Block中使用布局标识符std140
1、std140的使用
由于UBO中数据的布局和具体实现有关(内存对齐等等),因此我们需要在设置其值的时候查询偏移量。然后,我们可以使用标准布局std40来避免这一操作。这可以通过在定义Uniform Block的时候使用布局标识符来实现:
layout( std140 ) uniform BlobSettings {
…
};
2、std140详解
std40布局标识符要求GLSL着色器依据一组规则来组织Uniform Block中的变量,这样使得我们能够预先计算出其中的变量的偏移量。
变量的偏移量是根据起始偏移量和在其之前的变量的大小累积计算得到的。第一个成员变量的起始偏移量总是0.
std40的布局规则
变量类型
|
变量大小/偏移量
|
标量数据类型(bool,int,uint,float)
|
基于基本机器类型的标量值大小
(例如,sizeof(GLfloat))
|
二元向量(bvec2,ivec2,uvec2,vec2)
|
标量类型大小的两倍
|
三元向量(bvec3,ivec3,uvec3,vec3)
|
标量类型大小的四倍
|
三元向量(bvec4,ivec4,uvec4,vec4)
|
标量类型大小的四倍
|
标量的数组或向量
|
数组中每个元素大小是基本类型的大小,偏移量是其索引值(从0开始)与元素大小的乘积。整个数组必须是vec4类型的大小的整数倍(不足将在尾部填充)。
|
一个或多个C列R行列主序矩阵组成的数组
|
以C个向量(每个有R个元素)组成的数组形式存储。会像其他数组一样填充。
如果变量是M个列主序矩阵的数组,那么它的存储形式是:M*C个向量(每个有R个元素)组成的数组。
|
一个或多个R行C列的行主序矩阵组成的数组
|
以R个向量(每个有C个元素)组成的数组。默认像其他数组一样填充。
如果变量是M个行主序矩阵组成的数组,则存储形式是M*R个向量(每个有C个元素)组成的数组。
|
单个结构体或多个结构体组成的数组
|
单个结构体成员的偏移量和大小可以由前面的规则计算出。结构大小总是vec4大小的整数倍(不足在后面补齐)。
由结构组成的数组,偏移量的计算需要考虑单个结构的对齐和补齐。结构的成员偏移量由前面的规则计算出。
|
分享到:
相关推荐
内容包含了glm glut 等库,用vs2008 基于OpenGL 4.0 ,可以直接运行,包含所有源码,里面含有很多使用性技巧
opengl编程入门,glsl语言的hello world,着色器,glsl语言简介
opengl编程入门,glsl语言的hello world,着色器,glsl语言简介
opengl_learning--C-GLSL-C++.cmake-2020m6
If you are an OpenGL programmer looking to use the modern features of GLSL 4.0 to create real-time, three-dimensional graphics, then this book is for you. Familiarity with OpenGL programming, along ...
非常不好找的 opengl 4.0 shading language cookbook 源码 GLSL COOKBOOK 源码 opengl 4.0 shading language cookbook 源码 GLSL COOKBOOK 源码 opengl 4.0 shading language cookbook 源码 GLSL COOKBOOK 源码 ...
用于webpack的glsl着色器加载器,包括对嵌套导入的支持,从而允许在更复杂的着色器实现中智能地重用代码。 着色器以字符串形式返回。 安装 npm install --save-dev webpack-glsl-loader 用法 与require 注意:如中...
前端开源库-glsl-transitionsglsl transitions,在glsl.io上创建的glsl transitions集合。
opengl编程入门,glsl语言的hello world,你好三角形,绘制一个三角形
GLSL小巧的调试工具,可以代替glDebugger。我自己编译好的,免去自己编译的麻烦
:gem_stone: vscode-glsl-canvas 通过提供Show glslCanvas命令,该扩展程序可在VSCode中打开GLSL着色器的实时WebGL预览。 它使用的改进和改进版本,版本来自 javascript库和由制造的 。 现在支持WebGL2。 只需在文件...
前端开源库-glsl-transition-fadeglsl transition fade,简单的fade glsl transition对象
glsl-atmosphere, 使用瑞利和散射渲染天空颜色 glsl大气使用瑞利和散射渲染天空颜色。 演示工具安装npm install glsl-atmosphere示例 Javascriptvar quad = Geometry(gl). attr('a
这是一个简单的GLSL着色程序的完整代码,GLSL需要显卡支持OpenGL版本2.0以上
GLSL-Debugger 对GLSL语言的调试工具
这源码是OpenGL4.6着色语言精通_第三版的全部源代码,利用GLSL 4.6和C++ 17构建高质量实时三维图形。主要重点是OpenGL着色语言(GLSL)。因此,我们不花时间讨论用OpenGL编程的基础。在这个我认为读者对在OpenGL中...
autocomplete-glsl-源码.rar
OpenGL快速查找手册-OpenGL-ES-2_0-Reference-card