Adding optional ambient lighting to Particle.j3md shader

I recently had the idea to try to modify the particle shader to add a new define named IS_LIT that, when true, would apply super-basic lighting to the final particle color using the ambient light as a simple multiplier to the final color. So there would be no effect from the directional light (since directional lighting would obviously not work well with billboard particles that have their world normal constantly fluctuating based on the camera position/direction) but this would allow particles being used to represent special effects that do not double as a light source to become naturally dark at night.

Lately I’ve been thinking about this a lot, because I have some particle effects that are representing effects (like water or smoke) that do not emit light, and thus need to be darker at night to appear realistic and not break the immersion of night.

For other particle effects like fire and magical effects that appear to emit light from themselves, the boolean could just be left false and the particle effect will work like it normally does without using the ambient light.

Any thoughts on if this idea would work or if it would potentially cause some other issues or severely slow down the framerate in a way i may not be considering?

I plan to make my own fork of Particle.j3md to try this and would be glad to submit a PR if this turns out to be a good idea that others are interested in too, but I have not worked on the side of shaders that involves passing lights like an AmbientLight into the shader, so I could use some guidance and am interested to hear more input on the idea before I jump in.

Thanks :slightly_smiling_face:

i would need research it myself, but if you say it break the immersion of night, there should be some way instead of creating custom material.

im not sure for what [purpose/element] this particle emitter is used in your case(fire/magic sounds like it should lit), but cant use some PBR material, or default Lightning one? i dont remember what Particle.j3md made special for particles(except special visual), but i assume it should be ok to use other materials like mentioned ones, right?

Can’t particle color be used for this?

I admit that I don’t remember much about JME’s particles. I do remember this much though…

The perspective size foreshortening is all done in the shader. Without it, particles are all the same size all the time.

I’m using a particle emitter to represent rushing water coming out of a geyser, so it looks unusual when its night and is still the same bright water color as in the day time. I also don’t think it would be a good idea to reuse Lighting.j3md or PBRLIghting for a particle effect since they both rely on normal values for directional lighting and that would probably look unnatural with a billboard based particle system since the particles rotate and have their normal changed based on camera position. But using just the ambient light would be enough to scale the particle’s brightness without doing anything too complex.

Yes although I didn’t think that would be the best solution on a larger scale since that would require extra java code to keep track of every particle emitter’s original start color and end color in order to update the actual start and end color to match the ambient light’s brightness when the time changes, and that would also require re-registering a particle emitter’s original colors anytime you want to change its color (my game has many emitters for things like water that can be blue when they’re clean but interpolate to green when they get dirty, so anytime the color changes slightly, I’d also have to call extra code to set the new originalStart and originalEnd color values or risk breaking the lighting effect)

So I thought it would be a cleaner solution to modify Particle.frag to take in the AmbientLight and if it has a define like USE_AMBIENTLIGHT it would run a single line of code to multiply the ambient light by its current color, without requiring any java code to keep track of original colors.

But I don’t quite know what code I need to use to to pass in an ambient light into a shader, most of my shader knowledge is based on forking .frag .vert and .j3md files from other JME shaders that already handled the lighting and techniques. I see that some other shaders use a g_AmbientLight variable, but I don’t know enough to know what I’d need to change for Particle.j3md to have access to that variable.

I don’t know enough about the particle code but if the color is interpolate from the start and end values every frame or whatever… then you can check and see if they hold their own copy of the color for start/end or just set the instance.

If they just set the instance then you could one instance for all of them as your “ambient” color. You’d have to make sure you weren’t using color for anything else, though.

But it might also be easier to just add an ambient color material parameter and not worry about the light stuff.

1 Like

Note: I do not know much about the TechniqueDef logic so will appreciate it if someone corrects me if my below statement is wrong.

Afaik lights (including g_AmbientLightColor) are calculated and passed to the shader via the lighting logic defined here:

the “LightMode” specified in the material def decides which lighting logic to be used.

If LightMode is not set (Disabled) (e.g. in the Particle.j3md) then it will use “DefaultTechniqueDefLogic” which does not set any lighting info I think.

So I think you either need to activate the LightMode in Particle.j3md to be able to access scene light info in the shader or otherwise just add an ambient color material parameter as pspeed said. I guess the latter will be more efficient in your case.

1 Like