Fix transparent unshaded materials + SSAO

Hi,

I’ve realized that having transparent unshaded materials in a scene with ssao filter (or any other requiring the PreNormalPass) renders badly:


Left side is using unshaded and right uses lighting. Notice the dark blue front side of the left box.

This is the simple testcase:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.ssao.SSAOFilter;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        cam.setLocation(new Vector3f(0,5,10));
        cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
        flyCam.setDragToRotate(true);
        
        DirectionalLight dl0=new DirectionalLight(new Vector3f(0,-5,-10));
        rootNode.addLight(dl0);
        
        // Floor
        Box bFloor = new Box(100, 0.1f, 100);
        Geometry geomFloor = new Geometry("Box", bFloor);

        Material matFloor = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        matFloor.setColor("Color", ColorRGBA.Red);
        geomFloor.setMaterial(matFloor);

        rootNode.attachChild(geomFloor);
        
        // Unshaded transparent object (on the left)
        Box bObject1 = new Box(1, 1, 1);
        Geometry geomObject1 = new Geometry("Box", bObject1);
        geomObject1.setLocalTranslation(-2, 1, 0);

        Material matObject1 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        matObject1.setTexture("ColorMap", assetManager.loadTexture("Textures/tex.png"));
        matObject1.setFloat("AlphaDiscardThreshold", 0.5f);
        matObject1.setTransparent(true);
        
        geomObject1.setMaterial(matObject1);

        rootNode.attachChild(geomObject1);
        
        // lighting transparent object (on the right)
        Box bObject2 = new Box(1, 1, 1);
        Geometry geomObject2 = new Geometry("Box", bObject2);
        geomObject2.setLocalTranslation(2, 1, 0);

        Material matObject2 = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        matObject2.setTexture("DiffuseMap", assetManager.loadTexture("Textures/tex.png"));
        matObject2.setFloat("AlphaDiscardThreshold", 0.5f);
        matObject2.setTransparent(true);
        
        geomObject2.setMaterial(matObject2);

        rootNode.attachChild(geomObject2);
        
        FilterPostProcessor fpp=new FilterPostProcessor(this.getAssetManager());
        SSAOFilter ssao=new SSAOFilter();
        fpp.addFilter(ssao);
        viewPort.addProcessor(fpp);
    }

}

The issue is caused because unshaded material is not setting the diffusemap_alpha for the PreNormalPass

Unshaded:

Lighting:

I’m creating a PR to fix this

EDIT: PR created → Unshaded PreNormalPass fix by joliver82 · Pull Request #1512 · jMonkeyEngine/jmonkeyengine · GitHub

5 Likes

I’ve just noticed that PBRlighting also doesn’t define the map for PreNormalPass, so may fail the same way

4 Likes

Updated the PR to fix PBRlighting also

4 Likes

Thanks, @joliver82

@Ali_RS is this topic related to:

1 Like

IIRC it is a different issue related to FXAA filter removing transparency. I noticed it when I was using it with my icon generator, the resulting PNG texture had no transparency.

But thanks for bringing it up.

@joliver82 may I ask about your opinion on the proposed change to the shader on that topic?

Sure, I’m answering in the other topic

1 Like