[SOLVED] Problem with PBR : extension directive is not allowed in the middle of a shader

Hi friends

When running TestPBRLighting.java i am getting an exception

full detail :

INFO: Running on jMonkeyEngine 3.2-1
 * Branch: master
 * Git Hash: c50b4db
 * Build Date: 2016-09-22
Sep 23, 2016 11:05:23 AM 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
Sep 23, 2016 11:05:23 AM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: X.Org
 * Renderer: Gallium 0.4 on AMD CEDAR (DRM 2.43.0, LLVM 3.8.0)
 * OpenGL Version: 3.0 Mesa 11.2.0
 * GLSL Version: 1.30
 * Profile: Compatibility
Sep 23, 2016 11:05:23 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer Information
 * Device: OpenAL Soft
 * Vendor: OpenAL Community
 * Renderer: OpenAL Soft
 * Version: 1.1 ALSOFT 1.15.1
 * Supported channels: 64
 * 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
 * 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
Sep 23, 2016 11:05:23 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Sep 23, 2016 11:05:23 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Sep 23, 2016 11:05:23 AM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxiliary sends: 4
Sep 23, 2016 11:05:27 AM com.jme3.material.Material checkSetParam
WARNING: Material parameter being set: Texture with type Texture2D doesn't match definition types TextureCubeMap
Sep 23, 2016 11:05:27 AM com.jme3.material.Material setTextureParam
WARNING: The texture Textures/Sky/Path.hdr has linear color space, but the material parameter Texture specifies no color space requirement, this may lead to unexpected behavior.
Check if the image was not set to another material parameter with a linear color space, or that you did not set the ColorSpace to Linear using texture.getImage.setColorSpace().
Sep 23, 2016 11:05:31 AM com.jme3.renderer.opengl.GLRenderer updateShaderSourceData
WARNING: Bad compile of:
1    #version 110
2    #define FRAGMENT_SHADER 1
3    
4    uniform samplerCube m_CubeMap;
5    
6    varying vec3 Reflect_refVec;
7    
8    #extension GL_ARB_shader_texture_lod : enable
9    
10    void main(){
11            vec4 Global_color = vec4(1.0);
12    
13    
14        //EnvMapping : Begin
15        vec3 EnvMapping_refVec = Reflect_refVec;
16        vec4 EnvMapping_color;
17    
18            //@input vec3 EnvMapping_refVec the reflection vector
19        //@input samplerCube m_CubeMap the cube map
20        //@output vec4 EnvMapping_color the output EnvMapping_color
21    
22        EnvMapping_color = textureCubeLod(m_CubeMap, EnvMapping_refVec, 0.0);
23        Global_color = EnvMapping_color;
24        //EnvMapping : End
25    
26        gl_FragColor = Global_color;
27    }

Sep 23, 2016 11:05:31 AM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.renderer.RendererException: compile error in: ShaderSource[name=Default.frag, defines, type=Fragment, language=GLSL100]
0:8(1): error: #extension directive is not allowed in the middle of a shader

    at com.jme3.renderer.opengl.GLRenderer.updateShaderSourceData(GLRenderer.java:1203)
    at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1230)
    at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1294)
    at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:94)
    at com.jme3.material.Technique.render(Technique.java:166)
    at com.jme3.material.Material.render(Material.java:970)
    at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:616)
    at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:266)
    at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:305)
    at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:879)
    at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:781)
    at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1106)
    at com.jme3.renderer.RenderManager.render(RenderManager.java:1154)
    at com.jme3.app.SimpleApplication.update(SimpleApplication.java:253)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
    at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:197)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
    at java.lang.Thread.run(Thread.java:745)

Arf… I need to change how the extension is added with a glsllib

1 Like

Dear @nehon , thought you might forget about my problem :wink:
Still waiting for your fix … :slight_smile:

I did forget about it.
I will check it.

1 Like

committed a fix.
Can you try?

1 Like

Thanks so much Nehon. :slight_smile:
Going to try it.

I tried to add that fix manually by modifying jme3-core-3.2.0-SNAPSHOT.jar but was not successful to run. So i will rebuild it from source tonight.

if you use gradle, maven or whatever you can use Jit pack to get a lib from an arbitrary commit.
https://jitpack.io/#JmonkeyEngine/jMonkeyEngine/cd70630502

1 Like

Okay, I tested with new patch you made but unfortunately getting exactly the same error yet ! :disappointed_relieved:

Uncaught exception thrown in Thread[jME3 Main,5,main]
RendererException: compile error in: ShaderSource[name=Default.frag, defines, type=Fragment, language=GLSL100]
0:8(1): error: #extension directive is not allowed in the middle of a shader

could you paste the whole code please? the one output before the error.

this is the test class i am running

/*
 * Copyright (c) 2009-2015 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package jme3test.light.pbr;

import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingSphere;
import com.jme3.light.LightProbe;
import com.jme3.environment.LightProbeFactory;
import com.jme3.environment.EnvironmentCamera;
import com.jme3.environment.generation.JobProgressAdapter;
import com.jme3.environment.util.LightsDebugState;
import com.jme3.input.ChaseCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.FXAAFilter;
import com.jme3.post.filters.ToneMapFilter;
import com.jme3.post.ssao.SSAOFilter;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.texture.plugins.ktx.KTXLoader;
import com.jme3.util.MaterialDebugAppState;
import com.jme3.util.SkyFactory;
import com.jme3.util.mikktspace.MikktspaceTangentGenerator;

/**
 * A test case for PBR lighting.
 * Still experimental.
 *
 * @author nehon
 */
public class TestPBRLighting extends SimpleApplication {

    public static void main(String[] args) {
        TestPBRLighting app = new TestPBRLighting();
        app.start();
    }
    private Geometry model;
    private DirectionalLight dl;
    private Node modelNode;
    private int frame = 0;   
    private Material pbrMat;    

    @Override
    public void simpleInitApp() {
        assetManager.registerLoader(KTXLoader.class, "ktx");

        viewPort.setBackgroundColor(ColorRGBA.White);
        modelNode = (Node) new Node("modelNode");
        model = (Geometry) assetManager.loadModel("Models/Tank/tank.j3o");
        MikktspaceTangentGenerator.generate(model);
        modelNode.attachChild(model);

        dl = new DirectionalLight();
        dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
        rootNode.addLight(dl);
        dl.setColor(ColorRGBA.White);
        rootNode.attachChild(modelNode);

      
        FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
//        fpp.addFilter(new FXAAFilter());
        fpp.addFilter(new ToneMapFilter(Vector3f.UNIT_XYZ.mult(4.0f)));
//        fpp.addFilter(new SSAOFilter(0.5f, 3, 0.2f, 0.2f));
        viewPort.addProcessor(fpp);

        //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Sky_Cloudy.hdr", SkyFactory.EnvMapType.EquirectMap);
        Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Path.hdr", SkyFactory.EnvMapType.EquirectMap);
        //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", SkyFactory.EnvMapType.CubeMap);
        //Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/road.hdr", SkyFactory.EnvMapType.EquirectMap);
        rootNode.attachChild(sky);

        pbrMat = assetManager.loadMaterial("Models/Tank/tank.j3m");
        model.setMaterial(pbrMat);


        final EnvironmentCamera envCam = new EnvironmentCamera(128, new Vector3f(0, 3f, 0));
        stateManager.attach(envCam);
        
//        EnvironmentManager envManager = new EnvironmentManager();
//        stateManager.attach(envManager);
        
 //       envManager.setScene(rootNode);
        
        LightsDebugState debugState = new LightsDebugState();
        stateManager.attach(debugState);
        
        ChaseCamera chaser = new ChaseCamera(cam, modelNode, inputManager);
        chaser.setDragToRotate(true);
        chaser.setMinVerticalRotation(-FastMath.HALF_PI);
        chaser.setMaxDistance(1000);
        chaser.setSmoothMotion(true);
        chaser.setRotationSensitivity(10);
        chaser.setZoomSensitivity(5);
        flyCam.setEnabled(false);
        //flyCam.setMoveSpeed(100);

        inputManager.addListener(new ActionListener() {
            @Override
            public void onAction(String name, boolean isPressed, float tpf) {
                if (name.equals("debug") && isPressed) {
                    //envCam.toggleDebug();
                }

                if (name.equals("up") && isPressed) {
                    model.move(0, tpf * 100f, 0);
                }

                if (name.equals("down") && isPressed) {
                    model.move(0, -tpf * 100f, 0);
                }
                if (name.equals("left") && isPressed) {
                    model.move(0, 0, tpf * 100f);
                }
                if (name.equals("right") && isPressed) {
                    model.move(0, 0, -tpf * 100f);
                }
                if (name.equals("light") && isPressed) {
                    dl.setDirection(cam.getDirection().normalize());
                }
            }
        }, "toggle", "light", "up", "down", "left", "right", "debug");

        inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_RETURN));
        inputManager.addMapping("light", new KeyTrigger(KeyInput.KEY_F));
        inputManager.addMapping("up", new KeyTrigger(KeyInput.KEY_UP));
        inputManager.addMapping("down", new KeyTrigger(KeyInput.KEY_DOWN));
        inputManager.addMapping("left", new KeyTrigger(KeyInput.KEY_LEFT));
        inputManager.addMapping("right", new KeyTrigger(KeyInput.KEY_RIGHT));
        inputManager.addMapping("debug", new KeyTrigger(KeyInput.KEY_D));
        
        
        MaterialDebugAppState debug = new MaterialDebugAppState();
        debug.registerBinding("Common/MatDefs/Light/PBRLighting.frag", rootNode);
        getStateManager().attach(debug);

    }

    @Override
    public void simpleUpdate(float tpf) {
        frame++;

        if (frame == 2) {
            modelNode.removeFromParent();
            final LightProbe probe = LightProbeFactory.makeProbe(stateManager.getState(EnvironmentCamera.class), rootNode, new JobProgressAdapter<LightProbe>() {

                @Override
                public void done(LightProbe result) {
                    System.err.println("Done rendering env maps");
                }
            });
            ((BoundingSphere)probe.getBounds()).setRadius(100);
            rootNode.addLight(probe);
            //getStateManager().getState(EnvironmentManager.class).addEnvProbe(probe);
            
        }
        if (frame > 10 && modelNode.getParent() == null) {
            rootNode.attachChild(modelNode);
        }
    }

}

and this is whole error stack

ant -f /media/idea/01D0ABF282E1DD20/Java/jME_NB-PW-11-6-2015/JmeTests -Djavac.includes=jme3test/light/pbr/TestPBRLighting.java -Dnb.internal.action.name=run.single -Drun.class=jme3test.light.pbr.TestPBRLighting run-single
init:
Deleting: /media/idea/01D0ABF282E1DD20/Java/jME_NB-PW-11-6-2015/JmeTests/build/built-jar.properties
deps-jar:
Updating property file: /media/idea/01D0ABF282E1DD20/Java/jME_NB-PW-11-6-2015/JmeTests/build/built-jar.properties
Compiling 1 source file to /media/idea/01D0ABF282E1DD20/Java/jME_NB-PW-11-6-2015/JmeTests/build/classes
warning: [options] bootstrap class path not set in conjunction with -source 1.7
1 warning
compile-single:
run-single:
Oct 04, 2016 8:08:11 PM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.2-1
 * Branch: master
 * Git Hash: cd70630
 * Build Date: 2016-10-04
Oct 04, 2016 8:08:12 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 04, 2016 8:08:12 PM com.jme3.renderer.opengl.GLRenderer loadCapabilitiesCommon
INFO: OpenGL Renderer Information
 * Vendor: Intel Open Source Technology Center
 * Renderer: Mesa DRI Intel(R) Sandybridge Mobile 
 * OpenGL Version: 3.0 Mesa 11.2.0
 * GLSL Version: 1.30
 * Profile: Compatibility
Oct 04, 2016 8:08:13 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio Renderer Information
 * Device: OpenAL Soft
 * Vendor: OpenAL Community
 * Renderer: OpenAL Soft
 * Version: 1.1 ALSOFT 1.15.1
 * Supported channels: 64
 * 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
 * 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 04, 2016 8:08:13 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
WARNING: Pausing audio device not supported.
Oct 04, 2016 8:08:13 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio effect extension version: 1.0
Oct 04, 2016 8:08:13 PM com.jme3.audio.openal.ALAudioRenderer initOpenAL
INFO: Audio max auxiliary sends: 4
Oct 04, 2016 8:08:17 PM com.jme3.material.Material checkSetParam
WARNING: Material parameter being set: Texture with type Texture2D doesn't match definition types TextureCubeMap
Oct 04, 2016 8:08:17 PM com.jme3.material.Material setTextureParam
WARNING: The texture Textures/Sky/Path.hdr has linear color space, but the material parameter Texture specifies no color space requirement, this may lead to unexpected behavior.
Check if the image was not set to another material parameter with a linear color space, or that you did not set the ColorSpace to Linear using texture.getImage.setColorSpace().
Oct 04, 2016 8:08:21 PM com.jme3.renderer.opengl.GLRenderer updateShaderSourceData
WARNING: Bad compile of:
1    #version 110
2    #define FRAGMENT_SHADER 1
3    
4    uniform samplerCube m_CubeMap;
5    
6    varying vec3 Reflect_refVec;
7    
8    #extension GL_ARB_shader_texture_lod : enable
9    
10    void main(){
11            vec4 Global_color = vec4(1.0);
12    
13    
14        //EnvMapping : Begin
15        vec3 EnvMapping_refVec = Reflect_refVec;
16        vec4 EnvMapping_color;
17    
18            //@input vec3 EnvMapping_refVec the reflection vector
19        //@input samplerCube m_CubeMap the cube map
20        //@output vec4 EnvMapping_color the output EnvMapping_color
21    
22        EnvMapping_color = textureCubeLod(m_CubeMap, EnvMapping_refVec, 0.0);
23        Global_color = EnvMapping_color;
24        //EnvMapping : End
25    
26        gl_FragColor = Global_color;
27    }

Oct 04, 2016 8:08:21 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.renderer.RendererException: compile error in: ShaderSource[name=Default.frag, defines, type=Fragment, language=GLSL100]
0:8(1): error: #extension directive is not allowed in the middle of a shader

    at com.jme3.renderer.opengl.GLRenderer.updateShaderSourceData(GLRenderer.java:1203)
    at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1230)
    at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1294)
    at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:94)
    at com.jme3.material.Technique.render(Technique.java:166)
    at com.jme3.material.Material.render(Material.java:970)
    at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:616)
    at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:266)
    at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:305)
    at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:879)
    at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:781)
    at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1106)
    at com.jme3.renderer.RenderManager.render(RenderManager.java:1154)
    at com.jme3.app.SimpleApplication.update(SimpleApplication.java:253)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
    at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:197)
    at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:232)
    at java.lang.Thread.run(Thread.java:745)

Also should mention that , when running it runs for a second (or may half a second) and then throws this error.

oh doh… it’s in the debug material
Gonna fix it.
In the mean time comment the line

stateManager.attach(debugState);

it should work

@Momoko_Fan so basically using an extension declaration in a glsl lib is not really a good idea as it forces you to import it in a shader before everything else. It’s not practicle at all as users may not know what’s in the glsllib file.
Couldn’t we parse the glsl libs for “#extension” and put tis at the top of the file before the compilation? what do you think?

1 Like

Thanks a lot Nehon.

ok, could you test it again please? I committed a fix

Running successfully :slight_smile:
Thanks a lot

5 Likes

you should use game correction

1 Like

er… i meant gamma correction… but you know… with typos :stuck_out_tongue:

2 Likes

Wow! I thought perhaps you had implemented the equivalent of the elusive RMMM!

If my JME game isn’t working right, or isn’t good, you mean I can just do:

simpleApplication.correctGame();
1 Like