Glow on top of everything

Hello,

I have trouble with glow filter - it’s applied not only on visible part of quad but on an invisible one too (see screenshot - lower half of the burst is actually inside spatial, but glow is still shown). How to fix that? Thanks.

I presume the quad is in the wrong bucket.

http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:jme3_renderbuckets

Quad is made of Unshaded.j3md with setFaceCullMode.Off (to be able to see it from any point). I tried different BlendModes, with AlphaTest/DepthTest/DepthWrite set to true - still no luck. So little info about Render Buckets… at least couple of code snippets would be nice to illustrate the topic :stuck_out_tongue:
I know (more or less) how postprocessing is done in 3ds Max - 1st it renders the frame, then filters are applied on visible parts (with glow materal channel preset). Here it looks kinda different…

Set it in the quad’s material:

GlowColor : 0.0 0.0 0.0 1.0

RIght, but there’s no glow at all anymore this way :slight_smile: and I still would want it on visible part of the quad.

What’s the invisible part of the quad?
The glow filter renders everything that has a glow color or a glow map in an offscreen buffer, then applies a blur on it, then modulate the result with the back buffer.

So this means if I don’t want to see the whole Quad’s glow I will really need another rendering pass afterwards and I need to put there all the things that can be partially ahead of glowed objects… well, thanks, at least this gives an idea of how it works now.

No, it should work like you want if the quad is properly obscured by depth.

Something is odd with your scene setup but the code looks fine from what we can see. :wink:

From what I remember, certain OpenGL statement realizations can be GPU driver dependent. Probably shall test the code on different machine.

hint hint show your code hint hint. Nobody can find a bug without a forest in which to forage.

Tried it on linux/64 machine, same story. Well let’s examine the code (I won’t put the whole files as that would be kilometers of flood but will try to extract what can possibly relate to the render):

Main.java

 public Main()
        {
            super(  new StatsAppState(),                // display scene stats
                    ...
                    new SystemModelState(new SystemModelFactory()), // model management
                    ...
        }

| - the above mechanics courtesy of pspeed

public void simpleInitApp() {
...
        fpp = new FilterPostProcessor(assetManager);
        viewPort.addProcessor(fpp);
        BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Objects);
        bloom.setDownSamplingFactor(UtilConstants.BloomDownSamplingFactor);    
        bloom.setBlurScale(UtilConstants.GlowBlurScale); 
        bloom.setBloomIntensity(UtilConstants.GlowBloomIntensity);
        fpp.addFilter(bloom);

SystemModelState.java

protected void initialize( Application app ) {

        factory.setState(this);
        this.app = app;

       ...
        modelRoot = new Node("Model Root");
        
        // Creating global lights
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-2,2,-20).normalizeLocal());
        sun.setColor(ColorRGBA.White);
        modelRoot.addLight(sun);
        
        DirectionalLight sun2 = new DirectionalLight();
        sun2.setDirection(new Vector3f(-20,-200,10).normalizeLocal());
        sun2.setColor(ColorRGBA.White);
        modelRoot.addLight(sun2);
        
        Spatial starfield = app.getAssetManager().loadModel("Scenes/starfield.j3o");
        modelRoot.attachChild(starfield);
       ...

SystemModelFactory.java

public class SystemModelFactory implements InterfaceModelFactory
{
...
 public Spatial createModel(Entity e)
    {
     ....
    if (MODEL_TEST_SHIP.equals(type.getType()))
           {
            Node shielded_ship = new Node();
            Spatial spatial2 = assetManager.loadModel("Models/glider/glider.j3o");
            spatial2.scale(UtilConstants.UniformScale);
            shielded_ship.attachChild(spatial2);
            
            Sphere shield = new Sphere(18,18,1.1f);
            Geometry g = new Geometry("Shield", shield);
            Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md");
            mat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Solid_32th_trans.png"));
            mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
            mat.getAdditionalRenderState().setAlphaTest(true);
            mat.getAdditionalRenderState().setAlphaFallOff(0.02f);
            g.setQueueBucket(RenderQueue.Bucket.Transparent);
            g.setMaterial(mat);
            g.move(0f, -0.3f, 0f);
            shielded_ship.attachChild(g);
            
            return shielded_ship;
}
        if (
                MODEL_MISSILE.equals(type.getType()) 
           )
           {
            Node flaming_missile = new Node();
            Spatial spatial = assetManager.loadModel("Models/missile/missile.j3o");
            spatial.scale(UtilConstants.UniformScale);
            flaming_missile.attachChild(spatial);
            
            ParticleEmitter fireEmitter = new ParticleEmitter("Test fire",
                    ParticleMesh.Type.Triangle,
                    UtilConstants.IgnitionTrianglesTotal);
            Material fireMat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
            fireEmitter.setMaterial(fireMat);
        
            fireMat.setTexture("Texture", assetManager.loadTexture("Effects/Explosion/flame.png"));
            fireEmitter.setImagesX(2);
            fireEmitter.setImagesY(2);
            fireEmitter.setSelectRandomImage(true);
            fireEmitter.setRandomAngle(true); 
        
            fireEmitter.setStartColor(UtilConstants.IgnitionCoreColor);
            fireEmitter.setStartSize(UtilConstants.IgnitionStartSize);
            fireEmitter.setEndColor(UtilConstants.IgnitionPeripheralColor);
            fireEmitter.setEndSize(UtilConstants.IgnitionEndSize);
        
            fireEmitter.setGravity(0, 0, 0);
        
            fireEmitter.getParticleInfluencer().setInitialVelocity(new Vector3f(0,0,-0.1f));
            fireEmitter.getParticleInfluencer().setVelocityVariation(0.1f);
            
            flaming_missile.attachChild(fireEmitter);
            
            return flaming_missile;
           }
if (
                QUAD_BURST_BLUE.equals(type.getType())
           )
            {
            Quad burst = new Quad(UtilConstants.IonBurstWidth, UtilConstants.IonBurstLength);
            Geometry geom = new Geometry("Burst", burst);
            geom.setIgnoreTransform (false);
            Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
            mat.setColor("Color", UtilConstants.IonBurstColor);
            mat.setColor("GlowColor", UtilConstants.IonBurstColor);
            geom.setMaterial(mat);
            geom.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
            geom.setQueueBucket(RenderQueue.Bucket.Transparent);
            geom.getMaterial().getAdditionalRenderState().setAlphaTest(true);
            geom.getMaterial().getAdditionalRenderState().setDepthWrite(true);
            geom.getMaterial().getAdditionalRenderState().setDepthTest(true);
            
            geom.getMaterial().getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha); 
            
            Geometry otherGeom = geom.clone();
            otherGeom.setLocalTranslation(0, 0, UtilConstants.IonBurstWidth);
            otherGeom.setLocalRotation(new Quaternion().fromAngles (0, FastMath.HALF_PI, 0));
            otherGeom.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);

            Node x_ray = new Node();
            geom.setLocalTranslation( -UtilConstants.IonBurstWidth / 2.f, 0, UtilConstants.IonBurstWidth / 2.f);

            x_ray.attachChild(geom);
            x_ray.attachChild(otherGeom);
            return x_ray;
            }

I believe the rest is logic, cams, hud etc.