Threejs数组索引错误:索引表达式必须为常数

时间:2019-04-08 14:56:54

标签: three.js glsl webgl shader

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

  

'[]':索引表达式必须为常数

使用以下片段着色器:

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版本?

1 个答案:

答案 0 :(得分:2)

简短答案

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

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

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个数组,向量和矩阵的索引

     

定义:   常量索引表达式是常量表达式的超集。常量索引表达式可以包含附录A第4节中定义的循环索引。
  以下是常量索引表达式:

     
      
  • 常量表达式
  •   
  • 第4节中定义的循环索引
  •   
  • 由以上两个组成的表达式
  •   
     

当用作索引时,constant-index-expression必须具有整数类型。

     

制服(不包括采样器)

     

在顶点着色器中,必须支持所有形式的数组索引。在片段着色器中,仅对于常量索引表达式才强制支持索引。#

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


这在GLSL ES 3.0中进行了更改。参见OpenGL ES Shading Language 3.00 - 12.30 Dynamic Indexing;第142页:

  

对于GLSL ES 1.00,没有强制要求对数组,向量和矩阵进行动态索引,因为某些实现未直接支持它。存在针对一部分情况的软件解决方案(通过程序转换),但会导致性能下降。 GLSL ES 3.00是否应要求支持动态索引?

     

解决方案:强制支持对数组进行动态索引,但采样器数组,片段输出数组和统一块数组除外。


GLSL ES 3.0着色器必须由着色代码第一行中的Quilfier版本限定:

#version 300 es

此外,在语法上还存在一些差异,例如着色器输入和输出的限定符,分别是in而不是outattribute

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