Failed to link lighting shaders on Android


Well, I’m not sure if you are asking me or the whole community (or maybe just to @nehon ), by my part I don’t have a clue about the subject, sorry.


I just got back to android development again after an age of idleness. I also have issues with the lighting shader but a different one (still “Shader failed to link”:
Error: uniform variables in vertex shader do not fit in 256 vectors.
I’m going to see if I can find out what is causing it.

Using the lighting shader is possible, though. I used it for the asteroids in AsteroidBeltTravelVR. That has Shininess 0.0 though.


do you use hardware skinning?


Yes, I should have remembered that causes issues on android (but to be honest I had forgotten it was on).


Any progress on this issue? Or you someone explain what is the reason of the problem.


If I remember, it has something to do with detecting the capabilities incorrectly on emulators. I can’t remember how I bypassed it. I think I just changed the hardware requirements in the j3md file.

VertexShader GLSL100 GLSL150


VertexShader GLSL110

on both the vert and frag lines. or something like that.


Same thing happens also on real device, not on all but some. This is stack trace from one.

02-13 22:37:22.463 2667-2699/ E/ SEVERE Exception thrown in Thread[GLThread 1438,5,main]
    com.jme3.renderer.RendererException: Shader failed to link, shader:Shader[numSources=2, numUniforms=22, shaderSources=[ShaderSource[name=Common/MatDefs/Light/Lighting.frag, defines, type=Fragment, language=GLSL100], ShaderSource[name=Common/MatDefs/Light/Lighting.vert, defines, type=Vertex, language=GLSL100]]]
    --From Vertex Shader:
    Error: uniform variables in vertex shader do not fit in 256 vectors.
    --From Fragment Shader:
    Error: uniform variables in vertex shader do not fit in 256 vectors.
        at com.jme3.renderer.opengl.GLRenderer.updateShaderData(
        at com.jme3.renderer.opengl.GLRenderer.setShader(
        at com.jme3.material.logic.MultiPassLightingLogic.render(
        at com.jme3.material.Technique.render(
        at com.jme3.material.Material.render(
        at com.jme3.renderer.RenderManager.renderGeometry(
        at com.jme3.renderer.queue.RenderQueue.renderGeometryList(
        at com.jme3.renderer.queue.RenderQueue.renderQueue(
        at com.jme3.renderer.RenderManager.renderViewPortQueues(
        at com.jme3.renderer.RenderManager.flushQueue(
        at com.jme3.renderer.RenderManager.renderViewPort(
        at com.jme3.renderer.RenderManager.render(
        at android.opengl.GLSurfaceView$GLThread.guardedRun(
        at android.opengl.GLSurfaceView$

I m not using any material definition (well i guess not directly if engine is doing something ), just loading spatial from j3o file.


you will need to find the geometries in your model and tell them to use the material definition you modified, else they won’t use it.


Im not sure what this means, either, tbh. I’ve never seen that error before.


It means he’s using hardware skinning with too many bones, I guess. As already discussed higher up in this thread.


I have a solution to the original problem posted here. Well, a solution to the symptom…
Plus a speculative reason for the cause.

The solution is the add this to your material definition:
mat.setBoolean(“VertexLighting”, true);

Without this line, all the JME test examples using Lighting shaders that I tried crashed on Android.
mat.setBoolean(“VertexLighting”, false); //Guarantees a crash on android.

Speculative reason:
There is a series of #ifdef VERTEX_LIGHTING and #ifndef VERTEX_LIGHTING blocks of code in both Lighting.frag and Lighting.vert.
Having suffered many years of chasing ‘C’ program header bugs, the sight of complicated #ifdefs make my underpants shake. If anyone wants to debug the case when VERTEX_LIGHTING is false please do.

Speculation based on info I found on internet conversations is that Lighting.frag and Lighting.vert shader programs can choose precisions for variables based on the hardware they are running on. You would think they would choose the same precision, but maybe not?

There is the possibility of setting a hard coded precision in the shaders but that might defeat the possibility of harware optimisation. Maybe.

Anyway, I knew nothing about shaders yesterday, but now I know a little. Not enough fix the problem, just enough to cure the symptom.

I managed to get the more complicated test “jme3test.animation.TestJaime” working on my Android tablet using the above technique. (After comenting out all shadowing, which is not supported on my tablet). However it runs as a random scattering of brown triangles on the Android emulator. Not good.

To get at the material embedded in the jaime model I did this:
Geometry jaimeGeometry = (Geometry) jaime.getChild(0);
Material jaimeMaterial = jaimeGeometry.getMaterial();
jaimeMaterial.setBoolean(“VertexLighting”, true);

getChild(0) is a bit hacky, should really be a named child…


Turn off hardware skinning.


Yes, thanks, I disabled hardware skinning of jaime (below) and jaime works on my tablet.
//disable hardware skinning
SkeletonControl sc = jaime.getControl(SkeletonControl.class);

However I get the same ‘different precision’ crash in the android emulator.
Now if I do both (disable skinning AND VertexLighting=true) jaime works in the emulator!
It’s good fun this :slight_smile:

BTW. Is there any way to get shadows working on Android?
Even with hardware skinning disabled PostShadow.frag fails to compile (not supported)
Can a shadow shader be emulated? Or at some point do you have to have hardware support?
[Point me at some good reading material if I’m getting annoying]


The Android PostShadow issue sounds like it might be this one, which is fixed in JME’s master branch but not yet in any release:

Shadows and post processor filters issues and proposals


Sorry to report I am running the master branch. I ran in debugger.
After for Lighting frag and vert seemed to work OK,

source= ShaderSource[name=Common/MatDefs/Shadow/PostShadow.frag, defines, type=Fragment, language=GLSL100]

Line 1350 was hit: insertPrecision = true;
But at line 1384 compiledOK returned false
then later,
RendererException: compile error in: ShaderSource[name=Common/MatDefs/Shadow/PostShadow.frag WARNING: 0:8: ‘GL_ARB_gpu_shader5’ : extension is not supported…


Reading the topic linked above indicates that the initial fix wasn’t quite correct. Apparently @nehon and @joliver82 planned to follow up, but perhaps they never did, which would explain why master is still broken.


Hi all,

@sgold, in fact I’ve been working in my own fork of jme3 with some light improvements for jme3 for android but sadly they’re still not mature enough for PR.

About the issue here, it doesn’t look like the one detected in the linked topic which in fact, as far as I know, it was never fully fixed in master, the change was applied to version >= 130 instead of the “else” path, so shadowing should still be failing for android because the engine is always using gles 2.0 with shaders 1.0

Getting back to the topic… @tharg2, I didn’t undertand your last message… did it work for you in master or are you still having the same error?


Hi @joliver82 Sorry it is getting a little confused with the 2 errors being discussed.

Re. the ‘precision’ error: Error: uniform m_Shininess specified with different precision in different shaders.

  1. setHardwareSkinningPreferred(false); => shadowless jaime works on my android tablet
  2. setHardwareSkinningPreferred(false); => shadowless jaime crashes on the android emulator with the ‘precision’ error
  3. setHardwareSkinningPreferred(false) AND VertexLighting=true => shadowless jaime works in the emulator

Re. the linked error: PostShadow.frag fails to compile:
Occurs on both real tablet and emulator when I enable shadowing, via setShadowMode


This tends to imply that shadows are using a feature not available on your tablet/emulator/etc.


@pspeed Yup. The “extension is not supported” is pretty explicit. So are shadows impossible on Android? Should I try later versions of Android platform on the Android emulator?
Yesterday I didn’t know what a shader was. Today I still don’t :wink:
It’s still a mystery where the cutoff lies between JME software vs Android system software vs Android hardware. Some simplistic architecture diagrams might help me understand where the Shady Shader fits in.
I’ll go read some more…