WebGL:在顶点着色器和片元着色器中绑定相同的uniform是否被禁止?

6
我正在使用Emscriten将OpenGL框架移植到JavaScript上。状态存储在一个统一的结构体中:
struct UniformState {
    ...
    mat4 modelviewprojection_matrix; 
    mat4 modelview_matrix;
    mat3 normal_matrix; 
    mat4 texture_matrix;
    ...
};

我希望在顶点着色器和片元着色器中都能访问以下内容:

uniform UniformState GLUP;

当我这样做时,在链接时会出现错误:

Uniform `GLUP`is not linkable between attached shaders

在顶点着色器和片元着色器中绑定相同的uniform是否被禁止?

(如果被禁止,那么显然我可以为每个着色器声明两个不同的uniform变量集,但我更希望只有一个,因为这样可以使代码更清晰/简单,这就是为什么我要问是否有特殊的方法可以实现它。)


这是我做这个已经很久了。我认为你可以从顶点着色器传递uniform到片段着色器。 - user3125280
请展示设置uniform、获取位置并将其发送到绘制调用的代码。似乎将其发送错误可能是问题所在。如果一切都失败了,您可以从顶点着色器输出uniform值以输入到片段着色器(varying var)。 - Dragan Okanovic
错误发生在着色器链接时,因此它不可能是由于提取统一变量位置和指定统一变量的方式引起的(这是在之后完成的)。 - BrunoLevy
3
顶点着色器和片段着色器可能会有不同的精度设置。请注意,着色器类型之间的默认精度是不同的。 - Reto Koradi
是的,它可以工作了。问题出在我在 FS 中使用了 mediump,将精度设置为 highp 可以解决这个问题。那么将 FS 设置为 highp 的后果是什么?它会降低移动设备的性能吗? - BrunoLevy
显示剩余2条评论
1个回答

5

看起来对我有效。

注意,如Reto所提到的,如果我不设置精度,我会得到链接错误。

"use strict";
var gl = document.createElement("canvas").getContext("webgl");
var program = twgl.createProgramFromScripts(gl, ["vs", "fs"], [], [], log);
log("--done--");

function log(msg) {
  var elem = document.createElement("pre");
  elem.appendChild(document.createTextNode(msg));
  document.body.appendChild(elem);
}
  <script id="vs" type="notjs">
struct Test {
  vec4 color;
  vec4 mult;
};

uniform Test test;
  
attribute vec4 position;

void main() {
  gl_Position = position * test.mult;
}
  </script>
  <script id="fs" type="notjs">
precision highp float;

struct Test {
  vec4 color;
  vec4 mult;
};

uniform Test test;

void main() {
  gl_FragColor = test.color;
  }
  </script>
  <script src="https://twgljs.org/dist/twgl.min.js"></script>


对于不支持片段着色器高精度的GPU应该怎么做? https://github.com/CesiumGS/cesium/issues/817 https://github.com/CesiumGS/webglreport/blob/master/webglreport.js#L120 - B''H Bi'ezras -- Boruch Hashem
1
在两个着色器中将uniform声明为struct Test { mediump vec4 color; mediump vec4 mult; }中的mediump。但要注意mediump的限制。对于颜色,您可以使用它,但是对于例如点光源计算,mediump没有足够的精度来计算点光源的最常见方式,因此无论您的着色器做什么,如果用户有不支持highp的手机,则可能必须完全使用不同的着色器。 - gman
那么您认为更好的方式是检查highp是否有效,如果有效,则在着色器文本中动态修改以使用highp,如果无效,则在顶点着色器中自动设置为mediump,还是我也必须在顶点着色器中自动将其设置为“mediump”? - B''H Bi'ezras -- Boruch Hashem
啊哈,但是顶点着色器中的默认值是什么?是highp吗?如果是这样,在不支持它的设备上,默认值会是mediump吗? - B''H Bi'ezras -- Boruch Hashem
默认情况下,在顶点着色器中始终使用highp,并且在所有GPU中都支持顶点着色器中的highp。只有在片段着色器中,highp是可选的。 - gman
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接