У меня есть следующая ошибка с Три.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
нельзя было использовать неконстантный индекс для массивов, но теперь это должно быть возможно, верно?
Как узнать версии GLSL, используемые Three.js и Babylon.js?
Для использования GLSL ES 3.0 в Три.js вам необходимо создать контекст 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 Shading Language 1.00 — 13 Благодарностей; стр. 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 3.00–12.30 Динамическое индексирование; стр. 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
вместо attribute
или varying
.
Для использования GLSL ES 3.0 вам необходимо создать контекст WebGL 2.0.
См. документацию Three.js: Как использовать WebGL2.