When setting
.js
renderer.shadowMapEnabled = true
I get several errors in chrome and the canvas does not get rendered.
In Firefox this is no issue.
I tested it with three.js73.
Here is the copy/paste from Chromes' console:
https://gist.github.com/nylki/672d2f714c4b75b282dc#file-gistfile1-js
error: sampler arrays indexed with non-constant expressions are forbidden in GLSL 1.30 and later
Uh... Any ideas @tschw?
@mrdoob
The warning says that later GL versions (including GL ES 3 / WebGL2) forbid stuff like
for ( int i = 0; i != 5; ++i ) {
color+= texture2D( mySamplerArray[ i ], uv );
}
It's in fact true. Spec references and discussion of possible solutions in #7426 .
/ping @kenrussell
Yes, it's unfortunately correct that indexing sampler arrays with non-constant indices is forbidden in OpenGL ES 3.0, where it was allowed in OpenGL ES 2.0 (basically for the situations where the compiler could unroll the loop).
It's unfortunate that constructs that are legal in ES 2.0 are failing to compile on desktop GL drivers, but I don't know the spec situation there. Intel's driver was overzealous in enforcing the sampler array indexing restrictions, and this was relaxed a while ago: see https://bugs.freedesktop.org/show_bug.cgi?id=84225 . Mesa 10.5 and 10.6 and the associated Intel drivers should have this fix.
There is an open bug about WebGL 2.0 strictly enforcing the new restrictions: https://github.com/KhronosGroup/WebGL/issues/1053 . We might need to revisit this topic even for WebGL 1.0, and manually unroll these loops in the shader translator as a workaround.
The most expedient workaround would be as described in #7426 and unroll the loop manually.
For the record, the WebGL conformance test glsl/bugs/sampler-array-using-loop-index.html covers this area.
CC'ing @Oletus and @zhenyao as an FYI since they both commented on the bug originally reported on this topic on Khronos' issue tracker (unfortunately not publicly visible).
One more comment: I'm not 100% sure why this would fail in Chrome and not Firefox. Chrome might be targeting a later desktop GLSL version in the ANGLE shader translator. You could confirm this by using the WEBGL_debug_shaders extension to get the translated shader source, and see if the Chrome version has a "#version 330" or similar directive at the top.
I encountered this issue when updating from Chromium 45 to 46: https://code.google.com/p/chromium/issues/detail?id=550487
Not a big deal since I can just keep Chromium downgraded, but I can give y'all some more bug data if you want
Also, my mesa driver is currently version 11.0.4 unfortunately
sampler-array-using-loop-index.html indeed fails here on Chromium 46.0.2490.86 MESA 11.0.6. How should WEBGL_debug_shaders be used?
Fetch the extension object from the WebGLRenderingContext, call getTranslatedShaderSource on the compiled vertex and fragment shaders (after they've been linked), and log the output to the console. See if the #version 330 directive is present in Chrome's output but not Firefox's.
Chrome's output presents #version 130, #version 330 however is not there.
Please copy/paste the output of your about:gpu into a gist somewhere and add the link here. I don't know what's going on. We can try to reproduce on a Linux machine with Intel GPU here.
OK, the Intel GLSL compiler is correct and the use of the #version 130 directive when ANGLE translates the shader to desktop GLSL is what's breaking the shaders. Here's the key part of GLSLangSpec.Full.1.30.10.pdf:
"Samplers aggregated into arrays within a shader (using square brackets [ ]) can only be indexed with integral constant expressions (see Section 4.3.3 “Constant Expressions”)."
Unfortunately this causes great difficulty for the WebGL implementation because we need to use version 130 of the desktop shading language for some constructs, but this breaks indexing of sampler arrays. It's not feasible for ANGLE to unroll all loops; the GLSL language doesn't have enough constructs to do this effectively. I'm sorry for this oversight and difference in behavior between platforms.
The best thing for Three.js to do is to work around this by using a switch statement and indexing the sampler array only with constants. The situation will become better in the future where at least the support will be consistent. In OpenGL ES 3.2 dynamic indexing of sampler arrays is finally universally supported, so a future WebGL implementation will support this better.
This should be solved with #13140 since we unroll all respective loops in the core shader code.
Users can now also trigger the loop unroll mechanism for custom shaders with a new pragma. It's only necessary that the for loop formatting corresponds to a defined standard.
Most helpful comment
This should be solved with #13140 since we unroll all respective loops in the core shader code.
Users can now also trigger the loop unroll mechanism for custom shaders with a new pragma. It's only necessary that the
forloop formatting corresponds to a defined standard.