I need to use #extension GL_OES_standard_derivatives:enable in a few fragment shaders, but I’m running into a problem on Android devices that only support medium precision floating point. The issue is that the extension directive must occur before any other non-preprocessor instructions so naturally I put the directive at the beginning of the file, but when the Android device doesn’t support high precision floats jME puts precision mediump float; at the top of the shader, above the extension directive, causing shader compilation to fail with Extension directive must occur before any non-preprocessor tokens.
So how does one go about using GLSL extensions in jME?
I was able to solve this issue for my app. My solution may not be the best for everyone, but it works for me because I already have precision mediump float; or precision highp float; in my shaders where necessary.
I re-compiled jME3-core with the following change to GLRenderer:
The thing is your shader can’t work on desktop anymore. It may be not an issue in your situation, though.
We had another issue with extensions not being put at the beginning of the shader IMO we should have something that parses the code for extensions and put them at the beginning of the file.
I made a change in the shader node generation in this regard, but I didn’t test on android, so the issue might still be there…
This way it only specifies the precision if it’s running on OpenGL ES, but yeah the change to GLRenderer was just a quick job meant to support just the Android app I’m working on right now.
Err actually just the Android app I finished a couple of hours ago ;).
How I’ve ultimately fixed this was to get rid of that entirely and edit all the shader files included with jME adding the following at the top of each:
#ifdef GL_ES
precision mediump float;
#endif
I’m not sure if that would be a viable long term solution for jMonkeyEngine, but it should be rather performance friendly and it would allow each shader to specify medium or high precision as needed. The only issue, I think, is that it’d break compatibility with older custom shaders when running on Android or iOS if they don’t specify a floating point precision.
I haven’t tested it with master, but I didn’t notice that. Although a couple of my shaders require high precision, does inserting precision mediump float; above a precision highp float; instruction cause it to use medium or high precision?
Yeah, I’m thinking having both defined would be handled differently depending on the device. I noticed that even though the spec indicates extention directives must occur at the beginning of a shader some devices allowed it if it wasn’t at the beginning and some didn’t.