Where to start for making a halo or glow FX with GLSL shaders?


using the RenderMonkey I found the "evil" project containing a vert and frag file called "corona".

These files requires as uniform input some vector4, but setUniform does not accept any Vector4f…

please please can you give me some hint to make a halo or glow FX?  :)  :smiley:

Have you treid if the official drivers from amd works with it as well?

you can use the setUniform() that takes 4 floats.

This is an interesting effect. Will you post the JME implementation here ?

Yes, but for now it’s the usual simple glow effect applied to a sphere: a flat panel or a billboard with an alpha texture simulating the glow.

Sample glow image:

With GLSL I tried to implement the shader of the glow I found in the AMD RenderMonkey,

but I am not able to make it working with all right uniform parameters :x


I disabled the GLSL via “this.createQuadGlow(false)” placed in the constructor.

Unfortunately I cannot use the SceneWorker for playing directly with uniform values

because it re-compiles GLSL only using LGWL, which is causing an out of memory

error when used for SimpleGame with my ATI graphic board.

In the meanwhile I start for reading the Orange Book  :stuck_out_tongue:

Test class

package glsl.test;

import java.util.logging.Logger;

import com.jme.app.SimpleGame;
import com.jme.image.Texture;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Quad;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;

public class TestShader extends SimpleGame  {
    private static final Logger LOGGER = Logger.getLogger(TestShader.class.getName());
    private PointLight pointLight;
    public static void main(String[] args) {
        TestShader app = new TestShader();

    protected void simpleInitGame() {
        super.display.setTitle("Glow GLSL");
        super.cam.setLocation(new Vector3f(0, 0, 20));
        pointLight = new PointLight();
        pointLight.setDiffuse(new ColorRGBA(1.0F, 1.0F, 0.25F, 1.0F));
        pointLight.setAmbient(new ColorRGBA(0.5F, 0.5F, 0.5F, 1.0F));
        pointLight.setLocation(new Vector3f(0F, 10F, 100F));

        final LightState lightState = DisplaySystem.getDisplaySystem().getRenderer().createLightState();
        Sphere glowObject = this.createGlowObject();
        Quad quadGlow = this.createQuadGlow(false);

        SceneMonitor.getMonitor().registerNode(rootNode, "root");*/
    private Quad createQuadGlow(final boolean enableGl) {
        final float fixedQuadSize=5F;
        Quad quadGlow = new Quad("simpleGlowPlane",fixedQuadSize,fixedQuadSize);
        quadGlow.getLocalTranslation().set(0F, 0F, 9.5F);
        // Check is GLSL is supported on current hardware.
        if (!GLSLShaderObjectsState.isSupported()) {
            LOGGER.severe("Your graphics card does not support GLSL programs, and thus cannot run this test.");

        final TextureState ts = display.getRenderer().createTextureState();
        Texture texBase = TextureManager.loadTexture(

        GLSLShaderObjectsState so = display.getRenderer().createGLSLShaderObjectsState();
        so.setUniform("coronaSize", fixedQuadSize);
        so.setUniform("strength", 2.5F);
        so.setUniform("coronaExp", 10.4F);
        float[] fPos = new float[4];
        float[] fCamDir = new float[4];
        so.setUniform("pos0", fPos, false);
        so.setUniform("coronaDir", new float[]{0F,0F,1F,0F}, false);
        so.setUniform("view_direction", fCamDir, false);
        so.setUniform("lightColor", new float[]{1F,0F,1F,1F}, false);
        so.setUniform("GlowTex", 0);
        return quadGlow;
    private Sphere createGlowObject() {

        final TextureState ts = display.getRenderer().createTextureState();
        Texture texBase = TextureManager.loadTexture(

        Sphere sphere = new Sphere("glslSphere#0", 32,32, .5F);
        sphere.getLocalTranslation().set(0F, 0F, +10F);
        return sphere;

    protected void simpleUpdate() {}
    protected void simpleRender() {}

    protected void cleanup() {super.cleanup();}


uniform vec4 pos0;         // location of screen aligned quad
uniform float coronaSize;  // size of screen aligned quad (currently 16.0)

// output variables for Fragment Program.
varying vec2 vTexCoord;

void main(void)
   // Grab X and Y eye-space vectors in world-space ...
   // NOTE: OpenGL stores matrixes as column major, DirectX stores then row major.
   //       So here, we need to extract the rows we need...the D3D version of this
   //       shader is a touch simplier.
   vec3 dirX = vec3(
   vec3 dirY = vec3(

   // ... which are used for billboarding
   vec3 pos    = vec3(pos0) + coronaSize * (gl_Vertex.x * dirX + gl_Vertex.y * dirY );
   gl_Position = gl_ModelViewProjectionMatrix * vec4(pos,1.0);
   vTexCoord   = 0.5 * gl_Vertex.xy + 0.5;



uniform float strength;
uniform vec4 coronaDir;
uniform vec4 view_direction;
uniform sampler2D GlowTex;
uniform float coronaExp;
uniform vec4 lightColor;
uniform float constAtt;
uniform float sqrAtt;

// input variables from Vertex Program.
varying vec2 vTexCoord;

float saturate( float inValue)
   return clamp( inValue, 0.0, 1.0);

void main(void)
   vec4 corona  = texture2D(GlowTex, vTexCoord);
   // view directoin is set up for the handedness, we need to flip it for ogl.
   vec3 vdir    = vec3(view_direction.x, view_direction.y, view_direction.z);
   vec3 cdir    = vec3(coronaDir.x, coronaDir.y, coronaDir.z);

   // Glow depending on cosine (dotprod) with "corona directon"
   float glow   = saturate(dot(vdir, cdir));

   gl_FragColor = strength * pow(glow, coronaExp) * corona * lightColor;  

SteelPlume said:

Unfortunately I cannot use the SceneWorker for playing directly with uniform values
because it re-compiles GLSL only using LGWL, which is causing an out of memory
error when used for SimpleGame with my ATI graphic board.

i'm using an ati also and i've got no problem recompiling...
can you try upping the heap size maybe?
i execute scene worker with -Xms256m -Xmx512m
that might be the problem...
ncomp said:

i'm using an ati also and i've got no problem recompiling...

No, I mean that the LGWL rendering driver is intercepting an out of memory before to start any SimpleGame, not SceneWorker. This simply tries to recompile with LGWL support any scene rendered in JOGL. If I had LGWL working with my buggy video driver, I could try any GLSL fx directly in JMonkey...  :mrgreen:

Anyway, I am really struggling with my buggy video driver which encounters too many times the out of memory error, eg if I use BloomPass and I go fullscreen, then I obtain an out of memory, but when BloomPass has been disabled all works well.

Just out of intrest what graficcard are you useing?

Empire Phoenix said:

Just out of intrest what graficcard are you useing?

Just in time to say that I own a fu*** ATI Mobility Radeon X2500 video card. I just installed a new driver from Asus, rebooting and Vista magically hangup... damn it! :cry:

So until when I hadn't solved this f*** problem, I  will use a SuSE dist with all its billion of tons of rpm updates to configure correctly my f***ing opengl card, really I would like to throw my notebook in the basket beating it like a bongo  :D .. I am desperated  :x

For what I know the safe mode runs the base and official driver, is it?

Unfortunately, the problem is that also the safe mode appears "unbootable", in fact pressing F8 the system makes a reboot instead of showing the safe mode menu.

Pressing F9 shows the Vista repair mode, but it is unbootable, really a bloodbath… so Vista will Rest in Peace until and beyond Xmas.

Now I descend in another blooddrain, I will try to install the ATI GL driver for linux, I remember that exactly 1 years ago the driver was the cause I passed on Vista, I wish the driver has changed  :expressionless: