Sign in to follow this  
lipsryme

Problems with Point Lights

Recommended Posts

[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:
[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 = viewPosition.xyz;
//Return
return output;
}
float4 Phong_PointLight(float3 Position, half3 N, float SpecularIntensity, float SpecularPower)
{
// Calculate LightDirection
float3 L = LightPosition.xyz - Position.xyz;
// 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 - Position.xyz);

//Calculate N.L
float NL = dot(N, L);
//Calculate Diffuse
float3 Diffuse = LightColor.xyz * 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(Position.xyz, Normal, SpecularIntensity, SpecularPower);

}
[/CODE]

Share this post


Link to post
Share on other sites
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