Particles not showing through transparent sheet

Hey everyone,



I have a particle effect running that that I’m trying to look at through a transparent Box. However, when I move behind the transparent box, the particles disappear. If I have a clear view of the particles without any transparent objects in front, it works fine.



I have set the following properties on the emitter:



Material mat = new Material(Scene.getSceneAssetManager(), “Common/MatDefs/Misc/Particle.j3md”);

mat.setBoolean(“m_PointSprite”, true);

mat.setTexture(“m_Texture”, Scene.getSceneAssetManager().loadTexture(“Effects/Smoke/test.png”));

mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);

mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);

mat.getAdditionalRenderState().setAlphaTest(true);

emitter.setMaterial(mat);

emitter.setQueueBucket(RenderQueue.Bucket.Transparent);



Any insight into why they are not showing would be great. I saw something mentioned in the forums from a couple years back about a the z buffer but I’m not sure if it’s relevant anymore since the linked wiki page is gone

Are the particles inside the box or just behind it? I assume the box is also in the transparent bucket?



This is definitely Z-buffer related. The transparent box is drawn first and fills the z buffer with nearer values than the particles. The transparent bucket is sorted by distance to render back to front. So something is causing this not to work in this case… the likeliest cause being that the particles appear to the engine to be closer for some reason.

The particles are behind the box, and the box is in the transparent bucket.



I also have water, and the water is visible as well as the reflection of the particles in the water, just not the particles themselves.



However, the water is not the issue since the same problem occurs without water.



I have written a test application to demonstrate the problem. Simply fly the camera above the particles and the plane and you’ll see the particles get clipped out and flicker sometimes. Maybe z-buffer fighting each other like you mentioned:

pre type="java"
import com.jme3.app.SimpleApplication;


import com.jme3.effect.EmitterSphereShape;


import com.jme3.effect.ParticleEmitter;


import com.jme3.effect.ParticleMesh.Type;


import com.jme3.material.Material;


import com.jme3.material.RenderState.BlendMode;


import com.jme3.material.RenderState.FaceCullMode;


import com.jme3.math.ColorRGBA;


import com.jme3.math.Vector3f;


import com.jme3.renderer.queue.RenderQueue;


import com.jme3.scene.Geometry;


import com.jme3.scene.shape.Box;


import com.jme3.util.SkyFactory;





public class TestParticleWithTransparency extends SimpleApplication


{





    public static void main(String[] args)


    {


        TestParticleWithTransparency app = new TestParticleWithTransparency();


        app.start();


    }





    @Override


    public void simpleInitApp()


    {


        flyCam.setMoveSpeed(6);





        ParticleEmitter emit = new ParticleEmitter(“Emitter”, Type.Triangle, 200);


        emit.setShape(new EmitterSphereShape(Vector3f.ZERO, 1f));


        emit.setGravity(0);


        emit.setLowLife(5);


        emit.setHighLife(10);


        emit.setInitialVelocity(new Vector3f(0, 0, 0));


        emit.setImagesX(15);


        emit.setSelectRandomImage(false);


        Material mat = new Material(assetManager, “Common/MatDefs/Misc/Particle.j3md”);


        mat.setTexture(“Texture”, assetManager.loadTexture(“Effects/Smoke/Smoke.png”));


        mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);


        mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);


        mat.getAdditionalRenderState().setAlphaTest(true);


        emit.setMaterial(mat);


        emit.setQueueBucket(RenderQueue.Bucket.Transparent);





        rootNode.attachChild(CreateCube(“glassWall”, new Vector3f(0, 1f, 0), new Vector3f(3f, 0.001f, 3f), new ColorRGBA(1.0f, 0.7f, 0f, 0.2f), true));


        rootNode.attachChild(emit);


        rootNode.attachChild(SkyFactory.createSky(assetManager, “Textures/Sky/Bright/BrightSky.dds”, false));





    }





    private Geometry CreateCube(String name, Vector3f pos, Vector3f size, ColorRGBA color, boolean isTransparent)


    {


        Box box = new Box(pos, size.x, size.y, size.z);


        Geometry cube = new Geometry(name, box);


        Material mat1 = new Material(assetManager, “Common/MatDefs/Misc/SolidColor.j3md”);


        mat1.setColor(“Color”, color);


        mat1.setReceivesShadows(false);


        cube.setMaterial(mat1);


        if (isTransparent)


        {


            mat1.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);


            mat1.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);


            mat1.getAdditionalRenderState().setAlphaTest(true);


            cube.setQueueBucket(RenderQueue.Bucket.Transparent);


        }


        return cube;


    }


}
/pre

this is a depth write issue.

The particles material does not write depth to avoid to have to sorts the particles and kill the performances.



you could set the write depth to true to the material, but i’m afraid it will result in artifacts.

I’m gonna look at your test case.

Note: writing depth shouldn’t be an issue in this case, right? If the particles were drawn first then the transparent cube would be drawn on top and everything would be ok.



The particles do use depth test… which is what’s causing the issue since they are drawn after the cube. But I think depth test is necessary or you really will get weird errors.



Transparent sorting will never be 100% correct but I couldn’t tell from the above why they are being sorted wrong… at least not a quick glance.

We can’t write depth for particles, as then we would also have to sort them back to front which would be very slow.

Yea that makes sense, it’s kind of an either/or situation. Rendering magic always has a price.