Add Light to Particle System


#1

Hi everybody, I’m looking for a method for adding realistic light to a particle system built on a vbo, rendered with points as sprite and powered by OpenCL. In my experience a simple ofLight doesn’t work, I guess because the points in a vbo can’t be used for light computation. Do you know some method to achieve that? Like some light shader algorithm or something like that.
I would like to achieve something like that:


I know it’s really different from openFramework coding, but I would also like to get near that.

Thank you very much!

Federico


#2

Hey,
personally I would integrate light directly into the particle system shaders: depending on how the particles are created, I’d calculate normals in the vertex or geometry shader; then, using a classic Phong effect, I’d apply light in the fragment shader.


#3

Wow, don’t know why but I was sure that with draw mode as points it wouldn’t have worked.
Instead it worked perfectly : ) Thank you for your suggestion!


#4

Hi Frederico
I have been considering the same for one of my projects, but never got time to implement lighting.
Would you maybe share your code? Especially the shader would be interessting.
Best
Jonas


#5

Shure! Though it is just a simple light shader from the GLSL Orange Book.
Here’s the vertex shader:

#version 120
#extension GL_ARB_texture_rectangle : enable
#extension GL_EXT_gpu_shader4 : enable

varying float LightIntensity;
uniform vec3 LightPosition = vec3(0.0, 0.0, 4.0);
uniform float specSharp = 16.0;

const float specularContribution = 1.0;
const float diffuseContribution = 4.0 - specularContribution;

void main() {

vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);  //eye coordinates of the vertex
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);     //normalized normal in eye coordinates
vec3 lightVec = normalize(LightPosition - ecPosition);      //vector from the object to the light source
vec3 reflectVec = reflect(-lightVec, tnorm);                        //reflection vector of light in respect of normal
vec3 viewVec = normalize(-ecPosition);                            //vector pointing to the viewer

float spec = clamp(dot(reflectVec, viewVec), 0.0, 2.0);     //specular light value
spec = pow(spec, specSharp);

float diffuse = max(dot(lightVec, tnorm), 0.0);   //diffuse light value. If angle > 90º the value is clamped to 0.0

LightIntensity = diffuseContribution * diffuse + specularContribution * spec;  //resulting light intensity
}

in the frag shader you just have to multiply the gl_color for the varying variable LightIntensity:

gl_FragColor = gl_Color * LightIntensity;

Hope this helped!

Federico


#6

hi frederico,
thanks a lot. Unfortunately I don’t have time right now to implement it, but I am looking forward to do it next month.
It looks indeed straight forward.
Best
Jonas


#7

Hi,

I tried the shader code, but it does not seem to work for me. I only get a black screen when I use the shader. Could anyone give me a hint how to get the shader working. Is there anything special I need to setup?