Directional light shaders

I tried following this tutorial (http://zach.in.tu-clausthal.de/teaching/cg_literatur/glsl_tutorial/index.html#ogldir1) for implementing a directional light per pixel in my code, but it’s just not working.

Here my .frag and .vert :


// .vert
uniform float pointRadius;  // point size in world space  
uniform float pointScale;   // scale to calculate size in pixels  
varying vec3 posEye;
void main()  
{      
	// calculate window-space point size
	posEye = vec3(gl_ModelViewMatrix * vec4(gl_Vertex.xyz, 1.0));
	float dist = length(posEye);      
	gl_PointSize = pointRadius * (pointScale / dist);
	gl_Position = ftransform();
	gl_FrontColor = gl_Color;
}  


uniform float pointRadius;  // point size in world space  
varying vec3 posEye;        // position of center in eye space
uniform vec3 lightDir;
void main()  
{     

	lightDir = normalize(vec3(gl_LightSource[0].position));
	// calculate normal from texture coordinates
	vec3 N;
	N.xy = gl_TexCoord[0].xy*vec2(2.0, -2.0) + vec2(-1.0, 1.0);
	float mag = dot(N.xy, N.xy);      
	if (mag > 1.0) discard;   // kill pixels outside circle      
	N.z = sqrt(1.0-mag);
	// calculate lighting      
	float diffuse = max(0.0, dot(lightDir, N));
	gl_FragColor = gl_Color * diffuse;
}  

I tried following this tutorial (http://zach.in.tu-clausthal.de/teaching/cg_literatur/glsl_tutorial/index.html#ogldir1) for implementing a directional light per pixel in my code

You made some pretty substantial changes to the code for something that is supposed to be following the tutorial. For example, the camera-space surface normal in the tutorial was passed as a varying in the tutorial. In your code…

Well really, that’s likely your problem. In your code, you “calculate normal from texture coordinates”. But you didn’t pass any texture coordinates from your vertex shader. It never sets gl_TexCoord[0]. Why this isn’t a linker error, I don’t know.

This is one reason why you should always declare your shader inputs and outputs, even if they’re built-ins. That way, you can know at a glance what your shaders read and right. It’s also why avoiding built-ins is a good idea for a beginner; it forces you to explicitly say what you’re doing.

ThatMs because i want the point sprites to stay as spheres, if i change something else, the points will appear as point. So that’s why i’m having trouble using the tutorial.

ThatMs because i want the point sprites to stay as spheres, if i change something else, the points will appear as point.

That sounds like an even bigger bug. Admittedly, I haven’t used point sprites much, so I don’t fully understand the vagaries around them. But I don’t understand how which inputs/outputs you use affects where it is a “sphere” or a “point”.

But your problem remains as stated. Your vertex shader does not output the correct information to the fragment shader. Until you do so, you will not get proper lighting.

ok well…here the shaders i’m using : http://code.google.com/p/bullet/source/browse/trunk/Demos/ParticlesOpenCL/shaders.cpp
im trying to modify it because i don’t want the light to follow the user eye position (right now, no matter how you are rotating around the point sprites, it’s always looking the same, the sphere is always the same).

That code makes no sense.

Points are not quads. They have never been quads. The varyings are not interpolated over the area of the point. Therefore, if you pass a varying, every fragment gets the same value. Which means that you cannot use a varying to compute where you are on the surface.

(note: the above is true for shaders. Fixed function works differently)

If you want to know where you are on a point, you use gl_PointCoord. You can then do interpolation as you see fit.

I use point sprites to simulate alot of spheres, over 2 millions. Since it would be hard to render that many spheres using quads, i use point sprite, and use a shader to make them look like spheres. Now, the points sprites are always facing the user. I need them to stay fixed, so i can move around to really have the sensation of a 3d sphere.

Now, the points sprites are always facing the user. I need them to stay fixed, so i can move around to really have the sensation of a 3d sphere.

Assuming you have corrected the problem I mentioned, you still have other problems. For example, you are doing your lighting in camera space. This means that your light direction needs to be relative to the camera. It therefore changes when the camera changes.

However, you use a constant light direction:

const vec3 lightDir = vec3(0.577, 0.577, 0.577);

So it isn’t relative to the camera.

It is constant, relative to the position of the camera. Right now, The light is indeed following the camera. What i’m trying to do is the OPPOSITE.

M//Hax you where already told you have to change this uniform to make camera and light independent from each other !

Like this ? :


// pixel shader for rendering points as shaded spheres  
const char *spherePixelShader = STRINGIFY(
uniform float pointRadius;  // point size in world space  
varying vec3 posEye;        // position of center in eye space
uniform vec3 lightDir;
void main()  
{     
	lightDir = vec3(0.577, 0.577, 0.577);

Like this ? :

That won’t even compile. You cannot set uniforms from a shader (except as a constant initializer). They can only be set from code.

You have a light direction in world space. This represents the direction from the object to the light. You need a light direction in camera space. Therefore, you must transform the world space light direction into camera space. This is done on the CPU; the shader is then given the light direction in camera space as a uniform.

Not at all, try this instead :
http://www.opengl.org/sdk/docs/man/xhtml/glUniform.xml

ok so it should be something like that?


// pixel shader for rendering points as shaded spheres  
const char *spherePixelShader = STRINGIFY(
uniform float pointRadius;  // point size in world space  
varying vec3 posEye;        // position of center in eye space
uniform vec3 lightDir;
void main()  


//in void initPointSprites(), in main.cpp
	glUseProgram(m_shaderProgram);
        glUniform1f( glGetUniformLocation(m_shaderProgram, "pointScale"), g_windowHeight / tan(60.0f*0.35f*M_PI/180.0f) );
        glUniform1f( glGetUniformLocation(m_shaderProgram, "pointRadius"), 0.3f );
	glUniform1f( glGetUniformLocation(m_shaderProgram, "lightDir"), (.5,.5,.5) );

I know the images aren’t done for these yet, but you should just read these. And probably the tutorials on transformation and spaces.

Look like a good tutorial. I don’t feel like reading another tutorial (read about 3 tutorials about directional lighting). I’m just playing with the code right now, hoping some miracle will happen!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.