openGL之API学习(四十七)layout作用详解_glsl layout-程序员宅基地

技术标签: 图形学  着色器  openGL之API学习  opengl  GLSL  

原文在https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)

GLSL语言规范中也有对此的详细说明https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf

这里大致翻译如下:

布局限定符(GLSL除了这个限定符,还有很多其它限定符,比如存储限定符、内存限定符、插值限定符等,具体参看https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)),基本语法为:

layout(qualifier1​, qualifier2​ = value, ...) variable definition

主要有以下用法:

1、用于着色器输入/输出变量接口布局

着色器的输入/输出变量就是着色器与显存或其它着色器通信的接口,通过layout可以指定这些输入/输出变量从哪去什么值/向哪输出什么值。

1.1、顶点着色器的属性索引

layout(location = attribute index) in vec3 position;

可以指定顶点着色器输入变量使用的顶点属性索引值,一般在glVertexAttribPointer中指定属性索引值。如果同时使用了glBindAttribLocation,那么这个layout优先。

如果输入变量占用了多个属性位置槽,那么将按照属性位置顺序依次分配,如

layout(location = 2) in vec3 values[4];

values将依次获取属性位置2,3,4,5处的值。

值得注意的是,输入和输出变量的位置索引并不冲突,比如

#version 440

layout(location = 0) in vec4 inWorldPosition;
layout(location = 1) in vec4 inNormal;
layout(location = 2) in vec2 inTexCoord;
layout(location = 3) in vec4 inTangent;
layout(location = 4) in vec4 inBiTangent;

layout(location = 0) out vec4 nu_outColor;

1.2、片段着色器的缓冲区输出

layout(location = output index) out vec4 outColor;

可以指定片段着色器输出变量输出到哪个索引缓冲区,和顶点着色器类似。如果同时使用了 glBindFragDataLocation,那么这个layout优先。

对于双重来源混合(dual source blending,带有两源参数的附加混合模式),使用如下句法:

layout(location = output index, index = dual output index) out vec4 outColor;

如果同时使用了glBindFragDataLocationIndexed,那么这个layout优先。

1.3、着色器程序间的变量传递

这个特性是从opengl4.1开始有的。

比如,顶点着色器是这样的

layout(location = 0) out vec4 color;
layout(location = 1) out vec2 texCoord;
layout(location = 2) out vec3 normal;

其它着色器可以是这样的,通过相同的位置索引来获取顶点着色器中的变量,这里变量的名字和类型可以与顶点着色器中不同。

layout(location = 0) in vec4 diffuseAlbedo;
layout(location = 1) in vec2 texCoord
layout(location = 2) in vec3 cameraSpaceNormal;

注意1:有些变量会占用多个位置索引,比如结构体和数组,他们的位置索引会按照顺序占用,其它变量的位置索引不能与他们的位置索引重叠,否则在编译链接时会报错。

注意2:不同的变量类型占用的位置索引数是不同的,对于标量和非double型的向量(如vec3)而言,占用一个位置索引;double和dvec2占用一个位置索引;dvec3和dvec4占用2个位置索引;结构体根据它们的成员变量类型来确定占用的位置索引数量;数组根据它们的长度来确定占用的位置索引数目。如下例:

struct OutData
{
  vec3 data1;
  dvec4 data2;
  float val[3];
};
layout(location = 0) out vec3 vals[4];    // Consumes 4 locations
layout(location = 4) out OutData myOut;   // Consumes 6 locations. dvec4 uses 2, and `val[3]` uses 3 total
layout(location = 10) out vec2 texCoord;  // Consumes 1 location

注意3:可用的位置索引数是与硬件实现有关的,具体数量不可查询,至少是GL_MAX_VARYING_COMPONENTS的1/4。

1.4、块成员定位

这个特性是从opengl4.4开始有的。

块作为一个整体可以有一个位置索引,其内部成员从这个位置开始依次分配位置索引。

块中的成员也可以定义位置索引,这只有在块作为整体有位置索引或者块中的每一个成员都有位置索引的情况下才行。

块成员定义的位置索引会修改块为其分配的默认位置索引,并会修改该成员后面其它没有定义位置索引成员的位置索引,也就是从该成员的位置索引后顺序分配。

下面是一个例子:

layout(location = 0) out Block
{
  vec2 first;                        // Location 0.
  dvec4 second[3];                   // Location 1.
  vec4 third;                        // Location 7; dvec4 takes 2 each, and the prior one has 3 array members.
  layout(location = 10) vec2 fourth; // Location 10.
  dvec4 fifth;                       // Location 11. Starts from the most recent explicit location.
  layout(location = 8) dvec3 sixth;  // Location 8.
  vec3 seventh;                      // Location 10, overlaps with `fourth`, so causes an error.
};

1.5、用于定位到变量的组件

这个特性是从opengl4.4开始有的。

opengl的API默认所有变量是一组四元数的集合,比如mat2包含两个四元数(每个四元数的后两个组件没有使用),占用两个位置索引;vec4包含一个四元数,占用一个位置索引。

因此,对于某些变量而言,存在部分组件是未被使用的,这里的组件限定符将能使用这些未被使用的组件。

组件限定符指定了变量要使用的起始组件位置。如果从起始组件开始,变量占用的组件位置超出了4,这将是非法的,因此对于vec3而言,起始组件位置要么是0要么是1。

如果有两个变量占用同一个位置索引,那么他们所占用的组件不能重叠。比如不能将一个vec3和一个vec2分配在同一个位置索引上,但是可以将两个vec2分配在同一个位置索引上。

数组可以基于组件限定符进行分配,它将会在数组占用的每一个位置索引上,按照组件限定进行分配。比如:

layout(location = 0) out vec2 arr1[5];
layout(location = 0, component = 2) out vec2 arr2[4]; //Different sizes are fine.
layout(location = 4, component = 2) out float val;    //A non-array takes the last two fields from location 4.

两个或多个变量共享同一个位置索引,需要满足以下条件:

(1)必须具有相同的基本数据类型。比如都是float,或都是int,但是不能一个是float,另一个是int。

(2)使用同样的插值限定符(参看https://www.khronos.org/opengl/wiki/Type_Qualifier_(GLSL)#Interpolation_qualifiers)。

组件限定符不能用于以下情况:

(1)matrix类型变量

(2)struct类型变量

(3)块类型变量(但是可以用于块成员变量)

(4)以上几种变量的数组

glVertexAttribPointer在给变量填充数据时,如果有些组件没有被填充到,将会填上默认值0(最后一个组件,也就是第四个会填上1)。

1.6、绑定点

这个特性是从opengl4.2开始有的。

用于初始化变量

layout(binding = 3) uniform sampler2D mainTexture;
layout(binding = 1, std140) uniform MainBlock
{
  vec3 data;
};

1.7、图像格式

这个特性是从opengl4.2开始有的。

1.8、原子计数存储

layout(binding = 0, offset = 12) uniform atomic_uint one;
layout(binding = 0) uniform atomic_uint two;
layout(binding = 0, offset = 4) uniform atomic_uint three;

layout(binding = 1) uniform atomic_uint four;
layout(binding = 1) uniform atomic_uint five;
layout(binding = 1, offset = 20) uniform atomic_uint six;
layout(binding = 0) uniform atomic_uint seven;

The offsets for these are as follows:

  • one: 12
  • two: 16 (12 + 4)
  • three: 4 (specified)
  • four: 0 (unused bindings offsets always start with a default of 0).
  • five: 4
  • six: 20
  • seven: 8 (the last value used for binding 0 was 4, so this one gets 8).

 

 

 

 

 

布局限定符有时用于为不同的着色器阶段定义各种选项。这些着色器阶段选项应用于着色器阶段的输入或输出。在这些定义中,变量定义variable definition将只是输入in或输出out,比如:

layout (triangles, equal_spacing, cw) in;

 

layout (vertices = 3) out;  
layout (triangles, equal_spacing, cw) in;  
layout(location=0)

这里使用了layout关键字。这个关键字用于一个具体变量前,用于显式标明该变量的一些布局属性,这里就是显式设定了该attribute变量的位置值(location)。
优点:
(1)、避免了getlocation的开销;
(2)、重定义了OpenGL和GLSL之间attribute变量属性的依赖。过去我们的OpenGL端必须首先要知道GLSL端某个attribute的名字,才能设置/获得其位置值,如今两者只需要location对应起来就可以完成绘制时顶点属性流的传递了

layout(location = 0),叫做布局限定符,目的是为了方便给变量提供数据,layout()的还有其他的选项,在这里location相当于设定了变量在着色器程序中的访问位置。

 

 

 

#version 330

layout (points) in;
layout (triangle_strip) out;
layout (max_vertices = 4) out;
  • 公告板技术的核心就在几何着色器了,我们分解开一步步来看。开始我们先使用‘layout’关键字声明一些全局缓冲器。我们要先告诉渲染管线输入来的参数结构是点列表,输出的是三角带,并且说明输出的顶点个数最多为4个。这些关键词也会提示图形驱动器从几何着色器输出顶点的最大个数,提前知道顶点个数上限可以给驱动器机会来优化几何着色器在某些特定情况下的动作。我们知道对于每一个输入的顶点要输出的是一个扩展的四边形,因此我们设置最大顶点数为4。

 

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hankern/article/details/89325452

智能推荐

jquery图片轮播带缩略图_jq带缩略图的呼吸轮播-程序员宅基地

文章浏览阅读618次。(1)html 标签:div class="lb_list"> span class="btn left_btn">span> div class="large_box"> ul> li> img src="images/img1.jpg" width="530" height="350"> _jq带缩略图的呼吸轮播

熊海cms渗透测试-程序员宅基地

文章浏览阅读1.8k次。熊海cms渗透测试_熊海cms

什么是软件测试-程序员宅基地

文章浏览阅读7k次,点赞2次,收藏32次。1.软件测试的定义在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。(1)规定的条件(2)目的:发现程序错误,衡量软件质量通俗定义:软件测试是一种实际输出与预期输出之间的审核或者比较过程。设计过程当中:预期结果<------>实际输出需求测试是保证实际输出与预期输出之间的审核或比较过程,及时发现软件Bug与缺陷,避免项目上线由于Bug给公司带来损失。2.软件开发模型瀑布模型、快速原型模型、螺旋模型(1)_什么是软件测试

不会写只会说是不是一种才啊_不会说只会写-程序员宅基地

文章浏览阅读307次。写代码没有耐心,何况自己水平又那么烂,只会空想着这要有什么功能,指点着,自己又不会,不知道别人是不是很讨厌我啊?看同学个个有了工作,自己还没有,望着工作要求而叹,什么都不会,只知道一点点。每次有个好的IDear,感觉上都会实现的,只是自己不会编程啊,要是手里有个团队就好了,这个功能XX去做,XXX你去做这个部分,看来我只是做狗头军师的料,不知道我这只千里马何人才能相中啊!!_不会说只会写

根据银行卡号码获取银行卡归属行以及logo图标_支付宝获取银行图标-程序员宅基地

文章浏览阅读1.2k次。转自:https://blog.csdn.net/qq_28268507/article/details/68941754之前做商城的时候遇到过根据银行卡号码获取银行归属地信息以及银行logo的需求,当初参考的是网上的一篇博客android根据银行卡卡号判断银行后来觉得数据不够权威或者数据信息不全,最近又发现了一个新的api接口,支付宝提供的根据银行卡号码获取银行卡归属地信息接口地址:..._支付宝获取银行图标

[前端网站源码]基于HTML5,DIV CSS实现的酒店运营与推广(静态网页设计)_酒店网页设计动态效果代码csdn-程序员宅基地

文章浏览阅读34次。该项目使用HTML5、CSS3、DIV开发的静态网站,是针对需要做前段网页设计相关毕设课设的同学,前段相关知识点老师都有讲过可以免费学习,以及怎么改项目中图片和文字都有相关教程,教同学们怎么将项目改成独一无二的一份,就算是零基础的同学也可以非常轻松搞定前段网页毕设课设项目,对于基础不好的同学是不错的选择。..._酒店网页设计动态效果代码csdn

随便推点

VO:简单的视觉里程计代码注释(代码可运行)_视觉里程计开源代码-程序员宅基地

文章浏览阅读5.5k次,点赞6次,收藏65次。走完SLAM十四讲前端之后,代码都已经注释完,但还是感觉有点迷茫,所以专门参考冯兵的博客,实现简单的视觉里程计。收获是又重新认识到了C++基础的薄弱,决定之后的晚上要刷牛客题。不过就SLAM前端而言这部分基本可以理解代码了,这篇对VO代码进行注释。基本过程:1、获取图像2、对图像进行处理3、通过FAST算法对图像进行特征检测,通过KLT光流法跟踪图像的特征,如果跟踪的特征有所丢失,特..._视觉里程计开源代码

@mapperscan 匹配一个或多个包_一起做ROSDEMO:基于find_object_2d的目标模板匹配识别...-程序员宅基地

文章浏览阅读1k次。转载文章标注:本文转自CSDN,作者:跃动的风原文链接:https://blog.csdn.net/qq_23670601/article/details/93663974我们希望机器人能够更加智能一点,抓住我们想要的任何东西,而不是通过贴标签(ar_makrer)或者简单的颜色过滤分割(比如固定识别某纯色物体)来进行目标物体的识别。所以我们打算采用其他的方法来进行目标的识别识别。目前我..._@mapperscan后缀匹配

react 项目使用highcharts滚动条来展示数据_highstock react-程序员宅基地

文章浏览阅读1.6k次。在使用图表画图的时候总会,由于展示的面积有限,无法将数据完全展示到图表中,这个时候就可能考虑使用滚动条来滑动展示数据。 讲一下过程,我首先找资源,找到了这个,发现很适合我的需求。 highcharts很有意思,他单独的为react创立了一个包叫react-highcharts,如果你引入这个包,并且你想使用滚动条来实现,要引入: var ReactHighstock = require(..._highstock react

04.SSM框架整合-Mybatis映射文件的存放路径注意事项_ssm映射资源文件夹-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏13次。一: Mapper接口与映射文件在同一目录下方式一:同一目录,位置不同在Spring的核心配置文件中,配置了在指定包下批量扫描mapper映射文件: <!-- 批量扫描mapper包,创建代理对象 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.lg.mapper"/>_ssm映射资源文件夹

loadrunner运行场景时,常见错误及解决方法_loadrunner报错link调试-程序员宅基地

文章浏览阅读1.8k次。目录1、Error -27727:.32、Error -27728:.33、Error -27791:.34、Error -27492:.45、Error -27498:.46、Error -26612:.47、Error -27496:.58、Error -27995:.59、Error -27279:...510、Error -27796.5..._loadrunner报错link调试

计算机维修知识论文,计算机维修论文2000字-程序员宅基地

文章浏览阅读210次。如何保养和维护好一台计算机,最大限度地延长计算机的使用寿命,这是我们非常关心和经常面临的问题。下面是答.案.网 ZQNF.Com小编给大家推荐的计算机维修论文2000字,希望大家喜欢!计算机维修论文2000字篇一  《浅谈计算机硬件的维护维修》【摘要】计算机维护分硬件维护和软件维护两部分,硬件维护主要是指计算机上主板、显卡、处理器、硬盘、显示器等硬件设备的维护。【关键词】计算机硬件;故障;维护维修..._基于知识库的计算机硬件维修服务系统论文