# Lighting Calculation in View Space

This topic is 2465 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I just can't get my head around this lighting in view space. Can someone explain how this works in comparison to world space calculation ?
Because it doesn't work at all for me. A simple multiplication with the inverseView Matrix doesn't seem to do the trick of transforming my position back to world space.
I'm storing my depth and normals in view space.

Depth is stored like this:
output.Depth = length(input.Depth.z) / farClip;

And my lighting calculation looks like this:
 // Get Depth float Depth = tex2D(DepthBuffer, input.UV).r; float3 viewRay = input.vPosition.xyz; float3 PositionVS; PositionVS = viewRay * Depth; // Calculate Phong Shader output = Phong_DirectionalLight(PositionVS.xyz, normal, specularMaterial); 

##### Share on other sites

A simple multiplication with the inverseView Matrix

You should keep all your calculations in view space and avoid transforming them back into world space. The problem is, that your inverse view matrix will transform into object and not world space.

The standard view matrix is V= invC * M
with invC = inverse camera matrix and M = model matrix.
The model matrix alone transforms your model from object space into world space. So, to get a vector from view space into world space you need to apply the camera matrix alone, but this matrix is not available out of the box, you need to upload it yourself to your shader.

##### Share on other sites
Can you show us how [font=courier new,courier,monospace]Phong_DirectionalLight[/font] works? Is your light direction also in view-space?
Also, how are you transforming your normals into view space?
[font=courier new,courier,monospace]length(input.Depth.z)[/font] looks fishy - why are you calculating the length of a 1D variable?

The standard view matrix is V= invC * M
with invC = inverse camera matrix and M = model matrix.
The view matrix is simply the inverse camera matrix by itself.
The "world view" matrix is the inverse-camera and model/world matrix multiplied together.

##### Share on other sites
Isn't the Camera Matrix the same as the View Matrix ?

I transform the normal in the GBuffer pass by the WorldViewInverseTranspose.
I guess the length is unnecessary but the rest should be fine right(?), with input.Depth.z being (-viewPosition.z) passed to the PS.
What do you mean by light direction in view space ? Do I need to multiply that normalized Vector with the View Matrix ?

The DirectionalPhong looks like this (updated):
 PSO_Lighting Phong_DirectionalLight(float3 Position, float3 L, float3 N, SpecularMaterial material) { PSO_Lighting output = (PSO_Lighting)0; float3 V = LightDir - Position; //Calculate N.L float NL = dot(N, L); //Calculate Diffuse float3 Diffuse = LightColor.xyz * LightIntensity; // Specular Color float3 SpecColor; // If the Specular Color is the same as the Light, use the Lights Color if(Diffuse.r == material.SpecularColor.r && Diffuse.g == material.SpecularColor.g && Diffuse.b == material.SpecularColor.b) { SpecColor = Diffuse; } else { // If both Light and Material Color is different then combine them SpecColor = (Diffuse + material.SpecularColor) / 2; } //Calculate Reflection vector float3 R = normalize(reflect(-L, N)); // Calculate R dot V float RV = pow(saturate(dot(R, V)), material.SpecularPower); output.Lighting = float4(NL * Diffuse.r, NL * Diffuse.g, NL * Diffuse.b, 1); output.Specular = float4(RV * NL * SpecColor.r, RV * NL * SpecColor.g, RV * NL * SpecColor.b, 1); return output; } 

##### Share on other sites
So from the most recent code I've got there, the Light itself seems to work I guess (I still don't get why (0, 1, 0) shines from top to down, every other direction works and my camera is looking up (0, 1, 0) and towards positive Z) but I've been having problems with the reflection. In the way I've set up V = LightDir - ViewPosition the reflection stays still no matter the view angle which is wrong, right ?

##### Share on other sites
Alright so, still hoping I'm not doing a monologue here ;) the Light definitely works now (N.L Term), meaning the Normals are 100% correct. But the Specular unfortunately not.
I wrote a simple forward renderer to try out my Phong shader and there everything works just fine (completly in view space).
It seems the only problem I've got now is correctly reconstructing the View Space Position from Linear ViewSpace Depth.
viewRay * Depth does not work for me. Assuming the Depth is correct (which I think it is) the viewRay itself has to be wrong.
I haven't tried calculating it with FrustumCorners yet but MJP's solution says I can just pass in the viewPosition from the VertexShader in my FullscreenQuad pass like this:
float4 viewPosition = mul(input.Position, inverseProjection);

What am I doing wrong ? I've been at this for weeks now with no resolution

##### Share on other sites
Does input.Position have Z and W set to 1.0?

##### Share on other sites
It wasn't. No change though...

Outputting (viewRay * Depth) * 100 gives me something like this:
http://cl.ly/321M4636091x3b231f0m

##### Share on other sites
Ok finally "some" good news. I've got it working with both Phong/Blinn-Phong now.
The problem was that I had to normalize a lot of the vectors for it to work (kinda stupid but that was the problem).
Anyway here's the code for the Directional Light with Blinn-Phong (+ energy conserving):
PSO_Lighting BlinnPhong_DirectionalLight(float3 Position, float3 L, float3 N, SpecularMaterial material) { PSO_Lighting output = (PSO_Lighting)0; // Transform LightDirection to View Space L = normalize(mul(normalize(L), View)); //Calculate N.L float NL = saturate(dot(N, -L)); //Calculate Diffuse float3 Diffuse = LightColor.xyz * LightIntensity; // Specular Color float3 SpecColor; // If the Specular Color is the same as the Light, use the Lights Color if(Diffuse.r == material.SpecularColor.r && Diffuse.g == material.SpecularColor.g && Diffuse.b == material.SpecularColor.b) { SpecColor = Diffuse; } else { // If both Light and Material Color is different then combine and average them SpecColor = (Diffuse + material.SpecularColor) / 2; } // Normalized View Direction float3 V = normalize(normalize(mul(CameraPosition, View)) - normalize(Position)); // Calculate Half-Vector float3 H = normalize(V - L); // Calculate Normalization Factor for Energy Conserving BRDF float NormalizationFactor = (material.SpecularPower + 8) / (8 * 3.14159265); // Calculate N dot H float NH = pow(saturate(dot(N, H)), material.SpecularPower * specularBias); output.Lighting = float4(NL * Diffuse.r, NL * Diffuse.g, NL * Diffuse.b, 1); output.Specular = float4(NL * NH * NormalizationFactor * SpecColor.r, NL * NH * NormalizationFactor * SpecColor.g, NL * NH * NormalizationFactor * SpecColor.b, 1); return output; }

What's left now is to get it working with point light geometry, can anyone see a flaw in this solution ? :
PSO_Lighting BlinnPhong_PointLight(float3 Position, float3 L, float3 N, SpecularMaterial material) { PSO_Lighting output = (PSO_Lighting)0; L = mul(L, View); // Calculate Attenuation float Attenuation = saturate(1.0f - max(.01f, length(L)) / (LightRadius / 2)); L = normalize(L); // Transform LightDirection to View Space L = L - normalize(Position); //Calculate N.L float NL = saturate(dot(N, -L)); //Calculate Diffuse float3 Diffuse = LightColor.xyz * LightIntensity; // Specular Color float3 SpecColor; // If the Specular Color is the same as the Light, use the Lights Color if(Diffuse.r == material.SpecularColor.r && Diffuse.g == material.SpecularColor.g && Diffuse.b == material.SpecularColor.b) { SpecColor = Diffuse; } else { // If both Light and Material Color is different then combine and average them SpecColor = (Diffuse + material.SpecularColor) / 2; } // Normalized View Direction float3 V = normalize(normalize(mul(CameraPosition, View)) - normalize(Position)); // Calculate Half-Vector float3 H = normalize(V - normalize(L)); // Calculate Normalization Factor for Energy Conserving BRDF float NormalizationFactor = (material.SpecularPower + 8) / (8 * 3.14159265); // Calculate N dot H float NH = pow(saturate(dot(N, H)), material.SpecularPower * specularBias); output.Lighting = float4(NL * Diffuse.r * Attenuation, NL * Diffuse.g * Attenuation, NL * Diffuse.b * Attenuation, 1); output.Specular = float4(NL * NH * NormalizationFactor * SpecColor.r, NL * NH * NormalizationFactor * SpecColor.g, NL * NH * NormalizationFactor * SpecColor.b, 1); return output; }

Position = straight ViewPosition output of point light geometry from the VS

1. 1
2. 2
Rutin
20
3. 3
khawk
16
4. 4
A4L
14
5. 5

• 11
• 16
• 26
• 10
• 11
• ### Forum Statistics

• Total Topics
633756
• Total Posts
3013707
×