Sign in to follow this  

Problems with Point Lights

Recommended Posts

lipsryme    1522
[b]Update: See my reply[/b]

I've got them working on my previous renderer so I'm clueless why it doesn't work here. (Yes I've tried to look at how I implemented them there).

I'm rendering the Point Light with a sphere mesh to my Light Buffer (texture).
The normals are stored in view space and so is the depth (viewSpace.z / FarClip).

Here's the Light PS code:
//Vertex Input Structure
struct VSI_Point
float4 Position : POSITION0;
//Vertex Output Structure
struct PSI_Point
float4 Position : SV_POSITION;
float3 vPosition : TEXCOORD0;
float4 ScreenPosition : TEXCOORD1;
//Vertex Shader
PSI_Point Point_VS(VSI_Point input)
//Initialize Output
PSI_Point output = (PSI_Point)0;
//Transform Position
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.ScreenPosition = output.Position;
output.vPosition =;
return output;
float4 Phong_PointLight(float3 Position, half3 N, float SpecularIntensity, float SpecularPower)
// Calculate LightDirection
float3 L = -;
// Normalize LightDirection
L = normalize(L);

// Calculate Linear Attenuation
float Attenuation = saturate(1.0f - max(0.01f, length(L)) / (LightRadius / 2));
//Calculate Eye vector
float3 V = normalize(CameraPosition -;

//Calculate N.L
float NL = dot(N, L);
//Calculate Diffuse
float3 Diffuse = * LightIntensity;

// Calculate R
float3 R = normalize(2 * Diffuse * N - L);
// Calculate (R.V)n
float RV = SpecularIntensity * pow(saturate(dot(R, L)), SpecularPower);
// Return Lighting Term
return float4(NL * Diffuse.r * Attenuation,
NL * Diffuse.g * Attenuation,
NL * Diffuse.b * Attenuation,
NL * RV * Attenuation);
//Pixel Shader
float4 Point_PS(PSI_Point input) : COLOR0
//Get Screen Position
input.ScreenPosition.xy /= input.ScreenPosition.w;
//Calculate UV from ScreenPosition
float2 UV = 0.5f * (float2(input.ScreenPosition.x, -input.ScreenPosition.y) + 1) - float2(1.0f / GBufferTextureSize.xy);

//Get All Data from Normal part of the GBuffer
half4 encodedNormal = tex2D(NormalBuffer, UV);
//Decode Normal
half3 Normal = decode(encodedNormal);

//Get Specular Intensity from GBuffer
float SpecularIntensity = tex2D(SpecularBuffer, UV).x;
//Get Specular Power from GBuffer
float SpecularPower = tex2D(SpecularBuffer, UV).y;
//Get Depth from GBuffer
float Depth = tex2D(DepthBuffer, UV);
float3 viewRay = float3(input.vPosition.xy * (FarClip / input.vPosition.z), FarClip);

float3 Position = viewRay * Depth;
//Return Phong Shaded Value
return Phong_PointLight(, Normal, SpecularIntensity, SpecularPower);


Share this post

Link to post
Share on other sites
lipsryme    1522
Ok so I've figured out how to transform everything to world space, which works so far. But, the only problem I have now is that I need to transform my View Space Depth, which I stored like this: -viewPos.z / farClip to Clip Space Depth meaning the z/w thing. Because my light only appears when I move very close to the light and when I move it away its gone.

Well I just tried outputting ScreenPosition.z / ScreenPosition.w for depth and everything works perfectly.
But my SSAO and stuff doesn't. And I don't have enough space or precision to store both.
Can anyone tell me how to transform back and forth between those : / ? (is it even possible?)

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this