假设我在任何两个GLSL着色器阶段(例如顶点和片段阶段)之间有一个变量变量,声明为vec4:
in/out/varying vec4 texCoord;
Run Code Online (Sandbox Code Playgroud)
如果我只在两个着色器中使用该变量的一部分(例如,通过调配)会发生什么,即我只在顶点着色器中写入其中的一部分并且只从片段着色器中的相同部分读取?
// vertex shader
texCoord.st = ...
// fragment shader
... = texture2D(..., texCoord.st);
Run Code Online (Sandbox Code Playgroud)
是否保证(即通过规范)始终产生合理的结果?这样做似乎是合理的,但是我并不太熟悉GLSL语言律师的复杂性,也不知道编译器/链接器是否因为它不是解释为"不完整".完全写入前一阶段.我敢肯定的价值texCoord.pq总会被不确定,但不会影响的有效性texCoord.st过或不全部变系统在纯组件级操作?
我乍看之下在GLSL规范中没有发现任何相关的结果,我希望根据实际规范或任何其他"官方"保证得到答案,而不是它应该在合理的硬件上工作的陈述(当然除非情况下简单地是未指定或实现定义).我也对整个GLSL历史中可能发生的任何变化感兴趣,包括一直回到它的设备,gl_TexCoord[]以及旧的GLSL 1.10中已弃用的内置变量变量.
我试图证明你的代码会很好,按照规范。但是,我不确定您是否会觉得我的推理 100% 令人信服,因为我认为规范对此似乎有些不精确。我将参考OpenGL 4.5核心配置规范和OpenGL着色语言4.50规范。
关于输入和输出变量,GLSL 规范在第 4.3.4 节中建立了以下内容
着色器输入变量是用存储限定符声明的
in。它们形成 OpenGL 管道的前几个阶段和声明着色器之间的输入接口。[...]上一个管道阶段的值在着色器执行开始时被复制到输入变量中。
和 4.3.6 分别:
着色器输出变量是通过存储限定符使用 storage qualifier 来声明的
out。它们形成声明着色器和 OpenGL 管道后续阶段之间的输出接口。[...] 在着色器执行期间,它们将表现为正常的非限定全局变量。它们的值在着色器退出时复制到后续管道阶段。只需要写入后续管道阶段读取的输出变量;允许有多余的输出变量声明。
第 5.8 节“分配”规定
在写入(或初始化)变量之前读取变量是合法的,但该值是未定义的。
由于向量的赋值.st将写入子向量,因此我们可以确定该变量将在着色器调用结束时包含两个已初始化的组件和两个未初始化的组件,并且整个向量将被复制到输出。
GL 规范第 11.1.2.1 节规定:
如果输出变量直接传递到导致光栅化的顶点处理阶段,则所有输出的值预计将在正在渲染的图元上进行插值,除非平面着色。否则,所有输出的值都由基元组装阶段收集,并在收集到一个基元的足够数据后传递到后续管道阶段。
“所有输出的值”由着色器确定,尽管某些组件具有未定义的值,但它们仍然具有值,并且这里不存在未定义或实现定义的行为。线和多边形基元的插值公式(第 14.5.1 节和第 14.6.1 节)也不会在组件之间混合,因此任何定义的组件值都将导致插值基准中的定义值。
第 11.1.2.1 节还包含有关顶点着色器输出的声明:
链接程序时,顶点着色器写入的任何输出的所有组件都将计入此限制。如果程序的顶点着色器写入的值超过了
MAX_VERTEX_OUTPUT_COMPONENTS组件输出的值,则可能无法链接,除非依赖于设备的优化能够使程序适合可用的硬件资源。
请注意,这种语言意味着vec4一旦写入单个组件,a 的全部 4 个组件就会被计入限制。
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |