three.js - Threejs数组索引错误:索引表达式必须是常量
问题描述
当我尝试使用具有非恒定索引的数组时, 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 文档:如何使用 WebGL2。
长答案
问题的着色器版本是 GLSL ES 1.0。数组的索引必须是常量表达式。
请参阅OpenGL ES 着色语言 1.00 规范 - 13 致谢;第 109 页:
5 数组、向量和矩阵的索引
定义:常量索引表达式是常量表达式的超集。常量索引表达式可以包括附录 A 第 4 节中定义的循环索引
。以下是常量索引表达式:
- 常量表达式
- 第 4 节中定义的循环索引
- 由以上两个组成的表达式
当用作索引时,常量索引表达式必须具有整数类型。
制服(不包括采样器)
在顶点着色器中,要求支持所有形式的数组索引。在片段着色器中,仅对常量索引表达式要求支持索引。#
这意味着片段着色器中数组的索引在任何情况下都必须是常量或循环索引。
这在 GLSL ES 3.0 中发生了变化。请参阅OpenGL ES 着色语言 3.00 - 12.30 动态索引;第 142 页:
对于 GLSL ES 1.00,不强制支持数组、向量和矩阵的动态索引,因为某些实现不直接支持它。软件解决方案(通过程序转换)适用于部分案例,但会导致性能不佳。GLSL ES 3.00 是否应该强制支持动态索引?
解决方案:强制支持数组的动态索引,但采样器数组、片段输出数组和统一块数组除外。
GLSL ES 3.0 着色器必须由着色代码第一行中的版本限定符限定:
#version 300 es
此外,还有一些语法差异,例如着色器输入和输出的限定符,它们in
分别out
代替attribute
or varying
。
要使用 GLSL ES 3.0,您必须创建一个 WebGL 2.0 上下文。
请参阅 Three.js 文档:如何使用 WebGL2。
推荐阅读
- python - 使用 unittest 进行 Python Selenium 测试 - 驱动程序错误
- scala - 如何从 Spark DataFrame 中的 AWS S3 读取多个文件?
- azure-active-directory - Azure 所有者角色和共同管理员之间的区别
- python - 如何有效地比较日期时间对象
- javascript - 电子从 ipcMain 发送数据到 ipcRender
- javascript - Javascript - 围绕异步 WebSocket 构建异步接口
- python - python-elasticsearch:如何启用 curl 日志记录?
- sql-server - 获取值不为空的第一个条目 SQL Server 2012
- elasticsearch - kibana 中的 ElasticSearch 内存使用情况与 Windows 不匹配
- javascript - 传入的对象无效,应为 ':' 或 '}'