[Solved] Lighting up an object (by custom shader) problem

I need to light up an object, I have several copies of it in the scene, so adding an extra parameter to the standard lighting shader won’t solve the problem, it will cause that all objects of this kind will light up. All have the same material. Creating a copy of an material for every object’s instance is a bad idea.

I think that the best way to do it is to make a scene processor and add it to the viewPort. The code is simple (and dirty atm):

public class HighlightRenderer implements SceneProcessor, Savable 
{

    private GeometryList _list;
    private Material _hlMat;
    
    protected RenderManager _renderManager;
    protected ViewPort _viewPort;
    
    public HighlightRenderer(AssetManager assetManager)
    {
        _hlMat = new Material(assetManager, "MatDefs/Light/Highlight.j3md");
        _list = new GeometryList(new OpaqueComparator());
    }
    
    public void setHighlight(Geometry g)
    {
        //_hlGeom = g;
        if (g == null) _list.clear();
        else
        {
            _list.clear();
            _list.add(g);
        }
    }
    
    
    @Override
    public void initialize(RenderManager rm, ViewPort vp) 
    {
        _renderManager = rm;
        _viewPort = vp;
    }    
    
    @Override
    public void preFrame(float tpf) 
    {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void postQueue(RenderQueue rq) 
    {
        if (_list.size() == 0) return;
        
        //_renderManager.setForcedMaterial(_hlMat);
        _renderManager.setForcedTechnique("Highlight");
        
        Camera cam = _viewPort.getCamera();
        _viewPort.getQueue().renderShadowQueue(_list, _renderManager, cam, false);
        
        //_renderManager.setForcedMaterial(null);
        _renderManager.setForcedTechnique(null);
        _renderManager.setCamera(cam, false);
    }    

// ++ Empty overriden methods
}

In standard j3md I put:

    Technique Highlight
    {
        VertexShader GLSL100:   MatDefs/Light/Highlight.vert
        FragmentShader GLSL100: MatDefs/Light/Highlight.frag

        WorldParameters 
        {
            WorldViewProjectionMatrix
            WorldMatrix            
        }

        Defines 
        {    
            
        }

        ForcedRenderState 
        {
            Blend Additive
            DepthTest On
            DepthWrite On          
            PolyOffset -0.1 0
            ColorWrite On
        }
    }

vert and frag:

attribute vec3 inPosition;
uniform mat4 g_WorldViewProjectionMatrix;

void main()
{
    vec4 modelSpacePos = vec4(inPosition, 1.0);
      
    gl_Position = g_WorldViewProjectionMatrix * modelSpacePos;
}

void main()
{
    gl_FragColor = vec4(0.3, 0.3, 0.3, 0.3);
}

The blending is Additive so I guess that the 0.3, 0.3, 0.3 0.3 color should add to the actual color. Instead of that the object is just gray.

What am I doing wrong?

EDIT: If I comment the “PolyOffset -0.1 0” there is no coloring effect at all. Why?

postQueue occurs before rendering, but after queueing. So your highlight effect is being rendered before the model itself is rendered. What you want is postFrame.

Also shadow buckets are deprecated in jME3.1, don’t rely on them.

Damn, it’s late at night here, I was sure that this is one of the ‘stupid’ problems caused by mistake… Ofc I know the difference between postQueue and postFrame…

I’m strongly dependent on the existing JME3.0 mechanics, so I’ll continue to use shadow buckets. All of my renderers use it.

Thank you for the answer, now everything looks good :wink:

Well, there is a third option that is not so extreme:
Have one regular Lighting material for the regular items.
Have one highlght-modified Lighting material for the objects with highlights (the extra parameter that you avoided).

…then switch from one material to the other as needed.

It seems like that would be a lot less overhead than what you are attempting now.

Bad idea, I have torches, rocks, swords, armors and all that stupid ‘adventure’ items, every kind of an object have it’s own material, there will be over an hundred of them. I was thinking about making a copy of an material just for the case of highlighting particular object and putting it back to the object just when the highlight is off… Too many memory allocations just because a player moves his mouse and point to something on the ground. And too many possible an error-causing situations.

The ‘shader solution’ looks clean, just a next processor on the scene, next to all the ShadowRenderers, and for 99.9999% of the time it just do nothing.

Ah, I missed that only one object can be highlighted at a time.