Question

I'm trying to accomplish a spotlight effect with Cg. I've already managed to do normal ambient and diffuse lighting.

I understand the basic functionality of a spotlight (position, direction, cutoff angle), yet handling these in Cg still eludes me.

This is how I compute the spotlight parameters:

float4 dir_aux = mul(ModelViewProj, direction);
float4 lightP_aux = mul(ModelViewProj, lightPosition);

float3 lightP = lightP_aux.xyz;
float3 dir = normalize(dir_aux.xyz);

float3 P = IN.position;
float3 V = normalize(lightP - P);
dir = normalize(lightPosition - dir);

float angle = dot(V, dir);

direction is the pixel the spotlight is pointed to ( ex: (0, 0, 0) )

lightPosition is the position of the light

P is the point i am trying to light. IN.position comes from the vertex shader, and it's already multiplied with modelViewProj.

angle is the cosine of the angle between the direction of the light and the direction from the light, to the point I'm trying to light.

The problem is that changing the direction of the light does not affect the spotlight whatsoever.It will always be centered in 0,0,0. If I change lightPosition, the spotlight changes, but it still starts from 0,0,0 and expands oppsite the position of the light

Another thing is that when I compute the direction vector, I use lightPosition, instead of lightP.If I use lightP, the spotlight won't work at all.

Also the spotlight only lights on half of the scene.

My main reference for this was Chapter 5(Lighting), from The Cg Tutorial.

Was it helpful?

Solution

Here's my take on this, I think your vectors are pointing in the wrong directions (when you do the subtractions):

// direction is actually the location of the target
float4 target = direction; // renamed for clarity   

float4 target_aux = mul(ModelViewProj, target);
float4 lightP_aux = mul(ModelViewProj, lightPosition);

float3 lightP = lightP_aux.xyz;
float3 targetXYZ = target.xyz;

// don't normalise this it's a location at this point, NOT a direction vector
//float3 dir = normalize(dir_aux.xyz);

float3 P = IN.position;
// reversed to give vector from light source to IN.Position
float3 V = normalize(P - lightP);

// reversed to give vector from light source to target
float3 dir = normalize(targetXYZ - lightP);

float angle = dot(V, dir);

A bit late, but I hope that helps :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top