   WS Position from Depth (RenderMonkey)
  I'm writing a light pre-pass renderer, and at the moment I'm implementing the required shaders in RenderMonkey before using them in my engine.All my normal and lighting calculations work correctly, it's just recreating the position that I am having trouble with.I was previously calculating the world position by multiplying the depth by the inverse of the view*projection matrix per pixel, which worked but in my engine it became slow when working with a lot of lights.I'm now trying to recreate the world space based on the method described in the second comment in the following post:http://diaryofagraphicsprogrammer.blogspot.com/2008/09/calculating-screen-space-texture.htmlThe viewVecUpperLeft,etc in my light pass vertex shader will be passed in through my engine as a float4x4, but since I can't (or haven't worked out how to) simulate such a thing in RenderMonkey I'm calculating them in the lighting pass. Also, I'm using geometry for my lights (currently a sphere), but in the future it may be a box or a cone. I'm rendering my normal/depths to a A32B32G32R32F render target, which might be a waste of memory but reduces the need to pack bits (I might lower it down to A16B16G16R16F if the precision is still acceptable).My lighting pass is suppose to be outputing the world-space position as the colour. So when working "correctly" it should output red on the half, green on the top half, blue on the bottom half. It's kind of doing this now (from front on), but when I rotate around the model it completely distorts.My normal and depth pass:float4x4 matWorldViewProjection;float4x4 matWorldView;float4x4 matWorld;struct VS_INPUT {   float4 Position : POSITION0;   float3 Normal : NORMAL0;   float3 Tangent : TANGENT0;   float2 TexCoord : TEXCOORD0;   };struct VS_OUTPUT {   float4 Position    : POSITION;   float4 WorldPos : TEXCOORD0;   float3 Normal : TEXCOORD1;   float2 TexCoord : TEXCOORD2;   float3 Tangent : TEXCOORD3;   float3 Binormal : TEXCOORD4;};VS_OUTPUT vs_main( VS_INPUT Input ){   VS_OUTPUT Output;   Output.Position = mul( Input.Position, matWorldViewProjection );   Output.Normal = mul(Input.Normal, matWorldView);   Output.TexCoord = Input.TexCoord;   Output.Tangent = mul(Input.Tangent, matWorldView);   Output.Binormal = cross(Output.Normal, Output.Tangent); Output.WorldPos = mul(Input.Position, matWorld); return( Output );}sampler2D normalmap;float fFarClipPlane;float4 vViewPosition;float4 vViewDirection;float4x4 matView;struct PS_INPUT {   float4 WorldPos : TEXCOORD0;   float3 Normal : TEXCOORD1;   float2 TexCoord : TEXCOORD2;   float3 Tangent : TEXCOORD3;   float3 Binormal : TEXCOORD4;};struct PS_OUTPUT{   float4 NormalMap : COLOR0;};PS_OUTPUT ps_main( PS_INPUT Input ){   PS_OUTPUT Output;   float3 Normal = tex2D(normalmap, Input.TexCoord) - 0.5;   Normal = Normal.x * -Input.Tangent + Normal.y * -Input.Binormal + Normal.z * Input.Normal; float3 vEye = normalize(vViewDirection) / fFarClipPlane; Input.WorldPos.xyz /= Input.WorldPos.w; float depth = dot(vEye, (Input.WorldPos.xyz - vViewPosition.xyz)); Output.NormalMap = float4(normalize(Normal), depth);   return Output;}Light pass:float4x4 matWorldViewProjection;float4x4 matWorld;float2 fInverseViewportDimensions;float fFarClipPlane;float4 vViewPosition;float4 vViewDirection;float4 vViewSide;float4 vViewUp;float fFOV;float2 fViewportDimensions;struct appin{   float4 Position : POSITION;};struct vertout{   float4 Position : POSITION;   float3 ScreenCoords : TEXCOORD0;   float3 FarClipPlane : TEXCOORD1;   float4 WorldPos : TEXCOORD2;};vertout vs_main( appin IN){   vertout OUT;   OUT.Position = mul(IN.Position, matWorldViewProjection);   OUT.ScreenCoords.x = (OUT.Position.x / OUT.Position.w) + 1;   OUT.ScreenCoords.y = 1 - (OUT.Position.y / OUT.Position.w);   OUT.ScreenCoords.z = OUT.Position.w; OUT.ScreenCoords.xy += fInverseViewportDimensions;   OUT.ScreenCoords.xy *= 0.5f; /* calculate corners */   // This will be a matrix calculated in my game engine and passed through as a matrix,   // but while using RenderMonkey I must calculate it in the shader:   // ------------------------------ begin   float3 fc = vViewPosition.xyz + vViewDirection.xyz * fFarClipPlane; float tang = tan((3.14159265358979323846/180.0) * fFOV * 0.5);   float HFar = tang * fFarClipPlane;   float WFar = HFar * (fViewportDimensions.x / fViewportDimensions.y); float3 viewVecUpperLeft = fc + (vViewUp * HFar / 2) - (vViewSide * WFar / 2);   float3 viewVecUpperRight = fc + (vViewUp * HFar / 2) + (vViewSide * WFar / 2);   float3 viewVecLowerLeft = fc - (vViewUp * HFar / 2) - (vViewSide * WFar / 2);   float3 viewVecLowerRight = fc - (vViewUp * HFar / 2) + (vViewSide * WFar / 2);   // ------------------------------ end   OUT.WorldPos = mul(IN.Position, matWorld);   float3 upper = lerp(viewVecUpperLeft, viewVecUpperRight, OUT.ScreenCoords.x);   float3 lower = lerp(viewVecLowerLeft, viewVecLowerRight, OUT.ScreenCoords.x);   OUT.FarClipPlane = lerp (upper, lower, OUT.ScreenCoords.y); OUT.ScreenCoords.xy *= OUT.Position.w; return OUT;}sampler NormalMap;float3 LightPosition;float LightRange;float3 LightColour;float LightAttenuation;float SpecularPower;float4 vViewPosition;float2 fInverseViewportDimensions;float fFarClipPlane;struct fragin{   float3 ScreenCoords : TEXCOORD0;   float3 FarClipPlane : TEXCOORD1;   float4 WorldPos : TEXCOORD2;};struct fragout{   float4 Colour : COLOR0;};inline float3 getDistanceVectorToPlane(in float negFarPlaneDotEye,   in float3 direction, in float3 plane){   float denum = dot(plane, direction);   float t = negFarPlaneDotEye / denum;   return direction * t;    }fragout ps_main(fragin IN) : COLOR0{   fragout OUT;   IN.ScreenCoords.xy /= IN.ScreenCoords.z;   float4 normalMap = tex2D(NormalMap, IN.ScreenCoords.xy); float3 eyeRay = getDistanceVectorToPlane(dot(IN.FarClipPlane, vViewPosition),   IN.WorldPos.xyz / IN.WorldPos.w, IN.FarClipPlane); float3 position = vViewPosition + (eyeRay - vViewPosition) * normalMap.w;   // Lighting calculations here, but I've snipped this out just to focus on the position   OUT.Colour = float4(position,0);   return OUT;}