Error in shader compile

I’ve got this bug report from a user, but I have no idea of what it means “Bad compile” of a shader. The code works on my machine.

Many thanks!

Oct 26, 2015 1:41:37 PM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.1-PBRisComing-5213
 * Branch: PBRisComing
 * Git Hash: 2db5f77
 * Build Date: 2015-09-25
Oct 26, 2015 1:41:38 PM com.jme3.system.lwjgl.LwjglContext printContextInitInfo
INFO: LWJGL 2.9.3 context running on thread jME3 Main
 * Graphics Adapter: null
 * Driver Version: null
 * Scaling Factor: 1
Oct 26, 2015 1:41:38 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: NVIDIA Corporation
 * Renderer: GeForce GTX 560/PCIe/SSE2
 * OpenGL Version: 4.5.0 NVIDIA 358.50
 * GLSL Version: 4.50 NVIDIA
 * Profile: Compatibility
Oct 26, 2015 1:41:38 PM com.jme3.asset.AssetConfig loadText
WARNING: Cannot find loader com.jme3.scene.plugins.blender.BlenderModelLoader
Oct 26, 2015 1:41:38 PM net.java.games.input.DefaultControllerEnvironment getControllers
WARNING: Found unknown Windows version: Windows 10
Oct 26, 2015 1:41:38 PM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Attempting to use default windows plug-in.
Oct 26, 2015 1:41:38 PM net.java.games.input.DefaultControllerEnvironment getControllers
INFO: Loading: net.java.games.input.DirectAndRawInputEnvironmentPlugin
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Device: OpenAL Soft
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Vendor: OpenAL Community
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer: OpenAL Soft
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Version: 1.1 ALSOFT 1.15.1
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: ALC extensions: ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX ALC_EXT_thread_local_context ALC_SOFT_loopback
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AL extensions: AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model AL_LOKI_quadriphonic AL_SOFT_buffer_samples AL_SOFT_buffer_sub_data AL_SOFTX_deferred_updates AL_SOFT_direct_channels AL_SOFT_loop_points AL_SOFT_source_latency
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: AudioRenderer supports 64 channels
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Oct 26, 2015 1:41:38 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxilary sends: 4
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Oct 26, 2015 1:41:47 PM com.jme3.renderer.opengl.GLRenderer updateShaderSourceData
WARNING: Bad compile of:
1	#version 110
2	#define FRAGMENT_SHADER 1
3	uniform sampler2D m_ColorMap0;
4	uniform sampler2D m_ColorMap1;
5	uniform sampler2D m_ColorMap2;
6	uniform sampler2D m_ColorMap3;
7	uniform sampler2D m_ColorMap4;
8	uniform sampler2D m_ColorMap5;
9	uniform sampler2D m_ColorMap6;
10	uniform sampler2D m_ColorMap7;
11	uniform float g_Time;
12	uniform float m_HitTime;
13	uniform vec4 m_GlowColor;
14	uniform float m_Sheet;
15	
16	varying vec2 texCoord;
17	
18	void main(){  
19	
20	if (m_Sheet == 0.0)
21	    vec4 color = texture2D(m_ColorMap0, texCoord);
22	if (m_Sheet == 1.0)
23	    color = texture2D(m_ColorMap1, texCoord);
24	if (m_Sheet == 2.0)
25	    color = texture2D(m_ColorMap2, texCoord);
26	if (m_Sheet == 3.0)
27	    color = texture2D(m_ColorMap3, texCoord);
28	if (m_Sheet == 4.0)
29	    color = texture2D(m_ColorMap4, texCoord);
30	if (m_Sheet == 5.0)
31	    color = texture2D(m_ColorMap5, texCoord);
32	if (m_Sheet == 6.0)
33	    color = texture2D(m_ColorMap6, texCoord);
34	if (m_Sheet == 7.0)
35	    color = texture2D(m_ColorMap7, texCoord);
36	/*    color.a = color.r * 0.7f;
37	    vec4 overlay =  vec4(0.5,0.8,1.0,1.0);
38	
39	 //gl_FragColor = max((1.0 - ((1.0 - color) / overlay)), 0.0);
40	    gl_FragColor = color * overlay;//
41	*/
42	vec4 overlay =  vec4(1.0,1.0,1.0,1.0);
43	  gl_FragColor =  mix(color, overlay, m_HitTime);//
44	//gl_FragColor =  m_GlowColor;
45	gl_FragColor.a = color.a;
46	}

Oct 26, 2015 1:41:47 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.renderer.RendererException: compile error in: ShaderSource[name=MatDefs/Anim.frag, defines, type=Fragment, language=GLSL100]
0(23) : error C1008: undefined variable "color"
0(25) : error C1008: undefined variable "color"
0(27) : error C1008: undefined variable "color"
0(29) : error C1008: undefined variable "color"
0(31) : error C1008: undefined variable "color"
0(33) : error C1008: undefined variable "color"
0(35) : error C1008: undefined variable "color"
0(43) : error C1008: undefined variable "color"
0(45) : error C1008: undefined variable "color"

	at com.jme3.renderer.opengl.GLRenderer.updateShaderSourceData(GLRenderer.java:1126)
	at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1153)
	at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1217)
	at com.jme3.material.Material.render(Material.java:1255)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:568)
	at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:266)
	at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:302)
	at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:831)
	at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:731)
	at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1030)
	at com.jme3.renderer.RenderManager.render(RenderManager.java:1086)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:260)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:152)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:192)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:233)
	at java.lang.Thread.run(Unknown Source)

To me, it looks like the variable “color” isn’t really defined. In line 21 there is an “vec4” color, but in all other cases, there is not. Maybe the color-variable should be defined at the beginning of the shader.

Try this:

  • line 15: add “vec4 color;”
  • line 21: remove “vec4”
1 Like

Works on my machine means nothing with shaders
(except maybe you are useing the linux mesa compiler, it is extremely strict).
Welcome to specification limbo.

Anyway due to the different achritecture your gpu might execture ALL if at the same time, and discard the unwanted ones, thu having the variable due to the first if where it is defined. Anyway that code is clearly violating specifcation.

1 Like

Because…

if (m_Sheet == 0.0)
    vec4 color = texture2D(m_ColorMap0, texCoord);

Is the same as:

if (m_Sheet == 0.0) {
    vec4 color = texture2D(m_ColorMap0, texCoord);
}

So, guess where color is defined and limited?

Thank everybody :smile:
@pspeed you have copied the same code twice. I guess you wanted to point out that I am not allowed to define vec4 inside if, but I might be wrong (again).

You need more attention to detail, I think:

1 Like

I guess there is more to it…
If this has been reported by a user, I guess it works on your end? But I can’t see how it could work.

You know… now that I think about it, this whole construct is a little weird.

Why set 7 color maps if you are only going to use one based on a uniform value? Why not just set the color map that you want to use rather than the uniform?

See, the thing is that conditionals like this can be bad. It’s possible that all 7 texture fetches are done and only the right one is used in the end. Versus guaranteeing that only one fetch is done by only having one in the first place.

1 Like

@nehon believe it or not, it works on intel HD 2000. :expressionless:

This is a spritesheet library, and I’d like to pack all the sprites in multiple sheets and abstract their position from the Java side. For example, I want to draw “sprite 230”, but I have no idea on which texture it is: it is all managed by the library. On the java side I create an array of int sheets+positions.

Like this:

public class MSFrame {
    int position;
    int sheet;
    public MSFrame(int position, int sheet){
        this.position=position;
        this.sheet=sheet;
    }
}

Then I change sprite like this:

material.setFloat("Position", frame.position);
material.setFloat("Sheet", frame.sheet);

Which could just as easily have been:

public class MSFrame {
    int position;
    Texture sheet;
    public MSFrame(int position, Texture sheet){
        this.position=position;
        this.sheet=sheet;
    }
}

And avoid the unnecessary overhead.

1 Like

Well… it works, but some frames are drawn with a Texture that is supposed to be used elsewhere (like: I see pieces of the GUI in it)… is it common for a shader to leak textures around?

I would use a texture array and a vec3(texCoordinate,sheetId) to access it on the shader, that would eliminate that ugly branching completely.

Stricktly: “vec4 color” is never defined unless m_Sheet == 0
Even if your compiler is smart enough to allow it, it is simply wrong.

It is usually a sign that you forgot to set a texture

1 Like

Awesome! Now I only have to clean some stuff on the Java side :smile: