NullPointerException with SSAOFilter

I am attempting to create a game, mostly for fun but also for learning. The specifics of how the game works are very unlikely to be necessary. However, if you need to know then please ask. There is one terrain object that is randomly generated at runtime via a custom Perlin Noise like implementation along with an Ambient Light, a DirectonalLight, a DirectionalLightShadowRenderer, DirectionalLightShadowFilter, and a SSAOFilter. Both filters are added to the same FilterPostProcessor. There are no other objects added to the RootNode at all.

I am using IntelliJ Idea Community Edition since I prefer it over JME’s SDK. I have all JME3 libraries added to the classpath along with the testdata. When the IDE builds the project, it simply extracts all of JME3’s jars into the application’s final jar to simplify deployment (although that will almost certainly never happen).

I have the following code to initialize the lighting:

AmbientLight ambientLight = new AmbientLight();
        ambientLight.setColor(ColorRGBA.White.mult(1.5f));
        balloonWars.getRootNode().addLight(ambientLight);

        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(SUN_DIR);
        sun.setColor(ColorRGBA.White.mult(1.2f));
        balloonWars.getRootNode().addLight(sun);

        FilterPostProcessor filterPostProcessor = new FilterPostProcessor();

        DirectionalLightShadowFilter directionalLightShadowFilter = new DirectionalLightShadowFilter(balloonWars.getAssetManager(), SHADOWMAP_SIZE, 3);
        directionalLightShadowFilter.setLight(sun);
        directionalLightShadowFilter.setEnabled(true);
        filterPostProcessor.addFilter(directionalLightShadowFilter);

        SSAOFilter ssaoFilter = new SSAOFilter();
        filterPostProcessor.addFilter(ssaoFilter);

        balloonWars.getViewPort().addProcessor(filterPostProcessor);

        DirectionalLightShadowRenderer directionalLightShadowRenderer = new DirectionalLightShadowRenderer(balloonWars.getAssetManager(), SHADOWMAP_SIZE, 3);
        directionalLightShadowFilter.setLight(sun);
        balloonWars.getViewPort().addProcessor(directionalLightShadowRenderer);

This code produces the following stacktrace:

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
at com.jme3.material.Material.<init>(Material.java:120)
at com.jme3.post.ssao.SSAOFilter.initFilter(SSAOFilter.java:150)
at com.jme3.post.Filter.init(Filter.java:234)
at com.jme3.post.FilterPostProcessor.initFilter(FilterPostProcessor.java:165)
at com.jme3.post.FilterPostProcessor.reshape(FilterPostProcessor.java:447)
at com.jme3.post.FilterPostProcessor.initialize(FilterPostProcessor.java:149)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:955)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1029)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:252)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)
at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:228)
at java.lang.Thread.run(Thread.java:745)

This is running on Ubuntu 14.04 LTS x64 on a Toshiba Satellite laptop with Intel Integrated Graphics. I have found that SSAO works fine in other games written in IntelliJ Idea on the same computer, however I am unaware of anything I did differently in those games that could have any effect on this.

The code to setup lighting is executed in an AppState, however when executed in simpleInitApp() the same issue occurs.

Probally you don’t have all default materials. Internally, SSAOFilter uses “ssao.j3md”:

ssaoMat = new Material(manager, "Common/MatDefs/SSAO/ssao.j3md");

Check if you have this material (which comes preinstalled on SDK :blush:).

No, he’s using the wrong constructor to instantiate a FilterPostProcessor… the tutorials or the javadoc could have been a good place to start, maybe.

http://javadoc.jmonkeyengine.org/com/jme3/post/FilterPostProcessor.html#FilterPostProcessor()

See the first sentence on the docs of the no-arg constructor.

1 Like

And here is the 20 second process I used to find that answer.

  1. Opened the line of the NPE in the stack trace:
public Material(AssetManager contentMan, String defName) {
-->        this((MaterialDef) contentMan.loadAsset(new AssetKey(defName)));
}

The only way for that line to throw an NPE is if contentMan is null. So then I looked at the rest of the stack trace and thought “How does FilterPostProcessor get the AssetManager it is passing around?”

…so I looked a FPP’s constructors and saw the javadoc comment.

1 Like

Also don’t do this, pick one of those but don’t use both.

I did the same thing as well, however I assumed the NullPointerException was occurring due to SSAO.j3md not existing as @afonsolage suggested.

Will do.

No, the only way at all it’s possible to have an NPE on that line is if contentMan is null. There is no other way an NPE could be thrown by THAT line.

…a missing material would have been in a different place and probably a different error. NPEs are easy. An attempt was made to dereference a pointer. In that case, the only pointer dereference in the whole line was to call loadAsset() on contentMan.