Highlighting effect


I want to get a highlighting effect when a character hits a monster. Should I add something to a shader or I can make it with code(for example, with ambient light)?

Example of highlighting is here:



cant you just add AmbientLight to node contained monster?

same with gui highlighting… im adding AmbientLight to gui element, and it is highlighting… if i bad understand you, then sorry

about shader i can tell nothing, but light work as you said

I think a model will be overlighted if you already have ambiend + directional in a scene.

but light in subnode highlight only that subnode. You know what i mean. and more lights are summing somehow

i tested it and it work for me. I have highlight done :slight_smile: JME is so great

can you show a screenshot?

Can you try your test with another ambient light attached to the rootnode?



Do you mean 2 ambient lights in root node? it only give a sum… like a one stronger ambient light. What do you mean by another?

thanks. but it look not like in the video above. :frowning:

@mifth why not trying with rim lighting


it seems you integrated it in your shader pack.

try with white light and high power

oo, i have forgotten about it. thanks!

Guys, I did this effect with ambient light.

Here is my simple test (notice that Blue value of ambient_selection Color is NEGATIVE):


import com.jme3.app.SimpleApplication;

import com.jme3.collision.CollisionResults;

import com.jme3.font.BitmapText;

import com.jme3.input.MouseInput;

import com.jme3.input.controls.ActionListener;

import com.jme3.input.controls.MouseButtonTrigger;

import com.jme3.light.AmbientLight;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Ray;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.Box;

import com.jme3.system.AppSettings;

public class SelectObject extends SimpleApplication implements ActionListener{

public static void main(String[] args) {

SelectObject app = new SelectObject();



Geometry geom;

Node nd_selection;

Node scene;

Node sub_scene;


public void simpleInitApp() {


Box b = new Box(Vector3f.ZERO, 1, 1, 1);

geom = new Geometry("Geom", b);


Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");



DirectionalLight dl = new DirectionalLight();

dl.setDirection(new Vector3f(-0.8f, -0.6f, -0.08f).normalizeLocal());

dl.setColor(new ColorRGBA(0.9f,0.9f,0.9f,1.0f));


AmbientLight al = new AmbientLight();

al.setColor(new ColorRGBA(0.7f,0.9f,1.5f,1.0f));


scene = new Node("scene");

sub_scene = new Node("sub_scene");

nd_selection = new Node("nd_selection");

AmbientLight al_selection = new AmbientLight();

al_selection.setColor(new ColorRGBA(1.75f,1.2f,-0.95f,1.0f));






inputManager.addMapping("FIRE", new MouseButtonTrigger(MouseInput.BUTTON_LEFT));

inputManager.addListener(this, "FIRE");





public void onAction(String name, boolean isPressed, float arg) {

if (name.equals("FIRE") && isPressed){

CollisionResults crs = new CollisionResults();

scene.collideWith(new Ray(cam.getLocation(), cam.getDirection()), crs);

if (crs.getClosestCollision() != null){

System.out.println("Hit at "+crs.getClosestCollision().getContactPoint());

if (!geom.hasAncestor(nd_selection)) {

System.out.println("Geom is attached to nd_ambien node");




else {

if (geom.hasAncestor(nd_selection)) {

System.out.println("Geom is attached scene node");






protected void initCrossHairs() {

guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");

BitmapText ch = new BitmapText(guiFont, false);

ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);

ch.setText("+"); // crosshairs

ch.setLocalTranslation( // center

settings.getWidth()/2 - guiFont.getCharSet().getRenderedSize()/3*2,

settings.getHeight()/2 + ch.getLineHeight()/2, 0);


BitmapText ch2 = new BitmapText(guiFont, false);


ch2.setText("Click to select");

ch2.setColor(new ColorRGBA(1f,0.8f,0.1f,1f));





public void simpleUpdate(float tpf)




1 Like

The way you do it is dangerous

you detach the picked object from it’s parent and attach it to a “selection node”

What if the picked object is not directly attached to the rootNode, but has a parent node that has locatTransforms etc…

Your object will “loose” its world transforms when you pick it

@nehon , you are right. So what is the best way? what would you recommend?

Possibly, I should attach this ambient light to every node(object)?

yeah, unless you have several object that can be selected, you can have just one ambient light and set it to the selected Node.

What about the rim lighting approach? IMO it would be better since you would have to just set a parameter to the selected geometry material

if I use rim lighting, so I should make every material separate. That’s not good for me as I have many instances with the same mesh and material. But if there will be no other way, so i’ll be using the rim lighting.

What’s better? 100 cloned ambient lights or 100 cloned materials?

I think that ambient lights will be better for productivity.

@mifth said:
if I use rim lighting, so I should make every material separate. That's not good for me as I have many instances with the same mesh and material.

erf... you're right.
@Momoko_Fan, is there a way to send custom param to a material per geometry? If not could be nice to have something similar to userData, but for each entry it would set a uniform.

@mifth for now stick to the ambientLight method, but just set the ambient light to the selected geom, and don't change the geom's parent.
@mifth said:
What's better? 100 cloned ambient lights or 100 cloned materials?
I think that ambient lights will be better for productivity.

Actually you can set the same light to several geometries, you don't have to clone it

I get you, thanks!

Just clone the material, it will use up like 1 KB more memory but performance wise its the same.