当我尝试使用具有非常量索引的数组时,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版本?
要在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数组,向量和矩阵的索引
定义:constant-index-expressions是常量表达式的超集。常量索引表达式可以包括附录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着色器必须由着色代码的第一行中的版本quailfier限定:
#version 300 es
此外,还有一些语法差异,如着色器输入和输出的限定符,分别是in
,out
而不是attribute
或varying
。
对于GLSL ES 3.0的使用,您需要创建WebGL 2.0上下文。 请参阅Three.js文档:How to use WebGL2。