Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

11991 Posts in 1587 Topics- by 3507 Members - Latest Member: PienueDut

26. May 2012, 12:44:54 pm
Xith3D CommunityGeneral CategorySupport (Moderator: Marvin Fröhlich)Glowing like in the Eighties
Pages: [1]
Print
Author Topic: Glowing like in the Eighties  (Read 1347 times)
fbommeau
Just dropped in

Offline Offline

Posts: 8



View Profile
« on: 24. October 2009, 11:53:04 am »

Hi,

What is the way to make a simple scenegraph primitive (let say a org.xith3d.scenegraph.primitives.Line for example), flat colored, appeared as glowing (juste like neon, with a color halo around it).
I (unsuccessfully) tried bloom  factory, emissive color. I'm not very keen on shaders, materials, so I don't know where to begin ...

Thanks for lending me a hand on this !

-- Franck
« Last Edit: 24. October 2009, 02:07:37 pm by fbommeau » Logged

-- Too much of a good thing is wonderful (except OpenGL calls).
(Mae West turned geek)
fbommeau
Just dropped in

Offline Offline

Posts: 8



View Profile
« Reply #1 on: 27. October 2009, 06:59:02 am »

Nobody has an idea on how to do this ?
Logged

-- Too much of a good thing is wonderful (except OpenGL calls).
(Mae West turned geek)
Marvin Fröhlich
Xith Lord
Administrator
Guru
*****
Offline Offline

Posts: 4381


May the 4th, be with you...


View Profile
« Reply #2 on: 27. October 2009, 12:27:16 pm »

I can only say, it is done through shaders. But I am not a shader guy.

Marvin
Logged
hawkwind
Getting respectable
***
Offline Offline

Posts: 363



View Profile Email
« Reply #3 on: 27. October 2009, 11:30:03 pm »

I will post a shader example in a day.

Basically you can use a shader

set the material in the appearance with an emmisive color, say green

or you can copy the shape, scale it a little bigger and make it somewhat transparent t seem to glow
Logged
hawkwind
Getting respectable
***
Offline Offline

Posts: 363



View Profile Email
« Reply #4 on: 29. October 2009, 08:58:07 pm »

version 1 playing with the appearance attributes.

  Use Xith Interval instead of HawkInterval,  This code runs periodically and cycles the green intensity of the diffused material.  In my game when the mouse hovers or a shape I run the interval if the shape is important to clue the user.

Code:


import hawk.util.DebugLogger;
import hawk.util.HawkInterval;
import hawk.world.WorldManager;

import org.openmali.vecmath2.Colorf;
import org.xith3d.loop.UpdatingThread.TimingMode;
import org.xith3d.loop.opscheduler.Interval;
import org.xith3d.loop.opscheduler.ScheduledOperation;
import org.xith3d.scenegraph.Shape3D;

public class DemoPickOperation implements ScheduledOperation {
boolean alive = true;
Colorf color = new Colorf();
Interval myInterval = null;
static int textCounter = 0;


public DemoPickOperation(Shape3D shape) {
shape.getAppearance().getMaterial().getDiffuseColor(color);
final Colorf finalColor = color;
final Shape3D fshape = shape;
String msg = "active  ";
DebugLogger.getInstance().log("DemoPickOperation", msg);
WorldManager.getInstance().getEnv().getRenderLoop()
.getOperationScheduler().addInterval(
myInterval = new HawkInterval(WorldManager
.getInstance().getEnv().getRenderLoop()
.getTimingMode().getFromMilliSeconds(100L),
getDemoIntervalID()) {
float inc = .05f;

@Override
protected void onIntervalHit(long gameTime,
long frameTime, TimingMode timingMode) {
float green = finalColor.getGreen();
if (green >= 1.0f) {
inc = -.05f;
} else if (green <= 0f) {
inc = .05f;
}
// System.out.println("demo " + inc + " " + green);
green = green + inc;
finalColor.setGreen(green);
fshape.getAppearance().getMaterial()
.setDiffuseColor(finalColor);
}
});
}

public boolean isAlive() {
return alive;
}

public boolean isPersistent() {
return true;
}

public void setAlive(boolean alive) {
this.alive = alive;

myInterval.kill();
}

public void update(long gameTime, long frameTime, TimingMode timingMode) {
// if (StaticFileds.updateLogging)
// System.out.println("update " + this.getClass().getName());

}




Logged
hawkwind
Getting respectable
***
Offline Offline

Posts: 363



View Profile Email
« Reply #5 on: 29. October 2009, 09:14:08 pm »

Version 2 shader support.

This is more complex and different from the basic Xith shader support.  Basically I have a base class ShaderSupport that provide support and abstract methods.  The PulseShader class the extends this and provides settings for shader parameters and calculations for how the shader parameters updates etc.  Go ahead and ask questions if you need to.

Code:
package hawk.shader;

import hawk.util.DebugLogger;
import hawk.util.HawkInterval;
import hawk.world.WorldManager;

import org.xith3d.base.Xith3DEnvironment;
import org.xith3d.loaders.shaders.impl.glsl.GLSLShaderLoader;
import org.xith3d.loop.UpdatingThread.TimingMode;
import org.xith3d.loop.opscheduler.Interval;
import org.xith3d.resources.ResourceLocator;
import org.xith3d.scenegraph.GLSLContext;
import org.xith3d.scenegraph.GLSLFragmentShader;
import org.xith3d.scenegraph.GLSLShaderProgram;
import org.xith3d.scenegraph.GLSLVertexShader;
import org.xith3d.scenegraph.Shape3D;


public abstract class ShaderSupport {

String vertexProgram = "per-pixel-lighting.glslvert";
String fragmentProgram = "per-pixel-lighting.glslvert";
Interval myInterval = null;
GLSLContext shaderProgram = null;
Shape3D shape = null;

public ShaderSupport(Shape3D shp) {
GLSLContext.setDebuggingEnabled(true);
shape = shp;
String msg = "start ShaderSupport  ";
DebugLogger.getInstance().log(this.getClass().getName(), msg);

}

private GLSLContext loadShader(ResourceLocator resLoc) throws Exception {
// we will enable shader debugging to get some output in case of a
// shader bug...
GLSLContext.setDebuggingEnabled(true);

// to use shader programs we need to create
// GLSL{Vertex|Fragment}Shader's
// this time we'll use a Vertex Shader
GLSLVertexShader waverShader = GLSLShaderLoader.getInstance()
.loadVertexShader(resLoc.getResource(vertexProgram));

// very simple right?
// but that wasn't all ... we need to add this vertex shader to
// a GLSLShaderProgram to use it
GLSLContext shaderProg = new GLSLContext(new GLSLShaderProgram());
shaderProg.getProgram().addShader(waverShader);

// we'll load a fragmentshader too ... it's the very same procedure
GLSLFragmentShader heightcolorShader = GLSLShaderLoader.getInstance()
.loadFragmentShader(resLoc.getResource(fragmentProgram));
shaderProg.getProgram().addShader(heightcolorShader);

shaderProgram = shaderProg;
addVariables();
return (shaderProg);
}

public void createShaderProgramx() {
try {
shaderProgram = loadShader(ResourceLocator.getInstance());
// Appearance app = new Appearance();
// shape.setAppearance(app);
shape.getAppearance().setShaderProgramContext(shaderProgram);
} catch (Exception e) {
e.printStackTrace();
}
}

public void createShaderProgram() {
GLSLContext.setDebuggingEnabled(true);

shaderProgram = new GLSLContext(new GLSLShaderProgram());
GLSLShaderLoader loader = GLSLShaderLoader.getInstance();
try {

shaderProgram.getProgram().addShader(
loader.loadVertexShader(ResourceLocator.getInstance()
.getResource(vertexProgram)));
shaderProgram.getProgram().addShader(
loader.loadFragmentShader(ResourceLocator.getInstance()
.getResource(fragmentProgram)));

shaderProgram.getUniformParameters().setUniformVar("time", 10f);
shape.getAppearance().setShaderProgramContext(shaderProgram);
} catch (Exception e) {
e.printStackTrace();
}
}

public String getFragmentProgram() {
return fragmentProgram;
}

public void setFragmentProgram(String fragmentProgram) {
this.fragmentProgram = fragmentProgram;
}

public String getVertexProgram() {
return vertexProgram;
}

public void setVertexProgram(String vertexProgram) {
this.vertexProgram = vertexProgram;
}

public GLSLContext getShaderProgram() {
return shaderProgram;
}

public void setShaderProgram(GLSLContext shaderProgram) {
this.shaderProgram = shaderProgram;
}

//used for logging events
static int textCounter = 0;
public static String getNewIntervalID() {
String intervalName = "Shade-" + Integer.toString(textCounter++);
return intervalName;
}

abstract public void run() ;

public void run(final long delta) {
      Xith3DEnvironment env = WorldManager.getInstance().getEnv();
  env.getOperationScheduler().addInterval(
myInterval = new HawkInterval( env.getRenderLoop()
.getTimingMode().getFromMilliSeconds(delta),getNewIntervalID()) {
@Override
protected void onIntervalHit(long gameTime,
long frameTime, TimingMode timingMode) {
code(gameTime, frameTime, timingMode);
System.out.println("code "+delta+"  "+frameTime);
}
});
}

//use implement this method to add parameters to shader
abstract public void addVariables();

//use this methos to process data to be used as shader parameter values
abstract public void code(long gameTime, long frameTime,
TimingMode timingMode);
}


PulseShader extends ShaderSupport, defines parameter "time" and "baseMap".  "time" increments and affects the pulsing effect, "baseMap" set set to "0" which points to the base texture unit.  The code method updates "time" from an interval, which is render safe.  The constructor sets the fragment and vertex shader programs.  Whereever you place these programs needs to be accessable to your resource support.  See how this is done in the Xith shader examples.

Code:
package hawk.shader;

import hawk.util.DebugLogger;
import hawk.util.HawkInterval;
import hawk.world.WorldManager;

import java.util.ArrayList;
import java.util.Iterator;

import org.xith3d.base.Xith3DEnvironment;
import org.xith3d.loop.UpdatingThread.TimingMode;
import org.xith3d.scenegraph.Shape3D;

/*
 * Pulsing shader to highlight mouse over shape
 */
public class PulseShader extends ShaderSupport {

//* color option, eah requires a unique shader at this point
public static final int RED = 1;
public static final int BLUE = 2;

/*
* active shader list used for cleanup
*/
static Object syncObject = new Object();
static ArrayList<PulseShader> shaders = new ArrayList<PulseShader>();

public PulseShader(int color, Shape3D shape) {
super(shape);

DebugLogger.getInstance().log("Pulse Shader ", "new shader");

//set vrtex shader
setVertexProgram("shader/hawkwind/pulse.glslvert");

//set fragment shader based on color
if (color == RED)
setFragmentProgram("shader/hawkwind/redpulse.glslfrag");
if (color == BLUE)
setFragmentProgram("shader/hawkwind/bluepulse.glslfrag");

//NOTE using "x" shader support
createShaderProgramx();
addToList(this);
}

/*
* track active shaders,
* set common value for shader parameters,
* and start shader operation
*/
private void addToList(PulseShader shd) {
if (shaders.size() == 0) {
shaders.add(shd);
run();
}
synchronized (syncObject) {
shaders.add(shd);
}
}

/*
* override shadersupport run(non-Javadoc)
* @see hawk.shader.ShaderSupport#run()
*/
public void run() {
Xith3DEnvironment env = WorldManager.getInstance().getEnv();
env.getOperationScheduler().addInterval(
myInterval = new HawkInterval(env.getRenderLoop()
.getTimingMode().getFromMilliSeconds(60L),
getNewIntervalID()) {
@Override
protected void onIntervalHit(long gameTime, long frameTime,
TimingMode timingMode) {
for (Iterator iterator = shaders.iterator(); iterator
.hasNext();) {
ShaderSupport shader = (ShaderSupport) iterator
.next();
shader.code(gameTime, frameTime, timingMode);
}

}
});
}

/*
* override shadersupport
* (non-Javadoc)
* @see hawk.shader.ShaderSupport#code(long, long, org.xith3d.loop.UpdatingThread.TimingMode)
*/
public void code(long gameTime, long frameTime, TimingMode timingMode) {

//this shader uses "time" parameterfor its effect
final float gameSeconds = timingMode.getSecondsAsFloat(gameTime);
shaderProgram.getUniformParameters().setUniformVar("time",
gameSeconds * 2);
}

@Override
public void addVariables() {
// here we'll send a variable to the shader to make our waves move
// notice that all setUniformVars use dynamic parameter lists
// we could set 20 floats here ... and would be able to aquire
// them in the shader
shaderProgram.getUniformParameters().setUniformVar("time", 0f);
shaderProgram.getUniformParameters().setUniformVar("baseMap", 0);
}
}



Vertex program "shader/hawkwind/pulse.glslvert");

Code:
varying float y;

varying vec2 texCoord;

void main(void)
{

texCoord = gl_MultiTexCoord0.xy;
// get our y position
y = gl_Vertex.x;

// transform our vertex
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

      



Fragment programs, two ones that set different colors




 "shader/hawkwind/redpulse.glslfrag"

Code:
varying float y;
uniform float time;
uniform sampler2D baseMap;

varying vec2 texCoord;

#define RATE_SCALE 10.0

void main(void)
{
float intensity;
intensity = sin( y + (time * RATE_SCALE));
intensity = clamp( intensity, 0.0, 1.0);
    vec4 base = texture2D(baseMap, texCoord);
// vary color from white to green by varying red & blue
gl_FragColor = vec4( intensity,intensity, 1.0, 1.0);
}
       

"shader/hawkwind/bluepulse.glslfrag"

Code:
varying float y;
uniform float time;
uniform sampler2D baseMap;

varying vec2 texCoord;

#define RATE_SCALE 10.0

void main(void)
{
float intensity;
intensity = sin( y + (time * RATE_SCALE));
intensity = clamp( intensity, 0.0, 1.0);
    vec4 base = texture2D(baseMap, texCoord);
// vary color from white to green by varying red & blue
gl_FragColor = vec4(   1.0, 1.0, intensity,intensity );
}
Logged
fbommeau
Just dropped in

Offline Offline

Posts: 8



View Profile
« Reply #6 on: 10. November 2009, 08:18:47 am »

Hello hawkwind,

Thanks for your detailed answers !
...and sorry for this (very) late answer, I was away for 2 weeks.

I tried the version 2 with shader solution you suggested. It works, but the effect was not the one I expected: the Shape3D was a kind of glowing by changing color, but there was no halo around it. Did I set it correctly ?

I think that maybe I wasn't clear about the effect I was looking for, to be sure, have a look at: http://demos.labs.exalead.com/constellations/graph/  .
It's a demo search engine that show results as constallation. The effect I'm looking for is the halo surrounding each circle in the constellation.
Did you have this idea in mind ?

-- Franck 
Logged

-- Too much of a good thing is wonderful (except OpenGL calls).
(Mae West turned geek)
horati
Global Moderator
Getting respectable
*****
Offline Offline

Posts: 393


View Profile
« Reply #7 on: 13. November 2009, 11:50:35 pm »

Thanks for the wonderful example Hawk.  I just tested it out and it really helped me get a meager start with shaders.
Logged

Kevin
"It may not seem like a big deal, but ignorance of character encoding issues leads to insidious code rot akin to y2k."
http://stackoverflow.com/users/3474/sylvarking
hawkwind
Getting respectable
***
Offline Offline

Posts: 363



View Profile Email
« Reply #8 on: 14. November 2009, 10:07:33 pm »

OK..another then, note this abit complex because I added lighting code it can be simplified.


ask questions if you need...

alpha fragment

 basemap is text unit 0 bumpmap is unit 1.  This guy discards texture color from basemap when r,g,b of bumpmap equal 0.  So a black/white bumpmap texture can act as a mask for the actual texture.

Code:

 
#define NUM_LIGHTS 6

varying vec3 viewVec;
varying vec2 texCoord;
varying vec3 lightVecArr[NUM_LIGHTS];
varying float lightAtt[NUM_LIGHTS];
uniform sampler2D baseMap;
uniform sampler2D bumpMap;
uniform float invRadius;

varying float fogFactor;

void doLighting( in int i,
                 in vec3 lVec, 
                 in vec3 vVec,
                 in vec3 bump,
                 inout vec4 vAmbient,
                 inout vec4 vDiffuse,
                 inout vec4 vSpecular,in float att )
{
float distSqr = dot(lightVecArr[i], lightVecArr[i]);
//float att = clamp(1.0 - invRadius * sqrt(distSqr), 0.0, 1.0);

lVec = normalize(lVec);
float diffuse = max( dot(lVec, bump), 0.0 );
float specular = pow(clamp(dot(reflect(-vVec, bump), lVec), 0.0, 1.0), gl_FrontMaterial.shininess );

vAmbient += gl_FrontLightProduct[i].ambient;//* gl_FrontMaterial.ambient;
vDiffuse += gl_FrontLightProduct[i].diffuse * diffuse * att;
vSpecular += gl_FrontLightProduct[i].specular * specular * att;
}                 

void main (void)
{
vec3 vVec = normalize(viewVec);


vec4 base_color = texture2D(bumpMap, texCoord);

if(base_color.r==0)
{
discard;
}
else if(base_color.g==0)
{
discard;
}
else if(base_color.b==0)
{
discard;
}



vec4 base = texture2D(baseMap, texCoord);
vec3 bump = normalize(texture2D(bumpMap, texCoord).xyz * 2.0 - 1.0);

vec4 vAmbient = vec4(0.0);
vec4 vDiffuse = vec4(0.0);
vec4 vSpecular = vec4(0.0);

for( int i=0; i<NUM_LIGHTS; i++ )
{
float att = lightAtt[i];

doLighting(i, lightVecArr[i], vVec, bump, vAmbient, vDiffuse, vSpecular,att );
}

gl_FragColor = base  * vDiffuse + vAmbient  ;
gl_FragColor = mix(gl_Fog.color, gl_FragColor, fogFactor );

gl_FragColor = gl_FragColor + (vSpecular);


//clr = base  * vDiffuse + vAmbient  + (vSpecular);
//gl_FragColor = mix(gl_Fog.color, clr, fogFactor )+ (vSpecular);
}

alpha vert

Code:
 
#define NUM_LIGHTS 6

varying vec3 viewVec;
varying vec2 texCoord;
varying vec3 lightVecArr[NUM_LIGHTS];
varying float lightAtt[NUM_LIGHTS];
attribute vec3 tangent;
varying float fogFactor;

void main(void)
{
gl_Position = ftransform();
texCoord = gl_MultiTexCoord0.xy;

vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * tangent);
vec3 b = cross(n, t);

    vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);

const float LOG2 = 1.442695;
gl_FogFragCoord = length(vVertex);
fogFactor = exp2( -gl_Fog.density *
   gl_Fog.density *
   gl_FogFragCoord *
   gl_FogFragCoord *
   LOG2 );
fogFactor = clamp(fogFactor, 0.0, 1.0);




vec3 vVec = -vVertex;
viewVec.x = dot(vVec, t);
viewVec.y = dot(vVec, b);
viewVec.z = dot(vVec, n);

vec3 vLVec;
for( int i=0; i<NUM_LIGHTS; i++ )
{
vLVec = gl_LightSource[i].position.xyz - vVertex;
float d = length(vLVec);

lightAtt[i] = 1.0 / ( gl_LightSource[i].constantAttenuation +
(gl_LightSource[i].linearAttenuation*d) +
(gl_LightSource[i].quadraticAttenuation*d*d) );

lightVecArr[i].x = dot(vLVec, t);
lightVecArr[i].y = dot(vLVec, b);
lightVecArr[i].z = dot(vLVec, n);
}
}
 

Logged
horati
Global Moderator
Getting respectable
*****
Offline Offline

Posts: 393


View Profile
« Reply #9 on: 21. November 2009, 07:50:20 pm »

Sorry for the late reply.  As I mentioned in another post, my computer crashed.

It is now clear to me that shaders are whole (C-like) language of their own that can do really cool things.  Do you have links/books I can research?
Logged

Kevin
"It may not seem like a big deal, but ignorance of character encoding issues leads to insidious code rot akin to y2k."
http://stackoverflow.com/users/3474/sylvarking
fbommeau
Just dropped in

Offline Offline

Posts: 8



View Profile
« Reply #10 on: 23. November 2009, 09:24:42 am »

Hello hawkwind,

I just tried your example on a very simple test case:
 
Code:
TransformGroup tg=new TransformGroup();
Rectangle r=new Rectangle(2f,1f,Colorf.RED);
tg.addChild(r);
tg.setPosition(0,0,0);
r.getAppearance(true).setShaderProgramContext(loadShader());
...
env.addPerspectiveBranch(<The scene>)

The loadShader loads your alpha.glslvert and alpha.glslfrag in the same way as the xith test GLSLWaverTest does.

Result:
Without the shader I see my red rectangle at origin.
With the shaders loaded (they are correctly loaded), I see nothing (even if I add a spotlight to the rectangle).

I'll start tomorrow to learn the shader language (that doesn't seem to be so complicated) to understand what's going on. But in the meantime if you could help me to set up this example working. It would be great !

Tnxs !

-- Franck
Logged

-- Too much of a good thing is wonderful (except OpenGL calls).
(Mae West turned geek)
hawkwind
Getting respectable
***
Offline Offline

Posts: 363



View Profile Email
« Reply #11 on: 23. November 2009, 10:30:21 pm »

Does the shader have a run method....this starts a interval (xith interval)  which cycles the colors
Logged
platinumPotato
Just dropped in

Offline Offline

Posts: 1


View Profile Email
« Reply #12 on: 15. July 2011, 02:25:56 pm »

This is called bloom and there are two standard ways to do it.  You can achieve nicer results with the shader method, but fixed function also works with no shaders and can have nice results.

Fixed Function Method:

1. render the object(s) you want to bloom into a texture.  The texture should be cleared to 0 alpha first.
2. create mip maps of said texture. 
3. render a quad to the entire screen using only of the low mip maps of this texture and bilinear filtering and at a low transparency (10-25% usually).  The bilinear filtering blurs out the edges of the object, and the low transparency ensures that you get a soft layer of bloom surrounding the object.


Shader Method:

1. same step as the first step above.  I call this the source texture.
2. create a "filter" shader that basically super samples the texture you just created and averages the results.  This is pretty simple to do.  In your shader just have a for loop that adds a small offset to the texture coordinates in each iteration.  There are a lot of different types of filters you can do, sampling in a square pattern, a circular pattern, etc.  Render a quad into a second texture using this shader and the source texture as input.  The second texture is called the bloom texture.

3. the same as step 3 above, but you use the bloom texture instead of a mip map of the source texture.
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #13 on: 15. July 2011, 10:05:31 pm »

This can be done with the correct geometry and blending; this page (http://sebastien.hillaire.free.fr/index.php?option=com_content&view=article&id=54&Itemid=56) has a quick coverage.

You might not actually need shaders accomplish this; try using a textured rectangle with end caps and a gradient texture that fades to transparent from the center.
Logged
ChrisE
Becoming dependent
**
Offline Offline

Posts: 104


View Profile
« Reply #14 on: 15. July 2011, 10:11:26 pm »

Sorry for the late reply.  As I mentioned in another post, my computer crashed.

It is now clear to me that shaders are whole (C-like) language of their own that can do really cool things.  Do you have links/books I can research?

Shaders are pretty spiffy. I've been working on getting them integrated into our group's engine tech, and they are cool.

If you want a good environment for testing things out without having to deal with the (really annoying) setup code, try AMD RenderMonkey. It handles loading textures and models and setting up targets for you, so you can focus on writing the shaders.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic