Problem setting RenderState.BlendMode.Off on ParticleEmitter

Hi,
experimenting with particle effects, I noticed that by changing the default ‘BlendMode’ of the ‘particle material’ from Off to Alpha and then back to Off, something seems to break.

In short, setting the BlendMode.Off after changing it once, the effect no longer works correctly. Could this be a bug?

-

Here is the test case:

package com.test.main;

import com.jme3.app.SimpleApplication;
import com.jme3.effect.ParticleEmitter;
import com.jme3.effect.ParticleMesh;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.system.AppSettings;

/**
 * 
 * @author capdevon
 */
public class Test_BlendModeIssue extends SimpleApplication {

	private ParticleEmitter emit;
	private float angle = 0;
	private float timer;
	private float refreshRate = 1f;
	private int mIndex = 0;
	private BlendMode[] modes = { BlendMode.Off, BlendMode.Alpha };

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		AppSettings settings = new AppSettings(true);
		settings.setResolution(800, 600);

		Test_BlendModeIssue app = new Test_BlendModeIssue();
		app.setShowSettings(false);
		app.setPauseOnLostFocus(false);
		app.setSettings(settings);
		app.start();
	}

	@Override
	public void simpleInitApp() {
		flyCam.setDragToRotate(true);
		flyCam.setMoveSpeed(20);

		viewPort.setBackgroundColor(ColorRGBA.DarkGray);

/* --not required
		DirectionalLight sun = new DirectionalLight();
		sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
		sun.setColor(ColorRGBA.White);
		rootNode.addLight(sun);
*/
		createParticleEmitter();
	}

	@Override
	public void simpleUpdate(float tpf) {
		timer += tpf;
		if (timer > refreshRate) {
			timer = 0;
			mIndex = (mIndex + 1) % modes.length;
			BlendMode bm = modes[mIndex];
			fpsText.setText("BlendMode: " + bm.toString());
			emit.getMaterial().getAdditionalRenderState().setBlendMode(bm);
		}

		angle += tpf;
		angle %= FastMath.TWO_PI;
		float x = FastMath.cos(angle) * 2;
		float y = FastMath.sin(angle) * 2;
		emit.setLocalTranslation(x, 0, y);
	}

	private void createParticleEmitter() {
		emit = new ParticleEmitter("Emitter", ParticleMesh.Type.Triangle, 300);
		Material mat = new Material(assetManager, "Common/MatDefs/Misc/Particle.j3md");
		mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png"));
		emit.setGravity(0, 0, 0);
		emit.getParticleInfluencer().setVelocityVariation(1);
		emit.getParticleInfluencer().setInitialVelocity(new Vector3f(0, .5f, 0));
		emit.setLowLife(1);
		emit.setHighLife(1);
		emit.setImagesX(15);
		emit.setMaterial(mat);
		rootNode.attachChild(emit);

		System.out.println("Default BlendMode: " + mat.getAdditionalRenderState().getBlendMode());
	}
}

Edit:

Right, directional light does not affect the test.

1 Like

Also happens when setting it directly to Off without setting it to something else first.
The DirectionalLight doesn’t seem involved.

quickly tested with jme 3.3.2 stable, 3.4.1 stable
3.5.0-beta4 had problems finding liblwjgl.so

2 Likes

@capdevon and @1000ml:

Without knowing the root causes of these behaviors, it’s hard to decide whether they are bugs or not.

Since it’s been 3 days and the root causes are still (as far as I know) unknown, please open issues at GitHub for both behaviors:

  1. the effect looking different and
  2. inability to find “liblwjgl.so” (on which platform?)
1 Like

@capdevon does it happen also with other material types like Lighting.j3md or only happens with Particle.j3md?

Hi Stephen, here it is:

1 Like

I have not noticed any malfunctions with Lighiting.j3md

1 Like

I tried to understand more, in the Particle.j3md file, all RenderState{} blocks have BlendMode.AlphaAdditive by default.

The javadoc of the RenderState class suggests using the following modes for particle effects:

  • Additive
  • AlphaAdditive

It is probably correct that particle effects do not work correctly with BlendMode.Off

2 Likes

That makes sense. The additive blending modes are order-independent. For other modes, in order for blending to look good, the fragments need to be sorted back-to-front. Sorting lots of moving particles every frame is costly.

Now since the blending mode is initialized to AlphaAdditive, I think this is expected behavior.

What I find suspicious though, is that mat.getAdditionalRenderState().getBlendMode() doesn’t reflect the initial value. After creating a Material with Particle.j3md it returns BlendMode.Off.

2 Likes

I have some suspicions about it too, but i don’t know if this is a deliberate behavior.

1 Like

Where does the value get changed?

maybe here