PDA

View Full Version : problem with spherical point sprite shading



Piotrek Janisz
04-04-2011, 08:31 AM
Hi everyone,

I'm rendering spheres as points (I'm computing normals in fragment shader)
I have a scene with a sphere, and a directional light. I can rotate and move camera around scene.
The problem I have is that when I rotate camera the sphere shading changes - I mean the sphere diffuse intensity changes becouse the angle between lightDirection vector and sphere normal changes.
I can't just multiply normals by camera rotation matrix, as I do with light direction vector becouse this will cause the shading of sphere to be constant regardless of the camera position.
I want the shading of sphere to change accordingly to camera position and not to change when camera is rotated.
So my question is how should I transform normals to achieve that?

that is how I do it right now:

vertex shader:


uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

in vec4 vertex;

void main()
{
gl_Position = projectionMatrix * modelViewMatrix * v;
}



fragment shader:


uniform vec3 lightDirection; // this is already multiplied by camera rotation matrix
out vec4 fragColor;

void main()
{
vec3 normal;
normal.xy = gl_PointCoord.xy * vec2(2.0, -2.0) + vec(-1.0, 1.0);
float mag = dot(normal.xy, normal.xy);

if (mag > 1.0f)
discard;

normal.z = sqrt(1.0f - mag);
normal = normalize(normal);

float diffuseIntensity = max(0.0f, dot(normal, lightDir));

fragColor = vec4(0.1f, 0.1f, 0.1f, 1.0f) * diffuseIntensity * vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

mobeen
04-04-2011, 11:19 PM
Change this

normal.xy = gl_PointCoord.xy * vec2(2.0, -2.0) + vec(-1.0, 1.0);
to this

normal.xy = (gl_PointCoord.xy * 2.0) - vec2(1.0);

and also remove the normalization

normal = normalize(normal);

Piotrek Janisz
04-05-2011, 07:05 AM
Ok, thanks - it has slightly better performance now, but operations you suggested don't remove my problem.

here are two screenshots from my application, ligt direction vector is (-1, -1, -1), and on both camera is in the same position but it's rotation is different:
http://student.agh.edu.pl/~janisz/sphere1.jpg

http://student.agh.edu.pl/~janisz/sphere2.jpg

I don't want shading to change when camera rotates.

mobeen
04-06-2011, 12:44 AM
I don't want shading to change when camera rotates
Then don't multiply the light dir with the camera rotation matrix.

Piotrek Janisz
04-06-2011, 02:37 PM
I don't want shading to change when camera rotates
Then don't multiply the light dir with the camera rotation matrix.

but then shading won't change if I'll translate camera

Alfonse Reinheart
04-06-2011, 02:42 PM
but then shading won't change if I'll translate camera

It's a directional light; translation cannot affect it.

Piotrek Janisz
04-06-2011, 04:52 PM
It's a directional light; translation cannot affect it.

I know, but I need light direction vector to be in camera space (I'm only multiplying it by rotation part of camera matrix).

I'll try to explain my problem more:

I'm using frame (forward and up vectors and position) to represent camera.
I generate normals so that the central pixel of point (sphere) has normal (0.0, 0.0, 1.0) in camera space.
Normals I generate in fragment shader are already in camera space so I need only to transform light direction to camera space.
Everything is fine until forward vector points directly to the center of the sphere.
But if I rotate camera, light direction coordinates in camera space changes and normal coordinates don't (so central pixel still has (0, 0, 1)). Thus
angle between normal and light changes.

here is a picture that illustrates this:
http://student.agh.edu.pl/~janisz/picture.png

simply not transforming light direction into camera space is not a solution for me, becouse as I said, when I change camera position and look at sphere, I want the shading to change.