Threejs array index error: Index expression must be constant

Threejs array index error: Index expression must be constant

当我尝试使用具有非常量索引的数组时,Three.js 出现以下错误:

'[]' : Index expression must be constant

使用以下片段着色器:

precision mediump float;

varying vec2 vUV;

uniform vec2 screenResolution;

vec4 colors[2];

void main(void) {

    vec2 uv = gl_FragCoord.xy / screenResolution.xy;

    colors[0] = vec4(0.0);
    colors[1] = vec4(1.0);

    int index = int(floor(uv.y * 1.9));

    gl_FragColor = colors[index];
}

Babylon.js不会出现此错误。

我知道在 GLSL ES 的早期版本中不能对数组使用非常量索引,但现在应该可以了,对吗?

如何知道 Three.js 和 Babylon.js 使用的 GLSL 版本?

简答

要在 Three.js 中使用 GLSL ES 3.0,您必须创建 WebGL 2.0 上下文。

检查设备是否支持 WebGL 2 后,使用给定的 webgl2 上下文创建 WebGLRenderer

var canvas = document.createElement( 'canvas' );
var context = canvas.getContext( 'webgl2' );
var renderer = new THREE.WebGLRenderer( { canvas: canvas, context: context } );

请参阅 Three.js 文档:How to use WebGL2

长答案

问题的着色器版本是GLSL ES 1.0。数组的索引必须是常量表达式。

参见OpenGL ES Shading Language 1.00 Specification - 13 Acknowledgements;第 109 页:

5 Indexing of Arrays, Vectors and Matrices

Definition: constant-index-expressions are a superset of constant-expressions. Constant-index-expressions can include loop indices as defined in Appendix A section 4.
The following are constant-index-expressions:

  • Constant expressions
  • Loop indices as defined in section 4
  • Expressions composed of both of the above

When used as an index, a constant-index-expression must have integral type.

Uniforms (excluding samplers)

In the vertex shader, support for all forms of array indexing is mandated. In the fragment shader, support for indexing is only mandated for constant-index-expressions.#

这意味着片段着色器中数组的索引在任何情况下都必须是常量或循环索引。


这在 GLSL ES 3.0 中发生了变化。参见OpenGL ES Shading Language 3.00 - 12.30 Dynamic Indexing;第 142 页:

For GLSL ES 1.00, support of dynamic indexing of arrays, vectors and matrices was not mandated because it was not directly supported by some implementations. Software solutions (via program transforms) exist for a subset of cases but lead to poor performance. Should support for dynamic indexing be mandated for GLSL ES 3.00?

RESOLUTION: Mandate support for dynamic indexing of arrays except for sampler arrays, fragment output arrays and uniform block arrays.


GLSL ES 3.0 着色器必须通过着色代码第一行中的版本限定符进行限定:

#version 300 es

此外还有一些语法差异,例如着色器输入和输出的限定符,它们分别是 in out 而不是 attributevarying

要使用 GLSL ES 3.0,您必须创建一个 WebGL 2.0 上下文。
请参阅 Three.js 文档:How to use WebGL2.