diff --git a/build/engine/shaders/const.h b/build/engine/shaders/const.h
index c679b050cd6e681db084f13afdbeb253a0c9c75f..52e0dbc2fcf6eee1d83f2879715f9a033e6f40a1 100644
--- a/build/engine/shaders/const.h
+++ b/build/engine/shaders/const.h
@@ -12,6 +12,17 @@ const.h
 	float4 vWinSize;
 	float4 vNearFarLayers;
 }; */
+cbuffer CDataObserverCamera: register(b5)
+{
+	// float4x4 mV;
+	float4x4 g_mObserverVP;
+	float4 g_vObserverPosCam;
+	float4x4 g_mObserverInvVP;
+	float4x4 g_mObserverInvV;
+	
+	float4 g_vObserverNearFar;
+	float3 g_vObserverParamProj;
+};
 cbuffer CDataFrame: register(b4)
 {
 	float g_fFrameTime;
@@ -26,6 +37,10 @@ cbuffer CDataCamera: register(b2)
 	float4x4 g_mVP;
 	float4 g_vPosCam;
 	float4x4 g_mInvVP;
+	float4x4 g_mInvV;
+	
+	float4 g_vNearFar;
+	float3 g_vParamProj;
 };
 cbuffer CDataObject: register(b1)
 {
@@ -33,13 +48,13 @@ cbuffer CDataObject: register(b1)
 	// float4x4 g_mWV;
 	// float4x4 g_mWVP;
 };
-cbuffer CDataMaterial: register(b0)
+/* cbuffer CDataMaterial: register(b0)
 {
 	float4 g_vUserVS;
 	float4 g_vUserPS;
 	float4 g_vDestColor;
 	float4 g_vNearFarLayers;
-};
+}; */
 
 
 
diff --git a/build/engine/shaders/gi/gi_cubes.gs b/build/engine/shaders/gi/gi_cubes.gs
index fa638bafb634e621723294fa19152ebc5ed844fb..083efb784dd3e446837962e46bb40222ef2931bb 100644
--- a/build/engine/shaders/gi/gi_cubes.gs
+++ b/build/engine/shaders/gi/gi_cubes.gs
@@ -5,21 +5,7 @@ terrax_colored.vs
 */
 
 #include <struct.h>
-
-//##########################################################################
-
-cbuffer perFrame: register(b1)
-{
-	float4x4 g_mVP;
-	float4x4 g_mViewInv;
-	float2 g_vNearFar;
-	float3 g_vParamProj;
-};
-
-/* cbuffer b10: register(b10)
-{
-	float4 g_vCurrentCascade;
-}; */
+#include <const.h>
 
 //##########################################################################
 
@@ -34,14 +20,14 @@ void main(point VSO_GICubes input[1], inout TriangleStream<GSO_GICubes> OutputSt
 	float3 vCenter = input[0].vPosition.xyz;
 	
 	const GSO_GICubes vertices[8] = {
-		{mul(input[0].vPosition + float4(fSize, fSize, fSize, 0), g_mVP),    float3(fNormal, fNormal, fNormal),    vCenter},// 0
-		{mul(input[0].vPosition + float4(fSize, -fSize, fSize, 0), g_mVP),   float3(fNormal, -fNormal, fNormal),   vCenter},// 1
-		{mul(input[0].vPosition + float4(fSize, fSize, -fSize, 0), g_mVP),   float3(fNormal, fNormal, -fNormal),   vCenter},// 2
-		{mul(input[0].vPosition + float4(fSize, -fSize, -fSize, 0), g_mVP),  float3(fNormal, -fNormal, -fNormal),  vCenter},// 3
-		{mul(input[0].vPosition + float4(-fSize, -fSize, -fSize, 0), g_mVP), float3(-fNormal, -fNormal, -fNormal), vCenter},// 4
-		{mul(input[0].vPosition + float4(-fSize, -fSize, fSize, 0), g_mVP),  float3(-fNormal, -fNormal, fNormal),  vCenter},// 5
-		{mul(input[0].vPosition + float4(-fSize, fSize, fSize, 0), g_mVP),   float3(-fNormal, fNormal, fNormal),   vCenter},// 6
-		{mul(input[0].vPosition + float4(-fSize, fSize, -fSize, 0), g_mVP),  float3(-fNormal, fNormal, -fNormal),  vCenter}// 7
+		{mul(input[0].vPosition + float4(fSize, fSize, fSize, 0), g_mObserverVP),    float3(fNormal, fNormal, fNormal),    vCenter},// 0
+		{mul(input[0].vPosition + float4(fSize, -fSize, fSize, 0), g_mObserverVP),   float3(fNormal, -fNormal, fNormal),   vCenter},// 1
+		{mul(input[0].vPosition + float4(fSize, fSize, -fSize, 0), g_mObserverVP),   float3(fNormal, fNormal, -fNormal),   vCenter},// 2
+		{mul(input[0].vPosition + float4(fSize, -fSize, -fSize, 0), g_mObserverVP),  float3(fNormal, -fNormal, -fNormal),  vCenter},// 3
+		{mul(input[0].vPosition + float4(-fSize, -fSize, -fSize, 0), g_mObserverVP), float3(-fNormal, -fNormal, -fNormal), vCenter},// 4
+		{mul(input[0].vPosition + float4(-fSize, -fSize, fSize, 0), g_mObserverVP),  float3(-fNormal, -fNormal, fNormal),  vCenter},// 5
+		{mul(input[0].vPosition + float4(-fSize, fSize, fSize, 0), g_mObserverVP),   float3(-fNormal, fNormal, fNormal),   vCenter},// 6
+		{mul(input[0].vPosition + float4(-fSize, fSize, -fSize, 0), g_mObserverVP),  float3(-fNormal, fNormal, -fNormal),  vCenter}// 7
 	};
 
 	OutputStream.Append(vertices[0]);
diff --git a/build/engine/shaders/gi/gi_cubes.ps b/build/engine/shaders/gi/gi_cubes.ps
index 899e1145d40742ec19bfd234d5cedf5fbc053a55..5e4ace7c404780e1020868cd11462165052c7bcb 100644
--- a/build/engine/shaders/gi/gi_cubes.ps
+++ b/build/engine/shaders/gi/gi_cubes.ps
@@ -14,13 +14,6 @@ Texture3D g_txIllumRed: register(t0);
 Texture3D g_txIllumGreen: register(t1);
 Texture3D g_txIllumBlue: register(t2);
 
-cbuffer b8: register(b8)
-{
-	// float4x4 mV;
-	float4x4 g_mVP;
-	float4 g_vPosCam;
-};
-
 //##########################################################################
 
 float4 main(GSO_GICubes IN):COLOR0
diff --git a/build/engine/shaders/gi/gi_cubes.vs b/build/engine/shaders/gi/gi_cubes.vs
index 3ff5aeb01bb2fba61c553d5217f0a29f35c94e18..5c978b9f2ebaf5c1dde6692cbfd16fac98c8006a 100644
--- a/build/engine/shaders/gi/gi_cubes.vs
+++ b/build/engine/shaders/gi/gi_cubes.vs
@@ -9,16 +9,6 @@ terrax_colored.vs
 
 //##########################################################################
 
-cbuffer perFrame: register(b1)
-{
-	float4x4 g_mVP;
-	float4x4 g_mViewInv;
-	float2 g_vNearFar;
-	float3 g_vParamProj;
-};
-
-//##########################################################################
-
 VSO_GICubes main(VSI_GICubes IN)
 {
 	uint uCurrentCascade = g_vCurrentCascade.x;
diff --git a/build/engine/shaders/gi/gi_inject.vs b/build/engine/shaders/gi/gi_inject.vs
index 5b91ecaa783b9835a24c869ca10002f20957c736..fd7dbf84386e311dfdd4d41e59d32dcd98bb9663 100644
--- a/build/engine/shaders/gi/gi_inject.vs
+++ b/build/engine/shaders/gi/gi_inject.vs
@@ -1,5 +1,6 @@
 
 #include <lpv.h>
+#include <const.h>
 
 cbuffer perLight: register(b7)
 {
@@ -13,14 +14,7 @@ cbuffer perLight: register(b7)
 
 cbuffer b6 :register(b6)
 {
-	float4x4 g_mInvVP;
-};
-
-cbuffer b8: register(b8)
-{
-	// float4x4 mV;
-	float4x4 g_mVP;
-	float4 g_vPosCam;
+	float4x4 g_mLightInvVP;
 };
 
 struct VS_IN
@@ -68,7 +62,7 @@ RsmTexel GetRsmTexel(int2 coords, uint2 vTexSize)
 	tx.normalWS = rsmWsNorMap.Load(int3(coords, 0)).xyz * 2.0 - 1.0;
 	vScreenSpace.y *= -1.0;
 	
-	float4 vWS = mul(vScreenSpace, g_mInvVP);
+	float4 vWS = mul(vScreenSpace, g_mLightInvVP);
 	tx.positionWS = vWS.xyz / vWS.w;
 	
 #ifndef IS_SUN
@@ -100,7 +94,7 @@ GS_IN main(VS_IN input)
 	GS_IN output1 = (GS_IN)0;
 	// rsmTexel.positionWS = float4(((float2)rsmCoords + 0.5f) / (float2)RSMsize * 2.0 - 1.0, 0.0f, 1.0);
 	// rsmTexel.positionWS = float4(float3((float)(input.posIndex % 512), 0.0f, (float)(input.posIndex / 512)) / 512, 1.0);
-	output1.cellIndex = mul(float4(rsmTexel.positionWS, 1.0), g_mVP);
+	output1.cellIndex = mul(float4(rsmTexel.positionWS, 1.0), g_mObserverVP);
 	return(output1);
 #endif
 	
diff --git a/build/engine/shaders/gi/gi_inject_cube.vs b/build/engine/shaders/gi/gi_inject_cube.vs
index 22a26f48e7abf15b04ddd9e1acea1150bf66e7f2..f3d2584803ada4247feb68e1a1fd49fd38ca39fa 100644
--- a/build/engine/shaders/gi/gi_inject_cube.vs
+++ b/build/engine/shaders/gi/gi_inject_cube.vs
@@ -1,5 +1,6 @@
 
 #include <lpv.h>
+#include <const.h>
 
 cbuffer perLight: register(b7)
 {
@@ -11,18 +12,6 @@ cbuffer perLight: register(b7)
 #endif
 };
 
-/* cbuffer b6 :register(b6)
-{
-	float4x4 g_mInvVP[6];
-}; */
-
-cbuffer b8: register(b8)
-{
-	// float4x4 mV;
-	float4x4 g_mVP;
-	float4 g_vPosCam;
-};
-
 struct VS_IN
 {
 	uint posIndex :SV_VertexID;
@@ -132,7 +121,7 @@ GS_IN main(VS_IN input)
 	GS_IN output1 = (GS_IN)0;
 	// rsmTexel.positionWS = float4(((float2)rsmCoords + 0.5f) / (float2)RSMsize * 2.0 - 1.0, 0.0f, 1.0);
 	// rsmTexel.positionWS = float4(float3((float)(input.posIndex % 512), 0.0f, (float)(input.posIndex / 512)) / 512, 1.0);
-	output1.cellIndex = mul(float4(rsmTexel.positionWS, 1.0), g_mVP);
+	output1.cellIndex = mul(float4(rsmTexel.positionWS, 1.0), g_mObserverVP);
 	return(output1);
 #endif
 	
diff --git a/build/engine/shaders/lighting/lighting_bound.vs b/build/engine/shaders/lighting/lighting_bound.vs
index b630b0c2549158b95e6cfcff4b77d180846884f1..59a32bb3e03a2228fb395bf07af0754d1a389fef 100644
--- a/build/engine/shaders/lighting/lighting_bound.vs
+++ b/build/engine/shaders/lighting/lighting_bound.vs
@@ -5,29 +5,13 @@ lighting_bound.vs
 */
 
 #include <struct.h>
-
-//##########################################################################
-
-// half4x4 g_mWVP;
-
-cbuffer perLight: register(b0)
-{
-	float4x4 g_mW;
-};
-
-cbuffer perFrame: register(b1)
-{
-	float4x4 g_mVP;
-	float4x4 g_mViewInv;
-	float2 g_vNearFar;
-	float3 g_vParamProj;
-};
+#include <const.h>
 
 //##########################################################################
 
 VSO_LightBound main(VSI_LightBound IN)
 {
 	VSO_LightBound OUT = (VSO_LightBound)0;
-	OUT.vPosition = mul(float4(IN.vPosition, 1.0), mul(g_mW, g_mVP));
+	OUT.vPosition = mul(float4(IN.vPosition, 1.0), mul(g_mW, g_mObserverVP));
 	return(OUT);
 }
diff --git a/build/engine/shaders/lighting/lighting_com.ps b/build/engine/shaders/lighting/lighting_com.ps
index cebf48b94f1e8ad5c92e6480f1380714861bee49..b10884ffbcec07b796c30bd1bfcd491b3325871c 100644
--- a/build/engine/shaders/lighting/lighting_com.ps
+++ b/build/engine/shaders/lighting/lighting_com.ps
@@ -6,14 +6,10 @@ lighting_blend.ps
 
 #include <struct.h>
 #include <mtrl.h>
+#include <const.h>
 
 //##########################################################################
 
-cbuffer CDataScene: register(b3)
-{
-	float4 g_vNearFarInvWinSize;
-};
-
 cbuffer perLight: register(b0)
 {
 	float4 g_vLightColorPower;
@@ -24,11 +20,6 @@ cbuffer perLight: register(b0)
 #endif
 };
 
-cbuffer perFrame: register(b1)
-{
-	float3 g_vPosCam;
-};
-
 
 
 //##########################################################################
@@ -142,9 +133,14 @@ float4 main(VSO_ResPos IN):SV_TARGET
 	float4 vParam = g_txParameters.Sample(g_sPointClamp, IN.vTexUV);
 	float fDepth = g_txDepthView.Sample(g_sPointClamp, IN.vTexUV).r;
 	
-	float4 vPosition = float4(g_vPosCam.xyz + IN.vWorldRay * fDepth, 1.0);
+	float4 vPosition = float4(g_vObserverPosCam.xyz + IN.vWorldRay * fDepth, 1.0);
 	float3 vNormalPixel = normalize(NormalDecode(vNormals.xyz).xyz);
 	
+	// return(float4(g_vObserverPosCam.xyz, 1.0f));
+	// return(float4(frac(vPosition.zzz), 1.0f));
+	// return(float4((float3)fDepth, 1.0f));
+	// return(float4(frac(IN.vWorldRay), 1.0f));
+	
 	float fF0 = vNormals.w;
 	float fRoughness = lerp(PARAM_LIGHTING_ROUGHNESS_MIN, PARAM_LIGHTING_ROUGHNESS_MAX, vParam.x);
 	float fMetallic = vParam.y;
@@ -177,7 +173,7 @@ float4 main(VSO_ResPos IN):SV_TARGET
 	fShadow *= saturate(fNdotD - g_vLightSpotInnerOuterAngles.y) / (g_vLightSpotInnerOuterAngles.x - g_vLightSpotInnerOuterAngles.y);
 #endif
 	
-	float3 vVertexToEye = normalize(g_vPosCam.xyz - vPosition.xyz);
+	float3 vVertexToEye = normalize(g_vObserverPosCam.xyz - vPosition.xyz);
 	
 	float fNdotL = dot(vNormalPixel, vLigth);
 	
diff --git a/build/engine/shaders/lighting/lighting_gi.ps b/build/engine/shaders/lighting/lighting_gi.ps
index c2b6360c9d0ffc49ee4a8104c5b739cb2469e7b2..745e3d5ca4f8069d9bd411475690206984a6dd81 100644
--- a/build/engine/shaders/lighting/lighting_gi.ps
+++ b/build/engine/shaders/lighting/lighting_gi.ps
@@ -7,13 +7,7 @@ lighting_gi.ps
 #include <lpv.h>
 #include <struct.h>
 #include <mtrl.h>
-
-//##########################################################################
-
-cbuffer perFrame: register(b1)
-{
-	float3 g_vViewPos;
-};
+#include <const.h>
 
 //##########################################################################
 
@@ -38,12 +32,12 @@ PSO_Lbuffer main(VSO_ResPos IN)
 	float fMetallic = vParams.y;
 	
 	float3 vOrigin = float3(0, 0, 0); // Центр сетки
-	float3 vPosition = g_vViewPos + IN.vWorldRay * fDepth; // Мировая позиция пиксела
+	float3 vPosition = g_vObserverPosCam + IN.vWorldRay * fDepth; // Мировая позиция пиксела
 	
 	
 	float3 vNormalPixel = normalize(NormalDecode(vNormals.xyz).xyz);
 	
-	float3 vReflectDir = -normalize(reflect(g_vViewPos - vPosition, vNormalPixel));
+	float3 vReflectDir = -normalize(reflect(g_vObserverPosCam - vPosition, vNormalPixel));
 	
 	// OUT.vAmdient.xyz = lerp(vAlbedo.xyz, GetPixelLight(vPosition, vNormalPixel) * vAlbedo.xyz, vAlbedo.w);
 	OUT.vAmdient.xyz = lerp(vAlbedo.xyz, GetPixelLight(vPosition, lerp(vNormalPixel, vReflectDir, fMetallic)) * vAlbedo.xyz, vAlbedo.w);
diff --git a/build/engine/shaders/material/gbuffer.ps b/build/engine/shaders/material/gbuffer.ps
index e6800563a711100cecdd737bbf564a6d3a113c62..972acfd518ef883cee554ff35bf18e546996c731 100644
--- a/build/engine/shaders/material/gbuffer.ps
+++ b/build/engine/shaders/material/gbuffer.ps
@@ -17,7 +17,7 @@ PSO_Gbuffer main(PSI_XMaterial IN)
 	IN.vNormal = normalize(IN.vNormal);
 	
 #ifndef WANT_WRITE_DEPTH
-	float fDepth = 1.0f - (IN.vPos.z / g_vNearFarInvWinSize.x);
+	float fDepth = 1.0f - (IN.vPos.z / g_vNearFar.x);
 #endif
 
 	XMaterial mtrl = XMATERIAL_MAIN(IN);
@@ -39,7 +39,7 @@ PSO_Gbuffer main(PSI_XMaterial IN)
 	
 	//float fDepth = 
 #ifdef WANT_WRITE_DEPTH
-	float fDepth = (mtrl.fDepth + g_vNearFarInvWinSize.x) / g_vNearFarInvWinSize.y;
+	float fDepth = (mtrl.fDepth + g_vNearFar.x) / g_vNearFar.y;
 #else
 	// 1.0f - IN.vPos.z / g_vNearFarInvWinSize.x;
 	//(IN.vPos.z / IN.vPos.w);
diff --git a/build/engine/shaders/pp/pp_res_pos.vs b/build/engine/shaders/pp/pp_res_pos.vs
index b1393bb871c9123baf57aa725c59a29133c98867..5aa55c6bab24f37e72de5dd5d050886400053367 100644
--- a/build/engine/shaders/pp/pp_res_pos.vs
+++ b/build/engine/shaders/pp/pp_res_pos.vs
@@ -5,16 +5,7 @@ pp_res_pos.vs
 */
 
 #include <struct.h>
-
-//##########################################################################
-
-cbuffer perFrame: register(b1)
-{
-	float4x4 g_mVP;
-	float4x4 g_mViewInv;
-	float4 g_vNearFar;
-	float3 g_vParamProj;
-};
+#include <const.h>
 
 //##########################################################################
 
@@ -24,13 +15,13 @@ VSO_ResPos main(VSI_PP IN)
 	OUT.vPosition = float4(IN.vPosition, 1.0);
 	OUT.vTexUV = IN.vTexUV.xy;
 	
-	float fTanHalfFOV = tan(g_vParamProj.z * 0.5) ; 
-	float aspectRatio = g_vParamProj.x / g_vParamProj.y; 
-	float fFarY = fTanHalfFOV * g_vNearFar.y; 
+	float fTanHalfFOV = tan(g_vObserverParamProj.z * 0.5) ; 
+	float aspectRatio = g_vObserverParamProj.x / g_vObserverParamProj.y; 
+	float fFarY = fTanHalfFOV * g_vObserverNearFar.y; 
 	float fFarX = fFarY * aspectRatio; 
 	
-	OUT.vEyeRay = float3(sign(OUT.vPosition.x) * fFarX, sign(OUT.vPosition.y) * fFarY, g_vNearFar.y); 
-	OUT.vWorldRay = mul(float4(OUT.vEyeRay, 0.0), g_mViewInv).xyz;
-  
+	OUT.vEyeRay = float3(sign(OUT.vPosition.x) * fFarX, sign(OUT.vPosition.y) * fFarY, g_vObserverNearFar.y); 
+	OUT.vWorldRay = mul(float4(OUT.vEyeRay, 0.0), g_mObserverInvV).xyz;
+	
 	return OUT;
 }
\ No newline at end of file
diff --git a/build/engine/shaders/ppgensm/ppgensm_direct.ps b/build/engine/shaders/ppgensm/ppgensm_direct.ps
index f0d45a2121aaa6212a2a06091973ec870f471428..92fee22b38ebb0dc2db8615247a5dfc4ed26361f 100644
--- a/build/engine/shaders/ppgensm/ppgensm_direct.ps
+++ b/build/engine/shaders/ppgensm/ppgensm_direct.ps
@@ -61,7 +61,7 @@ float4 main(VSO_ResPos IN):COLOR0
 	//g_txDepthShadow.Sample(g_sLinearClamp, IN.vTexUV)
 	
 	float fDepth = g_txDepthView.Sample(g_sPointClamp, IN.vTexUV).r;
-	float4 vPixelPos = float4(g_vPosCam + IN.vWorldRay * fDepth,1.f);
+	float4 vPixelPos = float4(g_vObserverPosCam + IN.vWorldRay * fDepth,1.f);
 	float4 vTexCoord = mul(vPixelPos, g_mMatrixTexture);
 	vTexCoord.xyz = vTexCoord.xyz / vTexCoord.w;
 	
diff --git a/build/engine/shaders/ppgensm/ppgensm_pssm.ps b/build/engine/shaders/ppgensm/ppgensm_pssm.ps
index 02fc594173d8f799455f66571cc73486ef47ed0d..f7677b668320b2f70e67686815b6fd1485912414 100644
--- a/build/engine/shaders/ppgensm/ppgensm_pssm.ps
+++ b/build/engine/shaders/ppgensm/ppgensm_pssm.ps
@@ -55,7 +55,7 @@ cbuffer perShadow: register(b6)
 {
 	float4x4 g_mMatrixTextureV[6];
 	float4x4 g_mMatrixTextureP[6];
-	float4 vSizeBoundNearFar;
+	float4 g_vSizeBoundNearFar;
 };
 
 SamplerComparisonState g_sComparisonLinearClamp: register(s1);
@@ -71,9 +71,9 @@ float4 main(VSO_ResPos IN): COLOR0
 	float fShadow = 1.0f;
 	float fDepth = g_txDepthView.Sample(g_sPointClamp, IN.vTexUV).r;
 	float3 vNormalWS = normalize(NormalDecode(g_txNormals.Sample(g_sPointClamp, IN.vTexUV).xyz).xyz);
-	float4 vPixelPosWS = float4(g_vPosCam + IN.vWorldRay * fDepth, 1.f);
+	float4 vPixelPosWS = float4(g_vObserverPosCam + IN.vWorldRay * fDepth, 1.f);
 	
-	float delta = 1.0f / vSizeBoundNearFar.x;
+	float delta = 1.0f / g_vSizeBoundNearFar.x;
 		
 	[unroll]for(int split = 0; split < NUM_SPLITS; split++)   
 	{
@@ -93,18 +93,18 @@ float4 main(VSO_ResPos IN): COLOR0
 				float3 vNormalLS = normalize(mul(float4(vNormalWS, 0.0f), g_mMatrixTextureV[split]).xyz);
 				
 				// Locate corresponding light space shadow map grid center
-				float2 index = floor(vTexCoord.xy * vSizeBoundNearFar.xx);
+				float2 index = floor(vTexCoord.xy * g_vSizeBoundNearFar.xx);
 				
 				// Normalized coordinate in [0,1]
 				float2 nlsGridCenter = 2.0f * delta * (index + float2(0.5f, 0.5f)); // Normalized eye space grid center --- [0,1]
 				
 				// Unnormalized coordinate in [-lightLeft,lightLeft]
-				float2 lsGridCenter = vSizeBoundNearFar.y * (2.0f * nlsGridCenter - float2(1.0f, 1.0f));
+				float2 lsGridCenter = g_vSizeBoundNearFar.y * (2.0f * nlsGridCenter - float2(1.0f, 1.0f));
 				
 				/** Define light ray **/
 				// Light ray direction in light space
-				// float3 lsGridLineDir = normalize(float3(lsGridCenter, -vSizeBoundNearFar.z)); // Light space grid line direction    
-				float3 lsGridLineDir = normalize(float3(0.0f, 0.0f, -vSizeBoundNearFar.z)); // Light space grid line direction    
+				// float3 lsGridLineDir = normalize(float3(lsGridCenter, -g_vSizeBoundNearFar.z)); // Light space grid line direction    
+				float3 lsGridLineDir = normalize(float3(0.0f, 0.0f, -g_vSizeBoundNearFar.z)); // Light space grid line direction    
 				
 				/** Plane ray intersection **/
 				// Locate the potential occluder for the shading fragment
@@ -124,8 +124,8 @@ float4 main(VSO_ResPos IN): COLOR0
 				float SMDepth = g_txDepthShadow.Sample(g_sPointClamp, cubeCoord).r;
 				// A and B are computed bnased on light near and far planes.
 				// They can be retrieved directly from light projection matrix
-				float A = vSizeBoundNearFar.w * g_mMatrixTextureP[split][2][2];
-				float B = vSizeBoundNearFar.w * g_mMatrixTextureP[split][3][2];    
+				float A = g_vSizeBoundNearFar.w * g_mMatrixTextureP[split][2][2];
+				float B = g_vSizeBoundNearFar.w * g_mMatrixTextureP[split][3][2];    
 				float adaptiveDepthBias = 0.5f * pow(1.0f - A - 2.0f * SMDepth, 2) * constantBias / B; 
 				
 				
diff --git a/build/gamesource/shaders/dbg/dbg_colorvertex.vs b/build/gamesource/shaders/dbg/dbg_colorvertex.vs
index 270b512f0fb5e351de50b018af284d08757c4ccd..ba49bb642913d84b241466d8d7f420204acfa5dd 100644
--- a/build/gamesource/shaders/dbg/dbg_colorvertex.vs
+++ b/build/gamesource/shaders/dbg/dbg_colorvertex.vs
@@ -4,7 +4,7 @@ terrax_colored.vs
 
 */
 
-#include <../struct.h>
+#include <struct.h>
 
 //##########################################################################
 
diff --git a/proj/sxgcore/vs2013/sxgcore.vcxproj b/proj/sxgcore/vs2013/sxgcore.vcxproj
index f3fc543e5b741ca3a33ba8067e281e89178f4d0c..511c54310e2bd4bc0d4280c8d01f9e11299336c3 100644
--- a/proj/sxgcore/vs2013/sxgcore.vcxproj
+++ b/proj/sxgcore/vs2013/sxgcore.vcxproj
@@ -216,7 +216,6 @@
     <ClCompile Include="..\..\..\source\gcore\sxgcore_dll.cpp" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\..\source\common\file_utils.h" />
     <ClInclude Include="..\..\..\source\common\string.h" />
     <ClInclude Include="..\..\..\source\common\string_utils.h" />
     <ClInclude Include="..\..\..\source\gcore\bound.h" />
diff --git a/proj/sxgcore/vs2013/sxgcore.vcxproj.filters b/proj/sxgcore/vs2013/sxgcore.vcxproj.filters
index 1b94e99ca5866f57f52c4c7ac36fb097332c403e..2df9faf328a0487e222d83e956baa3b510361d56 100644
--- a/proj/sxgcore/vs2013/sxgcore.vcxproj.filters
+++ b/proj/sxgcore/vs2013/sxgcore.vcxproj.filters
@@ -53,9 +53,6 @@
     <ClInclude Include="..\..\..\source\common\string.h">
       <Filter>Header</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\source\common\file_utils.h">
-      <Filter>Header</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\..\source\common\string_utils.h">
       <Filter>Header</Filter>
     </ClInclude>
diff --git a/proj/sxlight/vs2013/sxlight.vcxproj b/proj/sxlight/vs2013/sxlight.vcxproj
index 0076731cc8ace8557ac83f6e34d86ccb049ee92e..681e5c4de42937d0fcc054c0f5172842de724e35 100644
--- a/proj/sxlight/vs2013/sxlight.vcxproj
+++ b/proj/sxlight/vs2013/sxlight.vcxproj
@@ -192,6 +192,8 @@
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
     </ClCompile>
     <ClCompile Include="..\..\..\source\light\plugin_main.cpp" />
+    <ClCompile Include="..\..\..\source\light\shadow.cpp" />
+    <ClCompile Include="..\..\..\source\light\ShadowCache.cpp" />
     <ClCompile Include="..\..\..\source\light\sxlight.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
@@ -206,6 +208,8 @@
     <ClInclude Include="..\..\..\source\light\IXLightSystem.h" />
     <ClInclude Include="..\..\..\source\light\light.h" />
     <ClInclude Include="..\..\..\source\light\ml_data.h" />
+    <ClInclude Include="..\..\..\source\light\shadow.h" />
+    <ClInclude Include="..\..\..\source\light\ShadowCache.h" />
     <ClInclude Include="..\..\..\source\light\sxlight.h" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/proj/sxlight/vs2013/sxlight.vcxproj.filters b/proj/sxlight/vs2013/sxlight.vcxproj.filters
index de82e405b079c69f245e09e50d1af40a3cc741ff..c57c72b6d63a89dbd38a293bbd7785d0b7a66657 100644
--- a/proj/sxlight/vs2013/sxlight.vcxproj.filters
+++ b/proj/sxlight/vs2013/sxlight.vcxproj.filters
@@ -19,6 +19,12 @@
     <ClCompile Include="..\..\..\source\light\LightSystem.cpp">
       <Filter>Source</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\source\light\shadow.cpp">
+      <Filter>Source</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\source\light\ShadowCache.cpp">
+      <Filter>Source</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Source">
@@ -47,5 +53,11 @@
     <ClInclude Include="..\..\..\source\light\LightSystem.h">
       <Filter>Headers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\source\light\ShadowCache.h">
+      <Filter>Headers</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\source\light\shadow.h">
+      <Filter>Headers</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/proj/sxrender/vs2013/sxrender.vcxproj b/proj/sxrender/vs2013/sxrender.vcxproj
index e1c6b0533d6aaa3fe4937952064c47765cb74bf8..d9e7ca77e9194bc6d142d8f48cbdd2c3c208108d 100644
--- a/proj/sxrender/vs2013/sxrender.vcxproj
+++ b/proj/sxrender/vs2013/sxrender.vcxproj
@@ -187,8 +187,6 @@
     <ClInclude Include="..\..\..\source\render\RenderableVisibility.h" />
     <ClInclude Include="..\..\..\source\render\RenderPipeline.h" />
     <ClInclude Include="..\..\..\source\render\render_func.h" />
-    <ClInclude Include="..\..\..\source\render\shadow.h" />
-    <ClInclude Include="..\..\..\source\render\ShadowCache.h" />
     <ClInclude Include="..\..\..\source\render\sxrender.h" />
   </ItemGroup>
   <ItemGroup>
@@ -200,8 +198,6 @@
     <ClCompile Include="..\..\..\source\render\RenderableVisibility.cpp" />
     <ClCompile Include="..\..\..\source\render\RenderPipeline.cpp" />
     <ClCompile Include="..\..\..\source\render\render_func.cpp" />
-    <ClCompile Include="..\..\..\source\render\shadow.cpp" />
-    <ClCompile Include="..\..\..\source\render\ShadowCache.cpp" />
     <ClCompile Include="..\..\..\source\render\sxrender.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/proj/sxrender/vs2013/sxrender.vcxproj.filters b/proj/sxrender/vs2013/sxrender.vcxproj.filters
index ea8474fa695eb50d273eacd0d41acde075f35460..4a957e1884c5323daa8aacb2e54e3927de389d67 100644
--- a/proj/sxrender/vs2013/sxrender.vcxproj.filters
+++ b/proj/sxrender/vs2013/sxrender.vcxproj.filters
@@ -36,12 +36,6 @@
     <ClInclude Include="..\..\..\source\render\RenderPipeline.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\..\source\render\ShadowCache.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\..\source\render\shadow.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\..\source\render\RenderableVisibility.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -71,12 +65,6 @@
     <ClCompile Include="..\..\..\source\render\RenderPipeline.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\..\source\render\ShadowCache.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\..\source\render\shadow.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\..\source\render\RenderableVisibility.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/source/game/GameData.cpp b/source/game/GameData.cpp
index c92b35e4b938fc501931f816a31effcddaf88dfd..ea289172e5f9c7b750c784b3bb00e2cd4bc22cbc 100644
--- a/source/game/GameData.cpp
+++ b/source/game/GameData.cpp
@@ -444,7 +444,7 @@ GameData::GameData(HWND hWnd, bool isGame):
 	if(m_pLightSystem)
 	{
 		//	252, 212, 64
-		IXLightSun *pSun = m_pLightSystem->createSun();
+		IXLightSun *pSun = m_pLightSystem->newSun();
 		pSun->setColor(float3(2.52f, 2.12f, 0.64f) * 2.0f);
 		pSun->setDirection(SMQuaternion(LIGHTS_DIR_BASE, float3(1.0f, -1.0f, 1.0f)));
 	}
diff --git a/source/game/LightDirectional.cpp b/source/game/LightDirectional.cpp
index 45300acfc295562991b98f5244aa4d2e43995ec5..711ab4dc0096b54c3f9346a4e018ba87ae2c4455 100644
--- a/source/game/LightDirectional.cpp
+++ b/source/game/LightDirectional.cpp
@@ -29,7 +29,7 @@ CLightDirectional::CLightDirectional(CEntityManager *pMgr):BaseClass(pMgr)
 		{
 			m_fInnerAngle = m_fOuterAngle;
 		}
-		m_pLight = m_pLightSpot = m_pLightSystem->createSpot();
+		m_pLight = m_pLightSpot = m_pLightSystem->newSpot();
 		//m_pLight->setDistance(m_fDist);
 		m_pLight->setColor(m_vColor);
 		m_pLightSpot->setDirection(SMQuaternion(-SM_PI, 'z'));
diff --git a/source/game/LightPoint.cpp b/source/game/LightPoint.cpp
index 519e0d04028a6ecc49369c5bd1793ce35bfd52fc..f1663c6fff1cf406405d44ff43df173fe2518005 100644
--- a/source/game/LightPoint.cpp
+++ b/source/game/LightPoint.cpp
@@ -20,7 +20,7 @@ CLightPoint::CLightPoint(CEntityManager * pMgr):BaseClass(pMgr)
 {
 	if(m_pLightSystem)
 	{
-		m_pLight = m_pLightSystem->createPoint();
+		m_pLight = m_pLightSystem->newPoint();
 		//m_pLight->setDistance(m_fDist);
 		m_pLight->setColor(float4(m_vColor, m_fDist));
 	}
diff --git a/source/gcore/sxgcore.h b/source/gcore/sxgcore.h
index 958c3927f94739283ac9e1e991dfeeb87f5dff46..b4827299c7f3a4ee6008dc12066063545aa58400 100644
--- a/source/gcore/sxgcore.h
+++ b/source/gcore/sxgcore.h
@@ -272,6 +272,7 @@ SX_LIB_API void SGCore_ShaderUnBind();
 
 enum SHADER_CONST_REGISTER
 {
+	SCR_OBSERVER_CAMERA = 5,
 	SCR_FRAME = 4,
 	SCR_SCENE = 3,
 	SCR_CAMERA = 2,
diff --git a/source/level/level.cpp b/source/level/level.cpp
index 44679b58316f770d37cf3274e1d538963d3cd3dd..262b3aba1e382a033b26aa912f1d96364f52c24d 100644
--- a/source/level/level.cpp
+++ b/source/level/level.cpp
@@ -231,7 +231,7 @@ void CLevel::load(const char *szName, bool isGame)
 
 			if(m_pLightSystem)
 			{
-				m_pSun = m_pLightSystem->createSun();
+				m_pSun = m_pLightSystem->newSun();
 				m_pSun->setPosition(float3(60.0f, 60.0f, 0));
 				m_pSun->setColor(float4(1.0f, 1.0f, 1.0f, 100.0f));
 			}
diff --git a/source/level/weather.cpp b/source/level/weather.cpp
index 1bb2244883541449eea1e21d7e9a4d5d027486f1..b0c3af4ea8387a880c88cfa74e58903ecb41e2fa 100644
--- a/source/level/weather.cpp
+++ b/source/level/weather.cpp
@@ -180,7 +180,7 @@ CWeather::CWeather(IXLightSystem *pLightSystem):
 
 	if(m_pLightSystem)
 	{
-		m_pLightThunderbolt = m_pLightSystem->createPoint();
+		m_pLightThunderbolt = m_pLightSystem->newPoint();
 		m_pLightThunderbolt->setColor(float4(1.0f, 1.0f, 1.0f, 200.0f));
 		m_pLightThunderbolt->setEnabled(false);
 	}
diff --git a/source/light/IXLightSystem.h b/source/light/IXLightSystem.h
index 57a5cd3f4951cbf021e75a795370b79d01e4f55a..fcf8c971a2bcd98406663498c4c4882aa5542fc2 100644
--- a/source/light/IXLightSystem.h
+++ b/source/light/IXLightSystem.h
@@ -8,20 +8,28 @@
 #define IXLIGHTSYSTEM_GUID DEFINE_XGUID(0x19ebad4a, 0xf241, 0x4ea9, 0xa4, 0xcd, 0x52, 0x9, 0x6a, 0x2c, 0x1c, 0xe3)
 
 class ICamera;
+class IXRenderPipeline;
 class IXLightSystem: public IXUnknown
 {
 public:
-	virtual IXLightSun *createSun() = 0;
-	virtual IXLightSun *getSun() = 0;
+	virtual IXLightSun* XMETHODCALLTYPE newSun() = 0;
+	virtual IXLightSun* XMETHODCALLTYPE getSun() = 0;
 
+	virtual IXLightPoint* XMETHODCALLTYPE newPoint() = 0;
+	virtual IXLightSpot* XMETHODCALLTYPE newSpot() = 0;
 
-	virtual IXLightPoint *createPoint() = 0;
-	virtual IXLightSpot *createSpot() = 0;
+	virtual UINT XMETHODCALLTYPE getCount() = 0;
+	virtual IXLight* XMETHODCALLTYPE getLight(ID id) = 0;
 
-	virtual UINT getCount() = 0;
-	virtual IXLight *getLight(ID id) = 0;
+	virtual void XMETHODCALLTYPE updateVisibility() = 0;
 
-	virtual void updateVisibility(ICamera *pMainCamera, const float3 &vLPVmin, const float3 &vLPVmax) = 0;
+	virtual void XMETHODCALLTYPE setFrameObserverCamera(ICamera *pMainCamera) = 0;
+	
+	virtual void XMETHODCALLTYPE setRenderPipeline(IXRenderPipeline *pRenderPipeline) = 0;
+	virtual void XMETHODCALLTYPE setGBuffer(IGXTexture2D *pColor, IGXTexture2D *pNormals, IGXTexture2D *pParams, IGXTexture2D *pDepth) = 0;
+	virtual void XMETHODCALLTYPE renderGI(IGXTexture2D *pLightTotal, IGXTexture2D *pTempBuffer) = 0;
+	virtual void XMETHODCALLTYPE renderToneMapping(IGXTexture2D *pSourceLight) = 0;
+	virtual void XMETHODCALLTYPE renderDebug() = 0;
 };
 
 #endif
diff --git a/source/light/LightSystem.cpp b/source/light/LightSystem.cpp
index 58ffe9dc8593951192a0607ae587f9719ea9480c..4d568100ff014a25913554988c2f1eee29bc7f56 100644
--- a/source/light/LightSystem.cpp
+++ b/source/light/LightSystem.cpp
@@ -29,12 +29,197 @@ private:
 
 //##########################################################################
 
-CLightSystem::CLightSystem(IXCore *pCore)
+CLightSystem::CLightSystem(IXCore *pCore):
+	m_pCore(pCore)
 {
 	m_pLevelListener = new CLevelLoadListener(this, pCore);
 
 	m_pLevelChannel = pCore->getEventChannel<XEventLevel>(EVENT_LEVEL_GUID);
 	m_pLevelChannel->addListener(m_pLevelListener);
+
+	m_pDevice = SGCore_GetDXDevice();
+
+	m_pMaterialSystem = (IXMaterialSystem*)pCore->getPluginManager()->getInterface(IXMATERIALSYSTEM_GUID);
+
+	if(m_pDevice)
+	{
+		{
+			const UINT uSize = 32;
+			m_uGICubesCount = uSize * uSize * uSize;
+			float3_t *pData = new float3_t[m_uGICubesCount];
+			float fHalf = (float)uSize / 2.0f;
+			for(UINT x = 0; x < uSize; ++x)
+			{
+				for(UINT y = 0; y < uSize; ++y)
+				{
+					for(UINT z = 0; z < uSize; ++z)
+					{
+						pData[x + y * uSize + z * uSize * uSize] = (float3)(float3((float)x, (float)y, (float)z) - float3(fHalf));
+					}
+				}
+			}
+			IGXVertexBuffer *pVB = m_pDevice->createVertexBuffer(sizeof(float3_t) * m_uGICubesCount, GXBUFFER_USAGE_STATIC, pData);
+			mem_delete_a(pData);
+
+			GXVertexElement oLayout[] =
+			{
+				{0, 0, GXDECLTYPE_FLOAT3, GXDECLUSAGE_POSITION},
+				GX_DECL_END()
+			};
+
+			IGXVertexDeclaration *pVD = m_pDevice->createVertexDeclaration(oLayout);
+			m_pGICubesRB = m_pDevice->createRenderBuffer(1, &pVB, pVD);
+			mem_release(pVD);
+			mem_release(pVB);
+
+			ID idVS = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "gi_cubes.vs");
+			ID idPS = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "gi_cubes.ps");
+			ID idGS = SGCore_ShaderLoad(SHADER_TYPE_GEOMETRY, "gi_cubes.gs");
+			m_idGICubesShader = SGCore_ShaderCreateKit(idVS, idPS, idGS);
+		}
+
+
+		m_pLightLuminance = m_pDevice->createTexture2D(LUMINANCE_BUFFER_SIZE, LUMINANCE_BUFFER_SIZE, 1, GX_TEXFLAG_RENDERTARGET, GXFMT_R16F);
+
+		m_pLightLuminance32 = m_pDevice->createTexture2D(32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
+		m_pLightLuminance1 = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
+		m_pAdaptedLuminance[0] = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
+		m_pAdaptedLuminance[1] = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
+		
+		
+		m_pLPVcentersShaderData = m_pDevice->createConstantBuffer(sizeof(m_lpvCentersShaderData.vs));
+		m_pLPVcurrentCascadeShaderData = m_pDevice->createConstantBuffer(sizeof(float4_t));
+		
+		m_pToneMappingShaderData = m_pDevice->createConstantBuffer(sizeof(m_toneMappingShaderData));
+
+		for(UINT i = 0; i < 3; ++i)
+		{
+			m_aLPVs[i].pGIAccumRed = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
+			m_aLPVs[i].pGIAccumGreen = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
+			m_aLPVs[i].pGIAccumBlue = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
+
+			m_aLPVs[i].pGIAccumRed2 = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
+			m_aLPVs[i].pGIAccumGreen2 = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
+			m_aLPVs[i].pGIAccumBlue2 = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
+		}
+
+		m_idLightBoundShader = SGCore_ShaderCreateKit(SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "lighting_bound.vs"), -1);
+
+		m_idLPVPropagateShader = SGCore_ShaderCreateKit(-1, -1, -1, SGCore_ShaderLoad(SHADER_TYPE_COMPUTE, "gi_propagation.cs"));
+
+		m_idLuminanceReductionShader = SGCore_ShaderCreateKit(-1, -1, -1, SGCore_ShaderLoad(SHADER_TYPE_COMPUTE, "hdr_reduction.cs"));
+
+		
+		GXSamplerDesc samplerDesc;
+
+		samplerDesc.addressU = samplerDesc.addressV = samplerDesc.addressW = GXTEXTURE_ADDRESS_CLAMP;
+		m_pSamplerPointClamp = m_pDevice->createSamplerState(&samplerDesc);
+
+		samplerDesc.addressU = samplerDesc.addressV = samplerDesc.addressW = GXTEXTURE_ADDRESS_WRAP;
+		samplerDesc.filter = GXFILTER_MIN_MAG_MIP_LINEAR;
+		m_pSamplerLinearWrap = m_pDevice->createSamplerState(&samplerDesc);
+
+		samplerDesc.addressU = samplerDesc.addressV = samplerDesc.addressW = GXTEXTURE_ADDRESS_CLAMP;
+		m_pSamplerLinearClamp = m_pDevice->createSamplerState(&samplerDesc);
+
+		samplerDesc.addressU = samplerDesc.addressV = samplerDesc.addressW = GXTEXTURE_ADDRESS_BORDER;
+		samplerDesc.filter = GXFILTER_MIN_MAG_MIP_LINEAR;
+		samplerDesc.f4BorderColor = float4_t(0.0f, 0.0f, 0.0f, 0.0f);
+		m_pSamplerLinearBorder = m_pDevice->createSamplerState(&samplerDesc);
+
+		m_pShadowShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_shadowShaderData.vs));
+
+
+		GXRasterizerDesc rasterizerDesc;
+
+		//rasterizerDesc.useConservativeRasterization = true;
+		m_pRasterizerConservative = m_pDevice->createRasterizerState(&rasterizerDesc);
+
+		//rasterizerDesc.useConservativeRasterization = false;
+		rasterizerDesc.cullMode = GXCULL_NONE;
+		m_pRasterizerCullNone = m_pDevice->createRasterizerState(&rasterizerDesc);
+
+
+
+		GXBlendDesc blendDesc;
+
+		blendDesc.renderTarget[0].u8RenderTargetWriteMask = GXCOLOR_WRITE_ENABLE_RED;
+		m_pBlendRed = m_pDevice->createBlendState(&blendDesc);
+
+		blendDesc.renderTarget[0].u8RenderTargetWriteMask = GXCOLOR_WRITE_ENABLE_ALL;
+		blendDesc.renderTarget[0].useBlend = TRUE;
+		blendDesc.renderTarget[0].blendSrcColor = blendDesc.renderTarget[0].blendSrcAlpha = GXBLEND_ONE;
+		blendDesc.renderTarget[0].blendDestColor = blendDesc.renderTarget[0].blendDestAlpha = GXBLEND_ONE;
+		m_pBlendAlphaOneOne = m_pDevice->createBlendState(&blendDesc);
+
+
+
+
+		GXDepthStencilDesc dsDesc;
+		dsDesc.cmpFuncDepth = GXCMP_GREATER_EQUAL;
+		m_pDepthStencilStateDefault = m_pDevice->createDepthStencilState(&dsDesc);
+
+		dsDesc.useDepthTest = FALSE;
+		dsDesc.useDepthWrite = FALSE;
+		m_pDepthStencilStateNoZ = m_pDevice->createDepthStencilState(&dsDesc);
+
+		dsDesc.useStencilTest = TRUE;
+		dsDesc.useDepthTest = TRUE;
+		dsDesc.stencilTestFront.cmpFunc = GXCMP_ALWAYS;
+		dsDesc.stencilTestFront.opDepthFail = GXSTENCIL_OP_INCR;
+		dsDesc.stencilTestFront.opPass = GXSTENCIL_OP_KEEP;
+		dsDesc.stencilTestBack.opDepthFail = GXSTENCIL_OP_DECR;
+		m_pDepthStencilStateLightBound = m_pDevice->createDepthStencilState(&dsDesc);
+
+		dsDesc.useDepthTest = FALSE;
+		dsDesc.stencilTestFront.cmpFunc = GXCMP_EQUAL;
+		dsDesc.stencilTestFront.opDepthFail = GXSTENCIL_OP_ZERO;
+		dsDesc.stencilTestFront.opFail = GXSTENCIL_OP_ZERO;
+		dsDesc.stencilTestFront.opPass = GXSTENCIL_OP_KEEP;
+		m_pDepthStencilStateLightShadowNonGlobal = m_pDevice->createDepthStencilState(&dsDesc);
+
+		dsDesc.stencilTestFront.opPass = GXSTENCIL_OP_ZERO;
+		m_pDepthStencilStateLightClear = m_pDevice->createDepthStencilState(&dsDesc);
+
+		dsDesc.useStencilTest = FALSE;
+		m_pDepthStencilStateLightShadowGlobal = m_pDevice->createDepthStencilState(&dsDesc);
+
+
+
+		ID idScreenOut = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "pp_quad_render.vs");
+		ID idResPos = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "pp_res_pos.vs", "pp_quad_render_res_pos.vs");
+
+		GXMacro Defines_IS_SHADOWED[] = {{"IS_SHADOWED", ""}, {0, 0}};
+		GXMacro Defines_IS_SPOT_SHADOWED[] = {{"IS_SHADOWED", ""}, {"IS_SPOT", ""}, {0, 0}};
+		GXMacro Defines_IS_PSSM_SHADOWED[] = {{"IS_SHADOWED", ""}, {"IS_PSSM", ""}, {0, 0}};
+
+		m_idBlendAmbientSpecDiffColor = SGCore_ShaderCreateKit(idResPos, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_blend.ps"));
+		m_idComLightingShadow = SGCore_ShaderCreateKit(idResPos, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_com.ps", "lighting_com_shadow.ps", Defines_IS_SHADOWED));
+		m_idComLightingSpotShadow = SGCore_ShaderCreateKit(idResPos, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_com.ps", "lighting_com_spot_shadow.ps", Defines_IS_SPOT_SHADOWED));
+		m_idComLightingPSSMShadow = SGCore_ShaderCreateKit(idResPos, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_com.ps", "lighting_com_pssm_shadow.ps", Defines_IS_PSSM_SHADOWED));
+
+		m_idComLightingGI = SGCore_ShaderCreateKit(idResPos, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_gi.ps"));
+
+		m_idHDRinitLuminance = SGCore_ShaderCreateKit(idScreenOut, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "hdr_luminance.ps"));
+		m_idHDRAdaptLuminance = SGCore_ShaderCreateKit(idScreenOut, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "hdr_adapt.ps"));
+		m_idHDRToneMapping = SGCore_ShaderCreateKit(idScreenOut, SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "hdr_tonemapping.ps"));
+	}
+	else
+	{
+		m_pAdaptedLuminance[0] = NULL;
+		m_pAdaptedLuminance[1] = NULL;
+
+		for(UINT i = 0; i < 3; ++i)
+		{
+			m_aLPVs[i].pGIAccumRed = NULL;
+			m_aLPVs[i].pGIAccumGreen = NULL;
+			m_aLPVs[i].pGIAccumBlue = NULL;
+
+			m_aLPVs[i].pGIAccumRed2 = NULL;
+			m_aLPVs[i].pGIAccumGreen2 = NULL;
+			m_aLPVs[i].pGIAccumBlue2 = NULL;
+		}
+	}
 }
 
 CLightSystem::~CLightSystem()
@@ -44,6 +229,59 @@ CLightSystem::~CLightSystem()
 	mem_delete(m_pSun);
 	mem_release(m_pShapeSphere);
 	mem_release(m_pShapeCone);
+	mem_release(m_pRenderPipeline);
+
+	mem_release(m_pGICubesRB);
+
+	mem_release(m_pLightLuminance);
+	mem_release(m_pLightLuminance32);
+	mem_release(m_pLightLuminance1);
+	mem_release(m_pAdaptedLuminance[0]);
+	mem_release(m_pAdaptedLuminance[1]);
+
+	mem_release(m_pLPVcentersShaderData);
+	mem_release(m_pLPVcurrentCascadeShaderData);
+	mem_release(m_pToneMappingShaderData);
+
+
+	for(UINT i = 0; i < 3; ++i)
+	{
+		mem_release(m_aLPVs[i].pGIAccumRed);
+		mem_release(m_aLPVs[i].pGIAccumGreen);
+		mem_release(m_aLPVs[i].pGIAccumBlue);
+
+		mem_release(m_aLPVs[i].pGIAccumRed2);
+		mem_release(m_aLPVs[i].pGIAccumGreen2);
+		mem_release(m_aLPVs[i].pGIAccumBlue2);
+	}
+
+	mem_release(m_pDepthStencilStateDefault);
+
+	mem_release(m_pSamplerPointClamp);
+	mem_release(m_pSamplerLinearWrap);
+	mem_release(m_pSamplerLinearClamp);
+	mem_release(m_pSamplerLinearBorder);
+
+	mem_release(m_pShadowShaderDataVS);
+
+	mem_delete(m_pShadowCache);
+
+	mem_release(m_pRasterizerConservative);
+	mem_release(m_pRasterizerCullNone);
+
+	mem_release(m_pBlendRed);
+	mem_release(m_pBlendAlphaOneOne);
+
+	mem_release(m_pDepthStencilStateNoZ);
+	mem_release(m_pDepthStencilStateLightBound);
+	mem_release(m_pDepthStencilStateLightClear);
+	mem_release(m_pDepthStencilStateLightShadowNonGlobal);
+	mem_release(m_pDepthStencilStateLightShadowGlobal);
+
+	mem_release(m_pGBufferColor);
+	mem_release(m_pGBufferNormals);
+	mem_release(m_pGBufferParams);
+	mem_release(m_pGBufferDepth);
 }
 
 void CLightSystem::setLevelSize(const float3 &vMin, const float3 &vMax)
@@ -61,7 +299,7 @@ void CLightSystem::setLevelSize(const float3 &vMin, const float3 &vMax)
 	}
 }
 
-IXLightSun *CLightSystem::createSun()
+IXLightSun* XMETHODCALLTYPE CLightSystem::newSun()
 {
 	if(m_pSun)
 	{
@@ -76,7 +314,7 @@ IXLightSun *CLightSystem::createSun()
 	return(m_pSun);
 }
 
-IXLightSun *CLightSystem::getSun()
+IXLightSun* XMETHODCALLTYPE CLightSystem::getSun()
 {
 	if(m_pSun)
 	{
@@ -85,24 +323,24 @@ IXLightSun *CLightSystem::getSun()
 	return(m_pSun);
 }
 
-IXLightPoint *CLightSystem::createPoint()
+IXLightPoint* XMETHODCALLTYPE CLightSystem::newPoint()
 {
 	CXLightPoint *pLight = m_poolPoint.Alloc(this);
 	m_aLights.push_back(pLight);
 	return(pLight);
 }
-IXLightSpot *CLightSystem::createSpot()
+IXLightSpot* XMETHODCALLTYPE CLightSystem::newSpot()
 {
 	CXLightSpot *pLight = m_poolSpot.Alloc(this);
 	m_aLights.push_back(pLight);
 	return(pLight);
 }
 
-UINT CLightSystem::getCount()
+UINT XMETHODCALLTYPE CLightSystem::getCount()
 {
 	return(m_aLights.size());
 }
-IXLight *CLightSystem::getLight(ID id)
+IXLight* XMETHODCALLTYPE CLightSystem::getLight(ID id)
 {
 	assert(ID_VALID(id) && id < (ID)m_aLights.size());
 
@@ -140,7 +378,7 @@ void CLightSystem::_deleteLight(CXLight *pLight)
 	}
 }
 
-IMesh *CLightSystem::getShapeSphere()
+IMesh* CLightSystem::getShapeSphere()
 {
 	if(!m_pShapeSphere)
 	{
@@ -150,7 +388,7 @@ IMesh *CLightSystem::getShapeSphere()
 	return(m_pShapeSphere);
 }
 
-IMesh *CLightSystem::getShapeCone()
+IMesh* CLightSystem::getShapeCone()
 {
 	if(!m_pShapeCone)
 	{
@@ -160,13 +398,655 @@ IMesh *CLightSystem::getShapeCone()
 	return(m_pShapeCone);
 }
 
-void CLightSystem::updateVisibility(ICamera *pMainCamera, const float3 &vLPVmin, const float3 &vLPVmax)
+void XMETHODCALLTYPE CLightSystem::updateVisibility()
 {
+	assert(m_pMainCamera);
+
+	float3 vCamPos;
+	m_pMainCamera->getPosition(&vCamPos);
+
+	//! @todo fix this values!
+	float3 vLPVmin = float3(-16.0f, -16.0f, -16.0f) + vCamPos;
+	float3 vLPVmax = float3(16.0f, 16.0f, 16.0f) + vCamPos;
+
 	for(UINT i = 0, l = m_aLights.size(); i < l; ++i)
 	{
 		if(m_aLights[i]->isEnabled())
 		{
-			m_aLights[i]->updateVisibility(pMainCamera, vLPVmin, vLPVmax);
+			m_aLights[i]->updateVisibility(m_pMainCamera, vLPVmin, vLPVmax);
 		}
 	}
 }
+
+void XMETHODCALLTYPE CLightSystem::setFrameObserverCamera(ICamera *pMainCamera)
+{
+	//! @todo uncomment me!
+	// pMainCamera->AddRef();
+	m_pMainCamera = pMainCamera;
+}
+
+void XMETHODCALLTYPE CLightSystem::setGBuffer(IGXTexture2D *pColor, IGXTexture2D *pNormals, IGXTexture2D *pParams, IGXTexture2D *pDepth)
+{
+	pColor->AddRef();
+	pNormals->AddRef();
+	pParams->AddRef();
+	pDepth->AddRef();
+	m_pGBufferColor = pColor;
+	m_pGBufferNormals = pNormals;
+	m_pGBufferParams = pParams;
+	m_pGBufferDepth = pDepth;
+}
+
+void XMETHODCALLTYPE CLightSystem::setRenderPipeline(IXRenderPipeline *pRenderPipeline)
+{
+	mem_release(m_pRenderPipeline);
+	m_pRenderPipeline = pRenderPipeline;
+	m_pRenderPipeline->AddRef();
+	if(!m_pShadowCache)
+	{
+		m_pShadowCache = new CShadowCache(m_pRenderPipeline, m_pMaterialSystem);
+	}
+}
+
+void XMETHODCALLTYPE CLightSystem::renderGI(IGXTexture2D *pLightTotal, IGXTexture2D *pTempBuffer)
+{
+	IGXContext *pCtx = m_pDevice->getThreadContext();
+
+	IGXDepthStencilSurface *pOldDSSurface = pCtx->getDepthStencilSurface();
+
+	UINT uCounts[LIGHT_TYPE__COUNT] = {0};
+	for(int i = 0, l = getCount(); i < l; ++i)
+	{
+		++uCounts[getLight(i)->getType()];
+	}
+	m_pShadowCache->setLightsCount(uCounts[LIGHT_TYPE_POINT], uCounts[LIGHT_TYPE_SPOT], uCounts[LIGHT_TYPE_SUN] != 0);
+	m_pShadowCache->setRSMLightsCount(uCounts[LIGHT_TYPE_POINT], uCounts[LIGHT_TYPE_SPOT], uCounts[LIGHT_TYPE_SUN] != 0);
+
+	m_pShadowCache->setObserverCamera(m_pMainCamera);
+
+	m_pShadowCache->nextFrame();
+
+	IGXSurface *pAmbientSurf, *pBackBuf;
+	pAmbientSurf = pTempBuffer->getMipmap();
+
+	pBackBuf = pCtx->getColorTarget();
+
+	pCtx->setColorTarget(pAmbientSurf);
+
+	//очищаем рт и стенсил
+	pCtx->clear(GX_CLEAR_COLOR);
+	//	pCtx->clear(GX_CLEAR_COLOR | GX_CLEAR_STENCIL);
+	
+	m_pRenderPipeline->renderGI();
+
+	float3 vCamDir;
+	m_pMainCamera->getLook(&vCamDir);
+	float3 vCamPos;
+	m_pMainCamera->getPosition(&vCamPos);
+
+
+	const float c_aLPVsizes[] = {
+		//0.5f,
+		//1.0f,
+		//2.0f
+
+		1.0f,
+		2.0f,
+		4.0f
+	};
+
+	m_lpvCentersShaderData.vs.vCenterSize[0] = float4(vCamPos + vCamDir * (LPV_GRID_SIZE / 2 - LPV_STEP_COUNT) * c_aLPVsizes[0], c_aLPVsizes[0]);
+	m_lpvCentersShaderData.vs.vCenterSize[1] = float4(vCamPos + vCamDir * (LPV_GRID_SIZE / 2 - LPV_STEP_COUNT) * c_aLPVsizes[1], c_aLPVsizes[1]);
+	m_lpvCentersShaderData.vs.vCenterSize[2] = float4(vCamPos + vCamDir * (LPV_GRID_SIZE / 2 - LPV_STEP_COUNT) * c_aLPVsizes[2], c_aLPVsizes[2]);
+	m_pLPVcentersShaderData->update(&m_lpvCentersShaderData.vs);
+
+	/*
+	vs:
+	cbuffer0: (per light)
+	- g_mW
+	cbuffer1: (per frame)
+	- g_mVP
+	- g_mViewInv
+	- g_vNearFar
+	- g_vParamProj
+
+	ps:
+	cbuffer0: (per light)
+	- g_vLightPos
+	- g_vLightColor
+	- g_vLightPowerDistShadow
+	cbuffer1: (per frame)
+	- g_vViewPos
+
+
+	{
+	render shadowmaps
+	render direct light with shadows
+	inject VPLs into LPV grid
+	}
+	*/
+
+	// Определим список лампочек, которые будут участвовать в текущем кадре
+	IXLight *pLight;
+	for(int i = 0, l = getCount(); i < l; ++i)
+	{
+		pLight = getLight(i);
+
+		//если свет виден фрустуму камеры (это надо было заранее просчитать) и если свет включен
+		if(pLight->isEnabled() && pLight->getRenderType() != LRT_NONE)
+		{
+			if(pLight->getRenderType() & LRT_LPV)
+			{
+				m_pShadowCache->addRSMLight(pLight);
+			}
+			if(pLight->getRenderType() & LRT_LIGHT)
+			{
+				m_pShadowCache->addLight(pLight);
+			}
+		}
+	}
+
+	static const float *r_default_fov = GET_PCVAR_FLOAT("r_default_fov");
+	static const float *r_near = GET_PCVAR_FLOAT("r_near");
+	static const float *r_far = GET_PCVAR_FLOAT("r_far");
+
+	// 	float4x4 &mCamView = gdata::mCamView;
+	// 	// Core_RMatrixGet(G_RI_MATRIX_OBSERVER_VIEW, &mCamView);
+	// 	m_shadowShaderData.vs.mViewInv = SMMatrixTranspose(SMMatrixInverse(NULL, mCamView));
+	// 	m_shadowShaderData.vs.vNearFar = gdata::vNearFar; // float2(*r_near, *r_far);
+	// 	m_shadowShaderData.vs.vParamProj = float3((float)m_uOutWidth, (float)m_uOutHeight, gdata::fProjFov); // *r_default_fov);
+	// 	m_pShadowShaderDataVS->update(&m_shadowShaderData.vs);
+
+	//@TODO: убрать это
+	//Core_RFloat3Get(G_RI_FLOAT3_OBSERVER_POSITION, &m_shadowShaderData.ps.vPosCam);
+	//m_pShadowShaderDataPS->update(&m_shadowShaderData.ps);
+
+
+	//m_pDevice->setPixelShaderConstant(m_pShadowShaderDataPS, 7);
+
+	pCtx->setRasterizerState(m_pRasterizerConservative);
+
+	//pCtx->setVSConstant(m_pCameraShaderDataVS, 8);
+	//pCtx->setPSConstant(m_pCameraShaderDataVS, 8);
+
+	UINT uShadowCount = 0;
+	while((uShadowCount = m_pShadowCache->processNextBunch()))
+	{
+		pCtx->setColorTarget(pAmbientSurf);
+		pCtx->setDepthStencilSurface(pOldDSSurface);
+		pCtx->setBlendState(m_pBlendAlphaOneOne);
+
+	//	pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
+	//	pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
+
+		IBaseShadowMap *pShadow = NULL;
+
+		//render direct light with shadows
+		for(UINT i = 0; i < uShadowCount; ++i)
+		{
+			pLight = m_pShadowCache->getLight(i);
+			pShadow = m_pShadowCache->getShadow(i);
+
+			//если не глобальный источник
+			if(pLight->getType() != LIGHT_TYPE_SUN)
+			{
+				//помечаем в стенсил буфере пиксели  которые входят в ограничивающий объем света, чтобы их осветить
+				pCtx->setRasterizerState(m_pRasterizerCullNone);
+				pCtx->setStencilRef(0);
+				pCtx->setDepthStencilState(m_pDepthStencilStateLightBound);
+
+				//отрисовка ограничивающего объема
+				SGCore_ShaderBind(m_idLightBoundShader);
+				pLight->drawShape(m_pDevice);
+
+				pCtx->setStencilRef(255);
+				pCtx->setDepthStencilState(m_pDepthStencilStateLightShadowNonGlobal);
+			}
+			else
+			{
+				//иначе это глобальный источник, отключаем стенсил тест
+				pCtx->setDepthStencilState(m_pDepthStencilStateLightShadowGlobal);
+			}
+
+			pCtx->setRasterizerState(NULL);
+
+
+
+			//pCtx->setVSConstant(m_pShadowShaderDataVS, 1);
+		//	pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
+
+			pCtx->setBlendState(m_pBlendRed);
+			pShadow->genShadow(m_pGBufferDepth, m_pGBufferNormals);
+			pCtx->setBlendState(m_pBlendAlphaOneOne);
+			pCtx->setColorTarget(pAmbientSurf);
+
+			//	pCtx->setPSTexture(m_pShadow, 4);
+			//idshaderkit = gdata::shaders_id::kit::idComLightingShadow;
+			ID idshaderkit = -1;
+			switch(pLight->getType())
+			{
+			case LIGHT_TYPE_SPOT:
+				idshaderkit = m_idComLightingSpotShadow;
+				break;
+			case LIGHT_TYPE_POINT:
+				idshaderkit = m_idComLightingShadow;
+				break;
+			case LIGHT_TYPE_SUN:
+				idshaderkit = m_idComLightingPSSMShadow;
+				break;
+			default:
+				assert(!"Unknown light type!");
+			}
+
+		//	pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
+
+			//теперь когда будем считать освещение надо сбросить значения в стенсил буфере, чтобы каждый кадр не чистить
+			//если стенсил тест прошел успешно, устанавливаем значнеие в нуль
+			if(pLight->getType() != LIGHT_TYPE_SUN)
+			{
+				pCtx->setDepthStencilState(m_pDepthStencilStateLightClear);
+			}
+
+			IGXConstantBuffer *pLightConstants = pLight->getConstants(m_pDevice);
+			pCtx->setPSConstant(pLightConstants);
+			mem_release(pLightConstants);
+
+			SGCore_ShaderBind(idshaderkit);
+
+			pCtx->setSamplerState(m_pSamplerPointClamp, 0);
+
+			pCtx->setPSTexture(m_pGBufferColor);
+			pCtx->setPSTexture(m_pGBufferNormals, 1);
+			pCtx->setPSTexture(m_pGBufferParams, 2);
+			pCtx->setPSTexture(m_pGBufferDepth, 3);
+			//m_pDevice->setTexture(SGCore_GbufferGetRT(DS_RT_ADAPTEDLUM), 5);
+
+			SGCore_ScreenQuadDraw();
+		}
+
+
+		//pCtx->setSamplerState(gdata::rstates::pSamplerLinearWrap, 0);
+		//pCtx->setSamplerState(gdata::rstates::pSamplerLinearWrap, 1);
+	}
+
+	pCtx->setVSConstant(m_pLPVcentersShaderData, 9);
+	pCtx->setPSConstant(m_pLPVcentersShaderData, 9);
+
+	bool isFirstRun[3] = {true, true, true};
+	while((uShadowCount = m_pShadowCache->processNextRSMBunch()))
+	{
+		pCtx->setVSConstant(m_pLPVcurrentCascadeShaderData, 10);
+		pCtx->setPSConstant(m_pLPVcurrentCascadeShaderData, 10);
+
+		pCtx->setDepthStencilSurface(pOldDSSurface);
+		pCtx->setBlendState(m_pBlendAlphaOneOne);
+
+	//	pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
+	//	pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
+
+		IGXDepthStencilSurface *pOldSurface = pCtx->getDepthStencilSurface();
+		pCtx->unsetDepthStencilSurface();
+
+		IBaseReflectiveShadowMap *pShadow = NULL;
+
+		for(UINT i = 0; i < 3; ++i)
+		{
+			float4_t vTmp((float)i + 0.5f); // just to be sure
+			m_pLPVcurrentCascadeShaderData->update(&vTmp);
+
+			IGXSurface *pLPVRed = m_aLPVs[i].pGIAccumRed->asRenderTarget();
+			IGXSurface *pLPVGreen = m_aLPVs[i].pGIAccumGreen->asRenderTarget();
+			IGXSurface *pLPVBlue = m_aLPVs[i].pGIAccumBlue->asRenderTarget();
+
+			//m_pDevice->setColorTarget(pAmbientSurf);
+			pCtx->setColorTarget(pLPVRed);
+			pCtx->setColorTarget(pLPVGreen, 1);
+			pCtx->setColorTarget(pLPVBlue, 2);
+
+			mem_release(pLPVRed);
+			mem_release(pLPVGreen);
+			mem_release(pLPVBlue);
+
+			if(isFirstRun[i])
+			{
+				pCtx->clear(GX_CLEAR_COLOR);
+				isFirstRun[i] = false;
+			}
+
+			//inject VPLs into LPV grid
+			for(UINT j = 0; j < uShadowCount; ++j)
+			{
+				pShadow = m_pShadowCache->getRSMShadow(j);
+				pShadow->genLPV();
+			}
+
+			pCtx->setColorTarget(NULL);
+			pCtx->setColorTarget(NULL, 1);
+			pCtx->setColorTarget(NULL, 2);
+		}
+
+		const bool *dev_lpv_points = GET_PCVAR_BOOL("dev_lpv_points");
+		if(*dev_lpv_points)
+		{
+			auto pTarget = m_pGBufferColor->asRenderTarget();
+			pCtx->setColorTarget(pAmbientSurf);
+			mem_release(pTarget);
+			for(UINT i = 0; i < uShadowCount; ++i)
+			{
+				pShadow = m_pShadowCache->getRSMShadow(i);
+				pShadow->genLPV(true);
+			}
+			pCtx->setColorTarget(NULL);
+		}
+
+		pCtx->setDepthStencilSurface(pOldSurface);
+		mem_release(pOldSurface);
+
+		//break;
+	}
+	for(UINT i = 0; i < 3; ++i)
+	{
+		if(isFirstRun[i])
+		{
+			IGXSurface *pLPVRed = m_aLPVs[i].pGIAccumRed->asRenderTarget();
+			IGXSurface *pLPVGreen = m_aLPVs[i].pGIAccumGreen->asRenderTarget();
+			IGXSurface *pLPVBlue = m_aLPVs[i].pGIAccumBlue->asRenderTarget();
+
+			pCtx->setColorTarget(pLPVRed);
+			pCtx->setColorTarget(pLPVGreen, 1);
+			pCtx->setColorTarget(pLPVBlue, 2);
+
+			mem_release(pLPVRed);
+			mem_release(pLPVGreen);
+			mem_release(pLPVBlue);
+
+			pCtx->clear(GX_CLEAR_COLOR);
+			isFirstRun[i] = false;
+
+			pCtx->setColorTarget(NULL);
+			pCtx->setColorTarget(NULL, 1);
+			pCtx->setColorTarget(NULL, 2);
+		}
+	}
+
+	SGCore_ShaderUnBind();
+
+	mem_release(pOldDSSurface);
+
+	//pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
+	//pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
+
+	{
+		SGCore_ShaderBind(m_idLPVPropagateShader);
+		UINT uStepCount[] = {4, 6, 8};
+
+		//for(UINT k = 0; k < 1000; ++k)
+		//{
+		for(UINT j = 0; j < 3; ++j)
+		{
+			for(UINT i = 0; i < uStepCount[j]; ++i)
+			{
+				pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed, 0);
+				pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen, 1);
+				pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue, 2);
+
+				pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed2, 0);
+				pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen2, 1);
+				pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue2, 2);
+
+				pCtx->computeDispatch(4, 4, 32);
+
+				pCtx->setCSUnorderedAccessView(NULL, 0);
+				pCtx->setCSUnorderedAccessView(NULL, 1);
+				pCtx->setCSUnorderedAccessView(NULL, 2);
+
+				pCtx->setCSTexture(NULL, 0);
+				pCtx->setCSTexture(NULL, 1);
+				pCtx->setCSTexture(NULL, 2);
+
+
+				pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed2, 0);
+				pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen2, 1);
+				pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue2, 2);
+
+				pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed, 0);
+				pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen, 1);
+				pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue, 2);
+
+				pCtx->computeDispatch(4, 4, 32);
+
+				pCtx->setCSUnorderedAccessView(NULL, 0);
+				pCtx->setCSUnorderedAccessView(NULL, 1);
+				pCtx->setCSUnorderedAccessView(NULL, 2);
+
+				pCtx->setCSTexture(NULL, 0);
+				pCtx->setCSTexture(NULL, 1);
+				pCtx->setCSTexture(NULL, 2);
+			}
+		}
+		//}
+
+		SGCore_ShaderUnBind();
+	}
+
+
+	{
+		pCtx->setColorTarget(pAmbientSurf);
+		//gdata::pDXDevice->setRasterizerState(NULL);
+		pCtx->setRasterizerState(m_pRasterizerCullNone);
+		pCtx->setBlendState(m_pBlendAlphaOneOne);
+		pCtx->setDepthStencilState(m_pDepthStencilStateLightShadowGlobal);
+
+		//pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
+
+		ID idshaderkit = m_idComLightingGI;
+
+		//SGCore_ShaderSetVRF(SHADER_TYPE_PIXEL, idshader, "g_vViewPos", &gdata::vConstCurrCamPos);
+
+		//	pCtx->setPSConstant(m_pCameraShaderDataVS, 8);
+
+		SGCore_ShaderBind(idshaderkit);
+
+		pCtx->setSamplerState(m_pSamplerPointClamp, 0);
+		pCtx->setSamplerState(m_pSamplerLinearBorder, 1);
+
+		pCtx->setPSTexture(m_pGBufferDepth);
+		pCtx->setPSTexture(m_pGBufferNormals, 1);
+		pCtx->setPSTexture(m_pGBufferColor, 2);
+		pCtx->setPSTexture(m_pGBufferParams, 3);
+		for(UINT i = 0; i < 3; ++i)
+		{
+			pCtx->setPSTexture(m_aLPVs[i].pGIAccumRed, 4 + i);
+			pCtx->setPSTexture(m_aLPVs[i].pGIAccumGreen, 7 + i);
+			pCtx->setPSTexture(m_aLPVs[i].pGIAccumBlue, 10 + i);
+		}
+
+		SGCore_ScreenQuadDraw();
+
+		pCtx->setPSTexture(NULL, 2);
+		pCtx->setPSTexture(NULL, 3);
+		pCtx->setPSTexture(NULL, 4);
+
+		SGCore_ShaderUnBind();
+		pCtx->setSamplerState(m_pSamplerLinearClamp, 1);
+	}
+
+
+
+	pCtx->setDepthStencilState(m_pDepthStencilStateNoZ);
+	pCtx->setRasterizerState(NULL);
+	pCtx->setBlendState(NULL);
+
+	//pCtx->setColorTarget(NULL, 1);
+
+	mem_release(pAmbientSurf);
+
+	//-------------------------------
+
+	//теперь необходимо все смешать чтобы получить итоговую освещенную картинку
+	//{{
+
+	pCtx->setSamplerState(m_pSamplerPointClamp, 0);
+	pCtx->setSamplerState(m_pSamplerLinearClamp, 1);
+
+	IGXSurface *pComLightSurf = pLightTotal->getMipmap();
+	pCtx->setColorTarget(pComLightSurf);
+
+	//очищаем рт (в старой версии было многопроходное смешивание)
+	//	pCtx->clear(GX_CLEAR_COLOR);
+
+	pCtx->setPSTexture(m_pGBufferColor);
+	pCtx->setPSTexture(pTempBuffer, 1);
+	//pCtx->setPSTexture(m_pLightSpecular, 2);
+	pCtx->setPSTexture(m_pGBufferNormals, 3);
+	pCtx->setPSTexture(m_pGBufferDepth, 4);
+	//gdata::pDXDevice->setTexture(SGCore_GbufferGetRT(DS_RT_ADAPTEDLUM), 4);
+	pCtx->setPSTexture(m_pGBufferParams, 5);
+
+	SGCore_ShaderBind(m_idBlendAmbientSpecDiffColor);
+
+	SGCore_ScreenQuadDraw();
+
+	mem_release(pComLightSurf);
+	//}}
+
+	SGCore_ShaderUnBind();
+
+	pCtx->setColorTarget(pBackBuf);
+	mem_release(pBackBuf);
+
+	//Sleep(16);
+}
+void XMETHODCALLTYPE CLightSystem::renderToneMapping(IGXTexture2D *pSourceLight)
+{
+	Core_PStartSection(PERF_SECTION_TONEMAPPING);
+	static const float *hdr_adapted_coef = GET_PCVAR_FLOAT("hdr_adapted_coef");
+	static const float *hdr_base_value = GET_PCVAR_FLOAT("hdr_base_value");
+
+	//! @todo update only on change
+	m_toneMappingShaderData.fAdaptationSpeed = *hdr_adapted_coef;
+	m_toneMappingShaderData.fBaseValue = *hdr_base_value;
+	m_pToneMappingShaderData->update(&m_toneMappingShaderData);
+
+	//	SGCore_ToneMappingCom(timeDelta, (hdr_adapted_coef ? (*hdr_adapted_coef) : 0.03f));
+	IGXContext *pCtx = m_pDevice->getThreadContext();
+
+	pCtx->setPSConstant(m_pToneMappingShaderData, 8);
+
+	IGXSurface *pBackBuf = pCtx->getColorTarget();
+
+	IGXSurface *pRT = m_pLightLuminance->asRenderTarget();
+	pCtx->setColorTarget(pRT);
+	mem_release(pRT);
+
+	pCtx->setPSTexture(pSourceLight);
+	pCtx->setSamplerState(m_pSamplerLinearClamp, 0);
+
+	IGXDepthStencilSurface *pDSSurface = pCtx->getDepthStencilSurface();
+	pCtx->unsetDepthStencilSurface();
+
+	SGCore_ShaderBind(m_idHDRinitLuminance);
+	SGCore_ScreenQuadDraw();
+	SGCore_ShaderUnBind();
+
+	pCtx->setColorTarget(pBackBuf);
+
+	// Reduction
+	{
+		SGCore_ShaderBind(m_idLuminanceReductionShader);
+
+		pCtx->setCSTexture(m_pLightLuminance, 0);
+		pCtx->setCSUnorderedAccessView(m_pLightLuminance32, 0);
+		pCtx->computeDispatch(32, 32, 1);
+		pCtx->setCSUnorderedAccessView(NULL, 0);
+		pCtx->setCSTexture(NULL, 0);
+
+		pCtx->setCSTexture(m_pLightLuminance32, 0);
+		pCtx->setCSUnorderedAccessView(m_pLightLuminance1, 0);
+		pCtx->computeDispatch(1, 1, 1);
+		pCtx->setCSUnorderedAccessView(NULL, 0);
+		pCtx->setCSTexture(NULL, 0);
+
+		SGCore_ShaderUnBind();
+	}
+
+	// Adaptation
+	{
+		// m_pLightLuminance1
+		pCtx->setPSTexture(m_pAdaptedLuminance[!m_uCurrAdaptedLuminanceTarget]);
+		pCtx->setPSTexture(m_pLightLuminance1, 1);
+		IGXSurface *pAdaptedLuminanceBuf = m_pAdaptedLuminance[m_uCurrAdaptedLuminanceTarget]->asRenderTarget();
+		pCtx->setColorTarget(pAdaptedLuminanceBuf);
+		mem_release(pAdaptedLuminanceBuf);
+
+		SGCore_ShaderBind(m_idHDRAdaptLuminance);
+
+		SGCore_ScreenQuadDraw();
+
+		SGCore_ShaderUnBind();
+	}
+
+
+	pCtx->setColorTarget(pBackBuf);
+	mem_release(pBackBuf);
+
+	{
+		pCtx->setSamplerState(m_pSamplerPointClamp, 0);
+		pCtx->setPSTexture(pSourceLight);
+		pCtx->setPSTexture(m_pAdaptedLuminance[m_uCurrAdaptedLuminanceTarget], 1);
+		pCtx->setPSTexture(m_pLightLuminance1, 2);
+		SGCore_ShaderBind(m_idHDRToneMapping);
+
+		SGCore_ScreenQuadDraw();
+
+		SGCore_ShaderUnBind();
+	}
+
+	pCtx->setDepthStencilSurface(pDSSurface);
+	m_uCurrAdaptedLuminanceTarget = !m_uCurrAdaptedLuminanceTarget;
+
+	Core_PEndSection(PERF_SECTION_TONEMAPPING);
+}
+void XMETHODCALLTYPE CLightSystem::renderDebug()
+{
+	const bool *dev_lpv_cubes = GET_PCVAR_BOOL("dev_lpv_cubes");
+	if(*dev_lpv_cubes)
+	{
+		showGICubes();
+	}
+}
+
+void CLightSystem::showGICubes()
+{
+	IGXContext *pCtx = m_pDevice->getThreadContext();
+
+	pCtx->setPrimitiveTopology(GXPT_POINTLIST);
+	pCtx->setRenderBuffer(m_pGICubesRB);
+	SGCore_ShaderBind(m_idGICubesShader);
+	//pCtx->setGSConstant(m_pLightingShaderDataVS, 1);
+	pCtx->setDepthStencilState(m_pDepthStencilStateDefault);
+	pCtx->setSamplerState(m_pSamplerPointClamp, 0);
+
+	pCtx->setVSConstant(m_pLPVcurrentCascadeShaderData, 10);
+	pCtx->setGSConstant(m_pLPVcurrentCascadeShaderData, 10);
+	pCtx->setPSConstant(m_pLPVcurrentCascadeShaderData, 10);
+
+	for(UINT i = 2; i < 3; ++i)
+	{
+		float4_t vTmp((float)i + 0.5f);  // just to be sure
+		m_pLPVcurrentCascadeShaderData->update(&vTmp);
+
+		pCtx->setPSTexture(m_aLPVs[i].pGIAccumRed2, 0);
+		pCtx->setPSTexture(m_aLPVs[i].pGIAccumGreen2, 1);
+		pCtx->setPSTexture(m_aLPVs[i].pGIAccumBlue2, 2);
+
+		pCtx->drawPrimitive(0, m_uGICubesCount);
+	}
+
+
+	pCtx->setPrimitiveTopology(GXPT_TRIANGLELIST);
+
+	pCtx->setPSTexture(NULL, 0);
+	pCtx->setPSTexture(NULL, 1);
+	pCtx->setPSTexture(NULL, 2);
+}
diff --git a/source/light/LightSystem.h b/source/light/LightSystem.h
index e095ce52b3ae23bf3bb76dca571adf172189aa85..6be9039859530d3c0b31fa0d503503a4a11a6dcc 100644
--- a/source/light/LightSystem.h
+++ b/source/light/LightSystem.h
@@ -4,6 +4,12 @@
 #include "IXLightSystem.h"
 #include <common/memalloc.h>
 #include "light.h"
+#include "ShadowCache.h"
+
+#define LPV_CASCADES_COUNT 3
+#define LPV_GRID_SIZE 32
+#define LPV_STEP_COUNT 6
+#define LUMINANCE_BUFFER_SIZE 1024
 
 class CLevelLoadListener;
 class CLightSystem: public IXLightSystem
@@ -12,30 +18,50 @@ public:
 	CLightSystem(IXCore *pCore);
 	~CLightSystem();
 
-	IXLightSun *createSun() override;
-	IXLightSun *getSun() override;
+	IXLightSun* XMETHODCALLTYPE newSun() override;
+	IXLightSun* XMETHODCALLTYPE getSun() override;
 	void destroySun(IXLightSun *pLight);
 
-	IXLightPoint *createPoint() override;
+	IXLightPoint* XMETHODCALLTYPE newPoint() override;
 	void destroyPoint(IXLightPoint *pLight);
-	IXLightSpot *createSpot() override;
+	IXLightSpot* XMETHODCALLTYPE newSpot() override;
 	void destroySpot(IXLightSpot *pLight);
 
-	UINT getCount() override;
-	IXLight *getLight(ID id) override;
+	UINT XMETHODCALLTYPE getCount() override;
+	IXLight* XMETHODCALLTYPE getLight(ID id) override;
+
+	IMesh* getShapeSphere();
+	IMesh* getShapeCone();
 
-	IMesh *getShapeSphere();
-	IMesh *getShapeCone();
+	void XMETHODCALLTYPE updateVisibility() override;
 
-	void updateVisibility(ICamera *pMainCamera, const float3 &vLPVmin, const float3 &vLPVmax) override;
+	void XMETHODCALLTYPE setFrameObserverCamera(ICamera *pMainCamera) override;
 
 	void setLevelSize(const float3 &vMin, const float3 &vMax);
 
+	void XMETHODCALLTYPE setGBuffer(IGXTexture2D *pColor, IGXTexture2D *pNormals, IGXTexture2D *pParams, IGXTexture2D *pDepth) override;
+	void XMETHODCALLTYPE setRenderPipeline(IXRenderPipeline *pRenderPipeline) override;
+	void XMETHODCALLTYPE renderGI(IGXTexture2D *pLightTotal, IGXTexture2D *pTempBuffer) override;
+	void XMETHODCALLTYPE renderToneMapping(IGXTexture2D *pSourceLight) override;
+	void XMETHODCALLTYPE renderDebug() override;
+
+protected:
+	void showGICubes();
+
 protected:
 	CXLightSun *m_pSun = NULL;
 	MemAlloc<CXLightPoint, 256, 16, 16> m_poolPoint;
 	MemAlloc<CXLightSpot, 256, 16, 16> m_poolSpot;
 
+	IXCore *m_pCore;
+	IXRenderPipeline *m_pRenderPipeline = NULL;
+	IXMaterialSystem *m_pMaterialSystem = NULL;
+	IGXDevice *m_pDevice = NULL;
+
+	CShadowCache *m_pShadowCache = NULL;
+
+	ICamera *m_pMainCamera = NULL;
+
 	float3_t m_vLevelMin, m_vLevelMax;
 	float m_fLevelDimensions = 0.0f;
 
@@ -48,6 +74,105 @@ protected:
 
 	IMesh *m_pShapeSphere = NULL;
 	IMesh *m_pShapeCone = NULL;
+
+
+	IGXRenderBuffer *m_pGICubesRB = NULL;
+	UINT m_uGICubesCount = 0;
+	ID m_idGICubesShader = -1;
+
+	//! G-Buffer
+	IGXTexture2D *m_pGBufferColor = NULL;
+	IGXTexture2D *m_pGBufferNormals = NULL;
+	IGXTexture2D *m_pGBufferParams = NULL;
+	IGXTexture2D *m_pGBufferDepth = NULL;
+
+	//###################################
+
+	IGXDepthStencilState *m_pDepthStencilStateDefault = NULL;
+	IGXSamplerState *m_pSamplerPointClamp = NULL;
+	IGXSamplerState *m_pSamplerLinearWrap = NULL;
+	IGXSamplerState *m_pSamplerLinearClamp = NULL;
+	IGXSamplerState *m_pSamplerLinearBorder = NULL;
+
+	IGXRasterizerState *m_pRasterizerCullNone = NULL;
+	IGXRasterizerState *m_pRasterizerConservative = NULL;
+
+	IGXBlendState *m_pBlendRed = NULL;
+	IGXBlendState *m_pBlendAlphaOneOne = NULL;
+
+	IGXDepthStencilState *m_pDepthStencilStateNoZ = NULL;
+	IGXDepthStencilState *m_pDepthStencilStateLightBound = NULL;
+	IGXDepthStencilState *m_pDepthStencilStateLightClear = NULL;
+	IGXDepthStencilState *m_pDepthStencilStateLightShadowNonGlobal = NULL;
+	IGXDepthStencilState *m_pDepthStencilStateLightShadowGlobal = NULL;
+
+	//###################################
+
+	ID m_idBlendAmbientSpecDiffColor = -1;
+	ID m_idComLightingShadow = -1;
+	ID m_idComLightingSpotShadow = -1;
+	ID m_idComLightingPSSMShadow = -1;
+	ID m_idComLightingGI = -1;
+
+	ID m_idHDRinitLuminance = -1;
+	ID m_idHDRAdaptLuminance = -1;
+	ID m_idHDRToneMapping = -1;
+
+	//###################################
+
+	struct LPVcascade
+	{
+		IGXTexture3D *pGIAccumRed = NULL;
+		IGXTexture3D *pGIAccumGreen = NULL;
+		IGXTexture3D *pGIAccumBlue = NULL;
+
+		IGXTexture3D *pGIAccumRed2 = NULL;
+		IGXTexture3D *pGIAccumGreen2 = NULL;
+		IGXTexture3D *pGIAccumBlue2 = NULL;
+	} m_aLPVs[3];
+
+	ID m_idLightBoundShader = -1;
+	ID m_idLPVPropagateShader = -1;
+	ID m_idLuminanceReductionShader = -1;
+	struct
+	{
+		struct
+		{
+			float4 vCenterSize[LPV_CASCADES_COUNT]; // xyz: center / size; w: world size of cell in meters
+		} vs;
+		//float4 vNearFarLayers;
+	} m_lpvCentersShaderData;
+	IGXConstantBuffer *m_pLPVcentersShaderData = NULL;
+	IGXConstantBuffer *m_pLPVcurrentCascadeShaderData = NULL;
+
+	struct
+	{
+		float fAdaptationSpeed;
+		float fBaseValue;
+		float _padding[2];
+	} m_toneMappingShaderData;
+	IGXConstantBuffer *m_pToneMappingShaderData = NULL;
+
+	struct
+	{
+		struct
+		{
+			SMMATRIX mVP; // dummy
+			SMMATRIX mViewInv;
+			float2 vNearFar;
+			float3 vParamProj;
+		} vs;
+	} m_shadowShaderData;
+	IGXConstantBuffer *m_pShadowShaderDataVS = NULL;
+
+	//###################################
+
+	//! Буфер яркости
+	IGXTexture2D *m_pLightLuminance = NULL;
+	IGXTexture2D *m_pLightLuminance32 = NULL;
+	IGXTexture2D *m_pLightLuminance1 = NULL;
+	IGXTexture2D *m_pAdaptedLuminance[2];
+	UINT m_uCurrAdaptedLuminanceTarget = 0;
 };
 
 #endif
diff --git a/source/render/ShadowCache.cpp b/source/light/ShadowCache.cpp
similarity index 100%
rename from source/render/ShadowCache.cpp
rename to source/light/ShadowCache.cpp
diff --git a/source/render/ShadowCache.h b/source/light/ShadowCache.h
similarity index 100%
rename from source/render/ShadowCache.h
rename to source/light/ShadowCache.h
diff --git a/source/light/light.cpp b/source/light/light.cpp
index e5ada15d18f7e5e8440001605d903a9cd04acd86..bdf07c8c2a35123cf06f8681a73d64f3a9bb5585 100644
--- a/source/light/light.cpp
+++ b/source/light/light.cpp
@@ -129,7 +129,7 @@ void CXLight::drawShape(IGXDevice *pDevice)
 
 		IGXContext *pCtx = pDevice->getThreadContext();
 
-		pCtx->setVSConstant(m_pVSData);
+		pCtx->setVSConstant(m_pVSData, SCR_OBJECT);
 
 		m_pShape->draw();
 	}
@@ -407,7 +407,7 @@ void CXLightSpot::updatePSConstants(IGXDevice *pDevice)
 
 SMMATRIX CXLightSpot::getWorldTM()
 {
-	float fAngleScale = cosf(m_fInnerAngle * 0.5f) * sqrtf(2.0f);
+	float fAngleScale = tanf(m_fOuterAngle * 0.5f);
 
 	return(SMMatrixScaling(float3(fAngleScale, 1.0f, fAngleScale)) * SMMatrixScaling(float3(getMaxDistance())) * m_qDirection.GetMatrix() * SMMatrixTranslation(m_vPosition));
 }
diff --git a/source/render/shadow.cpp b/source/light/shadow.cpp
similarity index 98%
rename from source/render/shadow.cpp
rename to source/light/shadow.cpp
index 75955758e9269443634fc935662161fb9c947557..0634c4d18c1e247e9e00cca690c1d5aa6c0f9b26 100644
--- a/source/render/shadow.cpp
+++ b/source/light/shadow.cpp
@@ -171,7 +171,7 @@ void CShadowMap::process(IXRenderPipeline *pRenderPipeline)
 	}*/
 }
 
-void CShadowMap::genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals)
+void CShadowMap::genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals)
 {
 	if(!m_pDevice)
 	{
@@ -180,8 +180,8 @@ void CShadowMap::genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDepth
 
 	IGXContext *pCtx = m_pDevice->getThreadContext();
 
-	const float c_fTexWidth = (float)pShadowMap->getWidth();
-	const float c_fTexHeight = (float)pShadowMap->getHeight();
+	// const float c_fTexWidth = (float)pShadowMap->getWidth();
+	// const float c_fTexHeight = (float)pShadowMap->getHeight();
 
 //	IGXSurface *pRenderSurf, *pBackBuf;
 //	pRenderSurf = pShadowMap->getMipmap(0);
@@ -606,10 +606,10 @@ void CShadowPSSM::process(IXRenderPipeline *pRenderPipeline)
 
 	pCtx->setColorTarget(NULL);
 
-	if(GetAsyncKeyState('U') < 0)
+	/*if(GetAsyncKeyState('U') < 0)
 	{
 		m_pDevice->saveTextureToFile("pssm_depth.dds", m_pDepthMap);
-	}
+	}*/
 }
 
 #define PSSM_LIGHT_NEAR 0.1f
@@ -730,7 +730,7 @@ void CShadowPSSM::updateFrustums()
 	m_pShaderDataGS->update(&m_shaderData.gs);
 }
 
-void CShadowPSSM::genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals)
+void CShadowPSSM::genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals)
 {
 	if(!m_pDevice)
 	{
@@ -743,8 +743,8 @@ void CShadowPSSM::genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDept
 
 	IGXContext *pCtx = m_pDevice->getThreadContext();
 
-	const float c_fTexWidth = (float)pShadowMap->getWidth();
-	const float c_fTexHeight = (float)pShadowMap->getHeight();
+	// const float c_fTexWidth = (float)pShadowMap->getWidth();
+	// const float c_fTexHeight = (float)pShadowMap->getHeight();
 
 	//	IGXSurface *pRenderSurf, *pBackBuf;
 	//	pRenderSurf = pShadowMap->getMipmap(0);
@@ -943,12 +943,12 @@ void CReflectiveShadowSun::process(IXRenderPipeline *pRenderPipeline)
 	pCtx->setColorTarget(NULL, 1);
 	pCtx->setColorTarget(NULL, 2);
 
-	/*if(GetAsyncKeyState('U') < 0)
+	if(GetAsyncKeyState('U') < 0)
 	{
 		m_pDevice->saveTextureToFile("sm_depth.dds", m_pDepthMap);
 		m_pDevice->saveTextureToFile("sm_normal.dds", m_pNormalMap);
 		m_pDevice->saveTextureToFile("sm_flux.dds", m_pFluxMap);
-	}*/
+	}
 }
 
 void CReflectiveShadowSun::updateFrustum()
@@ -1198,14 +1198,14 @@ void CShadowCubeMap::process(IXRenderPipeline *pRenderPipeline)
 	}*/
 }
 
-void CShadowCubeMap::genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals)
+void CShadowCubeMap::genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals)
 {
 	if(!m_pDevice)
 	{
 		return;
 	}
-	const float c_fTexWidth = (float)pShadowMap->getWidth();
-	const float c_fTexHeight = (float)pShadowMap->getHeight();
+	// const float c_fTexWidth = (float)pShadowMap->getWidth();
+	// const float c_fTexHeight = (float)pShadowMap->getHeight();
 
 	IGXContext *pCtx = m_pDevice->getThreadContext();
 
diff --git a/source/render/shadow.h b/source/light/shadow.h
similarity index 95%
rename from source/render/shadow.h
rename to source/light/shadow.h
index 50f1d9b419caa4927c0622e6c4ff7e0e0a33671e..4f8cd5ebff64a36bb914f5affb02821eae7de50e 100644
--- a/source/render/shadow.h
+++ b/source/light/shadow.h
@@ -24,7 +24,7 @@ class IXTexture;
 class IBaseShadowMap
 {
 public:
-	virtual void genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) = 0;
+	virtual void genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) = 0;
 };
 
 //##########################################################################
@@ -51,7 +51,7 @@ public:
 
 	void setLight(IXLight *pLight);
 	void process(IXRenderPipeline *pRenderPipeline);
-	void genShadow(IGXTexture2D *shadowmap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) override;
+	void genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) override;
 
 private:
 	IGXDevice *m_pDevice = NULL;
@@ -197,7 +197,7 @@ public:
 	void setObserverCamera(ICamera *pCamera);
 	void setLight(IXLight *pLight);
 	void process(IXRenderPipeline *pRenderPipeline);
-	void genShadow(IGXTexture2D *shadowmap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) override;
+	void genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) override;
 
 protected:
 	void updateFrustums();
@@ -350,7 +350,7 @@ public:
 
 	void setLight(IXLight *pLight);
 	void process(IXRenderPipeline *pRenderPipeline);
-	void genShadow(IGXTexture2D *pShadowMap, IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) override;
+	void genShadow(IGXTexture2D *pGBufferDepth, IGXTexture2D *pGBufferNormals) override;
 
 private:
 	IGXDevice *m_pDevice = NULL;
diff --git a/source/render/OcclusionCuller.cpp b/source/render/OcclusionCuller.cpp
index 9ec3eceff38c63b4dbc42a744f8ed95f1ca03aaf..83d9bee17cdada9f46bf6b9c23c975ba57fa3bc5 100644
--- a/source/render/OcclusionCuller.cpp
+++ b/source/render/OcclusionCuller.cpp
@@ -139,7 +139,7 @@ void COcclusionCuller::_update()
 				UINT uLightKey = x * OCCLUSION_BUFFER_HEIGHT + y;
 				if(m_apTemp.size() <= uLightKey)
 				{
-					m_apTemp[uLightKey] = m_pLightSystem->createPoint();
+					m_apTemp[uLightKey] = m_pLightSystem->newPoint();
 					m_apTemp[uLightKey]->setColor(float3(1.0f, 0.0f, 0.0f));
 				}
 
diff --git a/source/render/RenderPipeline.cpp b/source/render/RenderPipeline.cpp
index e5f6eb62e8817f1bde84223ca14c6926bf0ea5ac..547ed179a49aac35106ed63e8129f67f6c27dec0 100644
--- a/source/render/RenderPipeline.cpp
+++ b/source/render/RenderPipeline.cpp
@@ -13,7 +13,6 @@ namespace gdata
 
 //! При изменении базовых шейдеров отредактировать https://wiki.skyxengine.com/index.php?title=Стандартные_шейдеры_материалов
 
-#define LUMINANCE_BUFFER_SIZE 1024
 
 CRenderPipeline::CRenderPipeline(IGXDevice *pDevice):
 	m_pDevice(pDevice)
@@ -530,16 +529,15 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice):
 	//GXFMT_G32R32F; // 64bpp; GXFMT_R32F
 	m_pGBufferDepth = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_R32F);
 
+	if(m_pLightSystem)
+	{
+		m_pLightSystem->setRenderPipeline(this);
+		m_pLightSystem->setGBuffer(m_pGBufferColor, m_pGBufferNormals, m_pGBufferParams, m_pGBufferDepth);
+	}
 
 	m_pLightAmbientDiffuse = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_A16B16G16R16F);
 	
-	m_pLightLuminance = m_pDevice->createTexture2D(LUMINANCE_BUFFER_SIZE, LUMINANCE_BUFFER_SIZE, 1, GX_TEXFLAG_RENDERTARGET, GXFMT_R16F);
-
-	m_pLightLuminance32 = m_pDevice->createTexture2D(32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
-	m_pLightLuminance1 = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
-	m_pAdaptedLuminance[0] = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
-	m_pAdaptedLuminance[1] = m_pDevice->createTexture2D(1, 1, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_R16F);
-
+	
 	m_pLightTotal = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_A16B16G16R16F);
 	
 	m_pRefractiveTextures[0] = m_pDevice->createTexture2D(m_uOutWidth, m_uOutHeight, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_AUTORESIZE, GXFMT_A16B16G16R16F);
@@ -569,78 +567,11 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice):
 	//m_pSceneShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_sceneShaderData));
 	m_pSceneShaderDataPS = m_pDevice->createConstantBuffer(sizeof(m_sceneShaderData));
 
-	m_pCameraShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_cameraShaderData.vs));
-
-	m_pLPVcentersShaderData = m_pDevice->createConstantBuffer(sizeof(m_lpvCentersShaderData.vs));
-	m_pLPVcurrentCascadeShaderData = m_pDevice->createConstantBuffer(sizeof(float4_t));
-
-	m_pLightingShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_lightingShaderData.vs));
-	m_pLightingShaderDataPS = m_pDevice->createConstantBuffer(sizeof(m_lightingShaderData.ps));
+	m_pCameraShaderData = m_pDevice->createConstantBuffer(sizeof(m_cameraShaderData));
 
 	m_pFrameShaderData = m_pDevice->createConstantBuffer(sizeof(m_frameShaderData));
 
-	m_pToneMappingShaderData = m_pDevice->createConstantBuffer(sizeof(m_toneMappingShaderData));
-
-	{
-		const UINT uSize = 32;
-		m_uGICubesCount = uSize * uSize * uSize;
-		float3_t *pData = new float3_t[m_uGICubesCount];
-		float fHalf = (float)uSize / 2.0f;
-		for(UINT x = 0; x < uSize; ++x)
-		{
-			for(UINT y = 0; y < uSize; ++y)
-			{
-				for(UINT z = 0; z < uSize; ++z)
-				{
-					pData[x + y * uSize + z * uSize * uSize] = (float3)(float3((float)x, (float)y, (float)z) - float3(fHalf));
-				}
-			}
-		}		
-		IGXVertexBuffer *pVB = m_pDevice->createVertexBuffer(sizeof(float3_t) * m_uGICubesCount, GXBUFFER_USAGE_STATIC, pData);
-		mem_delete_a(pData);
-
-		GXVertexElement oLayout[] =
-		{
-			{0, 0, GXDECLTYPE_FLOAT3, GXDECLUSAGE_POSITION},
-			GX_DECL_END()
-		};
-
-		IGXVertexDeclaration *pVD = m_pDevice->createVertexDeclaration(oLayout);
-		m_pGICubesRB = m_pDevice->createRenderBuffer(1, &pVB, pVD);
-		mem_release(pVD);
-		mem_release(pVB);
-
-		ID idVS = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "gi_cubes.vs");
-		ID idPS = SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "gi_cubes.ps");
-		ID idGS = SGCore_ShaderLoad(SHADER_TYPE_GEOMETRY, "gi_cubes.gs");
-		m_idGICubesShader = SGCore_ShaderCreateKit(idVS, idPS, idGS);
-	}
-
-//#define TIDX(x, y, z) (x + y * 32 + z * 32 * 32)
-	for(UINT i = 0; i < 3; ++i)
-	{
-		m_aLPVs[i].pGIAccumRed = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
-		m_aLPVs[i].pGIAccumGreen = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
-		m_aLPVs[i].pGIAccumBlue = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
-		
-		m_aLPVs[i].pGIAccumRed2 = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
-		m_aLPVs[i].pGIAccumGreen2 = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
-		m_aLPVs[i].pGIAccumBlue2 = m_pDevice->createTexture3D(32, 32, 32, 1, GX_TEXFLAG_RENDERTARGET | GX_TEXFLAG_UNORDERED_ACCESS, GXFMT_A32B32G32R32F);
-
-	}
-//#undef TIDX
-
-	m_idLightBoundShader = SGCore_ShaderCreateKit(SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "lighting_bound.vs"), -1);
-	// m_idLightBoundShader = SGCore_ShaderCreateKit(SGCore_ShaderLoad(SHADER_TYPE_VERTEX, "lighting_bound.vs"), 
-	// 	SGCore_ShaderLoad(SHADER_TYPE_PIXEL, "lighting_bound_debug.ps"));
-
-	m_idLPVPropagateShader = SGCore_ShaderCreateKit(-1, -1, -1, SGCore_ShaderLoad(SHADER_TYPE_COMPUTE, "gi_propagation.cs"));
-
-	m_idLuminanceReductionShader = SGCore_ShaderCreateKit(-1, -1, -1, SGCore_ShaderLoad(SHADER_TYPE_COMPUTE, "hdr_reduction.cs"));
-
-	m_pShadowCache = new CShadowCache(this, m_pMaterialSystem);
-	m_pShadowShaderDataVS = m_pDevice->createConstantBuffer(sizeof(m_shadowShaderData.vs));
-
+	
 	
 	newVisData(&m_pMainCameraVisibility);
 	m_pMainCameraOcclusionCuller = new COcclusionCuller();
@@ -666,8 +597,6 @@ CRenderPipeline::~CRenderPipeline()
 
 	mem_release(m_pRefractionScene);
 
-	mem_release(m_pToneMappingShaderData);
-
 	mem_release(m_pTransparencyShaderClipPlanes);
 
 	mem_release(m_pMainCameraOcclusionCuller);
@@ -676,13 +605,7 @@ CRenderPipeline::~CRenderPipeline()
 	//mem_release(m_pSceneShaderDataVS);
 	mem_release(m_pSceneShaderDataPS);
 
-	mem_release(m_pCameraShaderDataVS);
-
-	mem_release(m_pLPVcentersShaderData);
-	mem_release(m_pLPVcurrentCascadeShaderData);
-
-	mem_release(m_pLightingShaderDataVS);
-	mem_release(m_pLightingShaderDataPS);
+	mem_release(m_pCameraShaderData);
 
 	mem_release(m_pGBufferColor);
 	mem_release(m_pGBufferNormals);
@@ -690,12 +613,7 @@ CRenderPipeline::~CRenderPipeline()
 	mem_release(m_pGBufferDepth);
 
 	mem_release(m_pLightAmbientDiffuse);
-	mem_release(m_pLightLuminance);
 
-	mem_release(m_pLightLuminance32);
-	mem_release(m_pLightLuminance1);
-	mem_release(m_pAdaptedLuminance[0]);
-	mem_release(m_pAdaptedLuminance[1]);
 
 	mem_release(m_pFrameShaderData);
 
@@ -705,22 +623,6 @@ CRenderPipeline::~CRenderPipeline()
 
 	mem_release(m_pDepthStencilStateNoZWrite);
 	mem_release(m_pDepthStencilStateNoZ);
-
-	mem_release(m_pGICubesRB);
-
-	for(UINT i = 0; i < 3; ++i)
-	{
-		mem_release(m_aLPVs[i].pGIAccumRed);
-		mem_release(m_aLPVs[i].pGIAccumGreen);
-		mem_release(m_aLPVs[i].pGIAccumBlue);
-
-		mem_release(m_aLPVs[i].pGIAccumRed2);
-		mem_release(m_aLPVs[i].pGIAccumGreen2);
-		mem_release(m_aLPVs[i].pGIAccumBlue2);
-	}
-
-	mem_delete(m_pShadowCache);
-	mem_release(m_pShadowShaderDataVS);
 }
 
 void CRenderPipeline::resize(UINT uWidth, UINT uHeight, bool isWindowed)
@@ -731,16 +633,15 @@ void CRenderPipeline::resize(UINT uWidth, UINT uHeight, bool isWindowed)
 	m_isWindowed = isWindowed;
 }
 
-void CRenderPipeline::renderFrame()
+void CRenderPipeline::renderFrame(float fDeltaTime)
 {
-	UINT timeDelta = 16;
 	static const int *r_final_image = GET_PCVAR_INT("r_final_image");
 
 	IGXContext *pCtx = m_pDevice->getThreadContext();
 	IGXSurface *pBackBuf = pCtx->getColorTarget();
 	IGXSurface *pSceneBuf = NULL;
 
-	m_frameShaderData.fFrameTime = (float)timeDelta / 1000.0f;
+	m_frameShaderData.fFrameTime = fDeltaTime;
 	m_pFrameShaderData->update(&m_frameShaderData);
 
 	pCtx->setVSConstant(m_pFrameShaderData, SCR_FRAME);
@@ -751,13 +652,19 @@ void CRenderPipeline::renderFrame()
 	//m_pDevice->setVertexShaderConstant(m_pSceneShaderDataVS, SCR_SCENE);
 	pCtx->setPSConstant(m_pSceneShaderDataPS, SCR_SCENE);
 
-	m_cameraShaderData.vs.mVP = SMMatrixTranspose(gdata::mCamView * gdata::mCamProj);
-	m_cameraShaderData.vs.mInvVP = SMMatrixInverse(NULL, m_cameraShaderData.vs.mVP);
-	m_cameraShaderData.vs.vPosCam = gdata::vConstCurrCamPos;
-	m_pCameraShaderDataVS->update(&m_cameraShaderData.vs);
-	pCtx->setVSConstant(m_pCameraShaderDataVS, SCR_CAMERA);
-	pCtx->setPSConstant(m_pCameraShaderDataVS, SCR_CAMERA);
-
+	m_cameraShaderData.mVP = SMMatrixTranspose(gdata::mCamView * gdata::mCamProj);
+	m_cameraShaderData.mInvVP = SMMatrixInverse(NULL, m_cameraShaderData.mVP);
+	m_cameraShaderData.mInvV = SMMatrixTranspose(SMMatrixInverse(NULL, gdata::mCamView));
+	m_cameraShaderData.vPosCam = gdata::vConstCurrCamPos;
+	m_cameraShaderData.vNearFar = gdata::vNearFar;
+	m_cameraShaderData.vParamProj = float3_t((float)m_uOutWidth, (float)m_uOutHeight, gdata::fProjFov);
+	m_pCameraShaderData->update(&m_cameraShaderData);
+	pCtx->setVSConstant(m_pCameraShaderData, SCR_CAMERA);
+	pCtx->setPSConstant(m_pCameraShaderData, SCR_CAMERA);
+	pCtx->setVSConstant(m_pCameraShaderData, SCR_OBSERVER_CAMERA);
+	pCtx->setGSConstant(m_pCameraShaderData, SCR_OBSERVER_CAMERA);
+	pCtx->setPSConstant(m_pCameraShaderData, SCR_OBSERVER_CAMERA);
+	
 	renderPrepare();
 
 	Core_PStartSection(PERF_SECTION_MRT);
@@ -780,10 +687,10 @@ void CRenderPipeline::renderFrame()
 		goto end;
 	}
 
-	renderGI();
-
 	if(m_pLightSystem)
 	{
+		m_pLightSystem->renderGI(m_pLightTotal, m_pLightAmbientDiffuse);
+
 		if(*r_final_image == DS_RT_AMBIENTDIFF)
 		{
 			showTexture(m_pLightAmbientDiffuse);
@@ -811,14 +718,15 @@ void CRenderPipeline::renderFrame()
 	{
 		pCtx->setColorTarget(pBackBuf);
 
-		toneMapping();
+		m_pLightSystem->renderToneMapping(m_pLightAmbientDiffuse);
 
-		if(*r_final_image == DS_RT_LUMINANCE)
-		{
-			showTexture(m_pLightLuminance);
-			// showTexture(m_pLightLuminance32);
-			goto end;
-		}
+	//! @todo reimplement me!
+	//	if(*r_final_image == DS_RT_LUMINANCE)
+	//	{
+	//		showTexture(m_pLightLuminance);
+	//		// showTexture(m_pLightLuminance32);
+	//		goto end;
+	//	}
 
 		//showTexture(m_pLightAmbientDiffuse);
 	}
@@ -854,10 +762,9 @@ end:
 	mem_release(pBackBuf);
 	mem_release(pSceneBuf);
 
-	const bool *dev_lpv_cubes = GET_PCVAR_BOOL("dev_lpv_cubes");
-	if(*dev_lpv_cubes)
+	if(m_pLightSystem)
 	{
-		showGICubes();
+		m_pLightSystem->renderDebug();
 	}
 
 	Core_PStartSection(PERF_SECTION_RENDER_INFO);
@@ -886,10 +793,9 @@ void CRenderPipeline::updateVisibility()
 
 	if(m_pLightSystem)
 	{
-		float3 vCamPos;
-		gdata::pCamera->getPosition(&vCamPos);
-		//! @todo: fix grid center pos!
-		m_pLightSystem->updateVisibility(gdata::pCamera, float3(-16.0f, -16.0f, -16.0f) + vCamPos, float3(16.0f, 16.0f, 16.0f) + vCamPos);
+		//! @todo move to CRenderPipeline::setFrameObserverCamera() method
+		m_pLightSystem->setFrameObserverCamera(gdata::pCamera);
+		m_pLightSystem->updateVisibility();
 	}
 }
 
@@ -927,131 +833,6 @@ void CRenderPipeline::newVisData(IXRenderableVisibility **ppVisibility)
 	*ppVisibility = pVisibility;
 }
 
-void CRenderPipeline::showGICubes()
-{
-	IGXContext *pCtx = m_pDevice->getThreadContext();
-
-	pCtx->setPrimitiveTopology(GXPT_POINTLIST);
-	pCtx->setRenderBuffer(m_pGICubesRB);
-	SGCore_ShaderBind(m_idGICubesShader);
-	pCtx->setGSConstant(m_pLightingShaderDataVS, 1);
-	pCtx->setDepthStencilState(m_pDepthStencilStateDefault);
-	pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0);
-
-	pCtx->setVSConstant(m_pLPVcurrentCascadeShaderData, 10);
-	pCtx->setGSConstant(m_pLPVcurrentCascadeShaderData, 10);
-	pCtx->setPSConstant(m_pLPVcurrentCascadeShaderData, 10);
-
-	for(UINT i = 2; i < 3; ++i)
-	{
-		float4_t vTmp((float)i + 0.5f);  // just to be sure
-		m_pLPVcurrentCascadeShaderData->update(&vTmp);
-
-		pCtx->setPSTexture(m_aLPVs[i].pGIAccumRed2, 0);
-		pCtx->setPSTexture(m_aLPVs[i].pGIAccumGreen2, 1);
-		pCtx->setPSTexture(m_aLPVs[i].pGIAccumBlue2, 2);
-
-		pCtx->drawPrimitive(0, m_uGICubesCount);
-	}
-	
-
-	pCtx->setPrimitiveTopology(GXPT_TRIANGLELIST);
-
-	pCtx->setPSTexture(NULL, 0);
-	pCtx->setPSTexture(NULL, 1);
-	pCtx->setPSTexture(NULL, 2);
-}
-
-void CRenderPipeline::toneMapping()
-{
-	Core_PStartSection(PERF_SECTION_TONEMAPPING);
-	static const float *hdr_adapted_coef = GET_PCVAR_FLOAT("hdr_adapted_coef");
-	static const float *hdr_base_value = GET_PCVAR_FLOAT("hdr_base_value");
-	
-	//! @todo update only on change
-	m_toneMappingShaderData.fAdaptationSpeed = *hdr_adapted_coef;
-	m_toneMappingShaderData.fBaseValue = *hdr_base_value;
-	m_pToneMappingShaderData->update(&m_toneMappingShaderData);
-
-	//	SGCore_ToneMappingCom(timeDelta, (hdr_adapted_coef ? (*hdr_adapted_coef) : 0.03f));
-	IGXContext *pCtx = m_pDevice->getThreadContext();
-
-	pCtx->setPSConstant(m_pToneMappingShaderData, 8);
-
-	IGXSurface *pBackBuf = pCtx->getColorTarget();
-
-	IGXSurface *pRT = m_pLightLuminance->asRenderTarget();
-	pCtx->setColorTarget(pRT);
-	mem_release(pRT);
-
-	pCtx->setPSTexture(m_pLightAmbientDiffuse);
-	pCtx->setSamplerState(gdata::rstates::pSamplerLinearClamp, 0);
-
-	IGXDepthStencilSurface *pDSSurface = pCtx->getDepthStencilSurface();
-	pCtx->unsetDepthStencilSurface();
-
-	SGCore_ShaderBind(gdata::shaders_id::kit::idHDRinitLuminance);
-	SGCore_ScreenQuadDraw();
-	SGCore_ShaderUnBind();
-
-	pCtx->setColorTarget(pBackBuf);
-
-	// Reduction
-	{
-		SGCore_ShaderBind(m_idLuminanceReductionShader);
-
-		pCtx->setCSTexture(m_pLightLuminance, 0);
-		pCtx->setCSUnorderedAccessView(m_pLightLuminance32, 0);
-		pCtx->computeDispatch(32, 32, 1);
-		pCtx->setCSUnorderedAccessView(NULL, 0);
-		pCtx->setCSTexture(NULL, 0);
-
-		pCtx->setCSTexture(m_pLightLuminance32, 0);
-		pCtx->setCSUnorderedAccessView(m_pLightLuminance1, 0);
-		pCtx->computeDispatch(1, 1, 1);
-		pCtx->setCSUnorderedAccessView(NULL, 0);
-		pCtx->setCSTexture(NULL, 0);
-
-		SGCore_ShaderUnBind();
-	}
-
-	// Adaptation
-	{
-		// m_pLightLuminance1
-		pCtx->setPSTexture(m_pAdaptedLuminance[!m_uCurrAdaptedLuminanceTarget]);
-		pCtx->setPSTexture(m_pLightLuminance1, 1);
-		IGXSurface *pAdaptedLuminanceBuf = m_pAdaptedLuminance[m_uCurrAdaptedLuminanceTarget]->asRenderTarget();
-		pCtx->setColorTarget(pAdaptedLuminanceBuf);
-		mem_release(pAdaptedLuminanceBuf);
-		
-		SGCore_ShaderBind(gdata::shaders_id::kit::idHDRAdaptLuminance);
-
-		SGCore_ScreenQuadDraw();
-
-		SGCore_ShaderUnBind();
-	}
-
-
-	pCtx->setColorTarget(pBackBuf);
-	mem_release(pBackBuf);
-
-	{
-		pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0);
-		pCtx->setPSTexture(m_pLightAmbientDiffuse);
-		pCtx->setPSTexture(m_pAdaptedLuminance[m_uCurrAdaptedLuminanceTarget], 1);
-		pCtx->setPSTexture(m_pLightLuminance1, 2);
-		SGCore_ShaderBind(gdata::shaders_id::kit::idHDRToneMapping);
-
-		SGCore_ScreenQuadDraw();
-
-		SGCore_ShaderUnBind(); 
-	}
-
-	pCtx->setDepthStencilSurface(pDSSurface);
-	m_uCurrAdaptedLuminanceTarget = !m_uCurrAdaptedLuminanceTarget;
-
-	Core_PEndSection(PERF_SECTION_TONEMAPPING);
-}
 
 void CRenderPipeline::renderPrepare()
 {
@@ -1121,493 +902,15 @@ void CRenderPipeline::renderGBuffer()
 void CRenderPipeline::renderShadows()
 {
 	IGXContext *pCtx = m_pDevice->getThreadContext();
-
+	//m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow);
 	rfunc::SetRenderSceneFilter();
 	pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 1);
 }
 void CRenderPipeline::renderGI()
 {
-	if(!m_pLightSystem)
-	{
-		return;
-	}
-
-
-	IGXContext *pCtx = m_pDevice->getThreadContext();
-
-	IGXDepthStencilSurface *pOldDSSurface = pCtx->getDepthStencilSurface();
-
-	UINT uCounts[LIGHT_TYPE__COUNT] = {0};
-	for(int i = 0, l = m_pLightSystem->getCount(); i < l; ++i)
-	{
-		++uCounts[m_pLightSystem->getLight(i)->getType()];
-	}
-	m_pShadowCache->setLightsCount(uCounts[LIGHT_TYPE_POINT], uCounts[LIGHT_TYPE_SPOT], uCounts[LIGHT_TYPE_SUN] != 0);
-	m_pShadowCache->setRSMLightsCount(uCounts[LIGHT_TYPE_POINT], uCounts[LIGHT_TYPE_SPOT], uCounts[LIGHT_TYPE_SUN] != 0);
-
-	m_pShadowCache->setObserverCamera(gdata::pCamera);
-
-	m_pShadowCache->nextFrame();
-
-	IGXSurface *pAmbientSurf, *pBackBuf;
-	pAmbientSurf = m_pLightAmbientDiffuse->getMipmap();
-
-	pBackBuf = pCtx->getColorTarget();
-
-	pCtx->setColorTarget(pAmbientSurf);
-
-	//очищаем рт и стенсил
-	pCtx->clear(GX_CLEAR_COLOR | GX_CLEAR_STENCIL);
-
 	rfunc::SetRenderSceneFilter();
 	m_pMaterialSystem->bindRenderPass(m_pRenderPassIllumination);
 	renderStage(XRS_GI);
-
-	m_pMaterialSystem->bindRenderPass(m_pRenderPassShadow);
-	m_lightingShaderData.vs.mViewInv = SMMatrixTranspose(SMMatrixInverse(NULL, gdata::mCamView));
-	m_lightingShaderData.vs.mVP = SMMatrixTranspose(gdata::mCamView * gdata::mCamProj);
-	m_lightingShaderData.vs.vNearFar = gdata::vNearFar;
-	m_lightingShaderData.vs.vParamProj = float3_t((float)m_uOutWidth, (float)m_uOutHeight, gdata::fProjFov);
-	m_pLightingShaderDataVS->update(&m_lightingShaderData.vs);
-
-	m_lightingShaderData.ps.vViewPos = gdata::vConstCurrCamPos;
-	m_pLightingShaderDataPS->update(&m_lightingShaderData.ps.vViewPos);
-
-	float3 vCamDir;
-	gdata::pCamera->getLook(&vCamDir);
-
-	const float c_aLPVsizes[] = {
-		//0.5f,
-		//1.0f,
-		//2.0f
-
-		1.0f,
-		2.0f,
-		4.0f
-	};
-
-	m_lpvCentersShaderData.vs.vCenterSize[0] = float4(gdata::vConstCurrCamPos + vCamDir * (LPV_GRID_SIZE / 2 - LPV_STEP_COUNT) * c_aLPVsizes[0], c_aLPVsizes[0]);
-	m_lpvCentersShaderData.vs.vCenterSize[1] = float4(gdata::vConstCurrCamPos + vCamDir * (LPV_GRID_SIZE / 2 - LPV_STEP_COUNT) * c_aLPVsizes[1], c_aLPVsizes[1]);
-	m_lpvCentersShaderData.vs.vCenterSize[2] = float4(gdata::vConstCurrCamPos + vCamDir * (LPV_GRID_SIZE / 2 - LPV_STEP_COUNT) * c_aLPVsizes[2], c_aLPVsizes[2]);
-	m_pLPVcentersShaderData->update(&m_lpvCentersShaderData.vs);
-
-	/*
-	vs:
-		cbuffer0: (per light)
-		- g_mW
-		cbuffer1: (per frame)
-		- g_mVP
-		- g_mViewInv
-		- g_vNearFar
-		- g_vParamProj
-
-	ps:
-		cbuffer0: (per light)
-		- g_vLightPos
-		- g_vLightColor
-		- g_vLightPowerDistShadow
-		cbuffer1: (per frame)
-		- g_vViewPos
-
-
-	{
-		render shadowmaps
-		render direct light with shadows
-		inject VPLs into LPV grid
-	}
-	*/
-	
-	// Определим список лампочек, которые будут участвовать в текущем кадре
-	IXLight *pLight;
-	for(int i = 0, l = m_pLightSystem->getCount(); i < l; ++i)
-	{
-		pLight = m_pLightSystem->getLight(i);
-
-		//если свет виден фрустуму камеры (это надо было заранее просчитать) и если свет включен
-		if(pLight->isEnabled() && pLight->getRenderType() != LRT_NONE)
-		{
-			if(pLight->getRenderType() & LRT_LPV)
-			{
-				m_pShadowCache->addRSMLight(pLight);
-			}
-			if(pLight->getRenderType() & LRT_LIGHT)
-			{
-				m_pShadowCache->addLight(pLight);
-			}
-		}
-	}
-
-	static const float *r_default_fov = GET_PCVAR_FLOAT("r_default_fov");
-	static const float *r_near = GET_PCVAR_FLOAT("r_near");
-	static const float *r_far = GET_PCVAR_FLOAT("r_far");
-
-// 	float4x4 &mCamView = gdata::mCamView;
-// 	// Core_RMatrixGet(G_RI_MATRIX_OBSERVER_VIEW, &mCamView);
-// 	m_shadowShaderData.vs.mViewInv = SMMatrixTranspose(SMMatrixInverse(NULL, mCamView));
-// 	m_shadowShaderData.vs.vNearFar = gdata::vNearFar; // float2(*r_near, *r_far);
-// 	m_shadowShaderData.vs.vParamProj = float3((float)m_uOutWidth, (float)m_uOutHeight, gdata::fProjFov); // *r_default_fov);
-// 	m_pShadowShaderDataVS->update(&m_shadowShaderData.vs);
-
-	//@TODO: убрать это
-	//Core_RFloat3Get(G_RI_FLOAT3_OBSERVER_POSITION, &m_shadowShaderData.ps.vPosCam);
-	//m_pShadowShaderDataPS->update(&m_shadowShaderData.ps);
-	
-
-	//m_pDevice->setPixelShaderConstant(m_pShadowShaderDataPS, 7);
-
-	pCtx->setRasterizerState(gdata::rstates::pRasterizerConservative);
-
-	pCtx->setVSConstant(m_pCameraShaderDataVS, 8);
-	pCtx->setPSConstant(m_pCameraShaderDataVS, 8);
-	
-	UINT uShadowCount = 0;
-	while((uShadowCount = m_pShadowCache->processNextBunch()))
-	{
-		pCtx->setColorTarget(pAmbientSurf);
-		pCtx->setDepthStencilSurface(pOldDSSurface);
-		pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne);
-
-		pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
-		pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
-
-		IBaseShadowMap *pShadow = NULL;
-
-		//render direct light with shadows
-		for(UINT i = 0; i < uShadowCount; ++i)
-		{
-			pLight = m_pShadowCache->getLight(i);
-			pShadow = m_pShadowCache->getShadow(i);
-			
-			//если не глобальный источник
-			if(pLight->getType() != LIGHT_TYPE_SUN)
-			{
-				//помечаем в стенсил буфере пиксели  которые входят в ограничивающий объем света, чтобы их осветить
-				pCtx->setRasterizerState(gdata::rstates::pRasterizerCullNone);
-				pCtx->setStencilRef(0);
-				pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateLightBound);
-
-				//отрисовка ограничивающего объема
-				SGCore_ShaderBind(m_idLightBoundShader);
-				pLight->drawShape(m_pDevice);
-				
-				pCtx->setStencilRef(255);
-				pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateLightShadowNonGlobal);
-			}
-			else
-			{
-				//иначе это глобальный источник, отключаем стенсил тест
-				pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateLightShadowGlobal);
-			}
-
-			pCtx->setRasterizerState(NULL);
-
-
-
-			//pCtx->setVSConstant(m_pShadowShaderDataVS, 1);
-			pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
-
-			pCtx->setBlendState(gdata::rstates::pBlendRed);
-			pShadow->genShadow(m_pShadow, m_pGBufferDepth, m_pGBufferNormals);
-			pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne);
-			pCtx->setColorTarget(pAmbientSurf);
-
-		//	pCtx->setPSTexture(m_pShadow, 4);
-			//idshaderkit = gdata::shaders_id::kit::idComLightingShadow;
-			ID idshaderkit = -1;
-			switch(pLight->getType())
-			{
-			case LIGHT_TYPE_SPOT:
-				idshaderkit = gdata::shaders_id::kit::idComLightingSpotShadow;
-				break;
-			case LIGHT_TYPE_POINT: 
-				idshaderkit = gdata::shaders_id::kit::idComLightingShadow;
-				break;
-			case LIGHT_TYPE_SUN:
-				idshaderkit = gdata::shaders_id::kit::idComLightingPSSMShadow;
-				break;
-			default:
-				assert(!"Unknown light type!");
-			}
-
-			pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
-			
-			//теперь когда будем считать освещение надо сбросить значения в стенсил буфере, чтобы каждый кадр не чистить
-			//если стенсил тест прошел успешно, устанавливаем значнеие в нуль
-			if(pLight->getType() != LIGHT_TYPE_SUN)
-			{
-				pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateLightClear);
-			}
-
-			IGXConstantBuffer *pLightConstants = pLight->getConstants(m_pDevice);
-			pCtx->setPSConstant(pLightConstants);
-			mem_release(pLightConstants);
-
-			SGCore_ShaderBind(idshaderkit);
-
-			pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0);
-			
-			pCtx->setPSTexture(m_pGBufferColor);
-			pCtx->setPSTexture(m_pGBufferNormals, 1);
-			pCtx->setPSTexture(m_pGBufferParams, 2);
-			pCtx->setPSTexture(m_pGBufferDepth, 3);
-			//m_pDevice->setTexture(SGCore_GbufferGetRT(DS_RT_ADAPTEDLUM), 5);
-
-			SGCore_ScreenQuadDraw();
-		}
-
-
-		//pCtx->setSamplerState(gdata::rstates::pSamplerLinearWrap, 0);
-		//pCtx->setSamplerState(gdata::rstates::pSamplerLinearWrap, 1);
-	}
-
-	pCtx->setVSConstant(m_pLPVcentersShaderData, 9);
-	pCtx->setPSConstant(m_pLPVcentersShaderData, 9);
-
-	bool isFirstRun[3] = {true, true, true};
-	while((uShadowCount = m_pShadowCache->processNextRSMBunch()))
-	{
-		pCtx->setVSConstant(m_pLPVcurrentCascadeShaderData, 10);
-		pCtx->setPSConstant(m_pLPVcurrentCascadeShaderData, 10);
-
-		pCtx->setDepthStencilSurface(pOldDSSurface);
-		pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne);
-
-		pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
-		pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
-
-		IGXDepthStencilSurface *pOldSurface = pCtx->getDepthStencilSurface();
-		pCtx->unsetDepthStencilSurface();
-
-		IBaseReflectiveShadowMap *pShadow = NULL;
-
-		for(UINT i = 0; i < 3; ++i)
-		{
-			float4_t vTmp((float)i + 0.5f); // just to be sure
-			m_pLPVcurrentCascadeShaderData->update(&vTmp);
-
-			IGXSurface *pLPVRed = m_aLPVs[i].pGIAccumRed->asRenderTarget();
-			IGXSurface *pLPVGreen = m_aLPVs[i].pGIAccumGreen->asRenderTarget();
-			IGXSurface *pLPVBlue = m_aLPVs[i].pGIAccumBlue->asRenderTarget();
-
-			//m_pDevice->setColorTarget(pAmbientSurf);
-			pCtx->setColorTarget(pLPVRed);
-			pCtx->setColorTarget(pLPVGreen, 1);
-			pCtx->setColorTarget(pLPVBlue, 2);
-
-			mem_release(pLPVRed);
-			mem_release(pLPVGreen);
-			mem_release(pLPVBlue);
-
-			if(isFirstRun[i])
-			{
-				pCtx->clear(GX_CLEAR_COLOR);
-				isFirstRun[i] = false;
-			}
-
-			//inject VPLs into LPV grid
-			for(UINT j = 0; j < uShadowCount; ++j)
-			{
-				pShadow = m_pShadowCache->getRSMShadow(j);
-				pShadow->genLPV();
-			}
-
-			pCtx->setColorTarget(NULL);
-			pCtx->setColorTarget(NULL, 1);
-			pCtx->setColorTarget(NULL, 2);
-		}
-
-		const bool *dev_lpv_points = GET_PCVAR_BOOL("dev_lpv_points");
-		if(*dev_lpv_points)
-		{
-			auto pTarget = m_pGBufferColor->asRenderTarget();
-			pCtx->setColorTarget(pAmbientSurf);
-			mem_release(pTarget);
-			for(UINT i = 0; i < uShadowCount; ++i)
-			{
-				pShadow = m_pShadowCache->getRSMShadow(i);
-				pShadow->genLPV(true);
-			}
-			pCtx->setColorTarget(NULL);
-		}
-
-		pCtx->setDepthStencilSurface(pOldSurface);
-		mem_release(pOldSurface);
-
-		//break;
-	}
-	for(UINT i = 0; i < 3; ++i)
-	{
-		if(isFirstRun[i])
-		{
-			IGXSurface *pLPVRed =   m_aLPVs[i].pGIAccumRed->asRenderTarget();
-			IGXSurface *pLPVGreen = m_aLPVs[i].pGIAccumGreen->asRenderTarget();
-			IGXSurface *pLPVBlue =  m_aLPVs[i].pGIAccumBlue->asRenderTarget();
-
-			pCtx->setColorTarget(pLPVRed);
-			pCtx->setColorTarget(pLPVGreen, 1);
-			pCtx->setColorTarget(pLPVBlue, 2);
-
-			mem_release(pLPVRed);
-			mem_release(pLPVGreen);
-			mem_release(pLPVBlue);
-
-			pCtx->clear(GX_CLEAR_COLOR);
-			isFirstRun[i] = false;
-
-			pCtx->setColorTarget(NULL);
-			pCtx->setColorTarget(NULL, 1);
-			pCtx->setColorTarget(NULL, 2);
-		}
-	}
-
-	SGCore_ShaderUnBind();
-
-	mem_release(pOldDSSurface);
-
-	pCtx->setVSConstant(m_pLightingShaderDataVS, 1);
-	pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
-
-	{
-		SGCore_ShaderBind(m_idLPVPropagateShader);
-		UINT uStepCount[] = {4, 6, 8};
-
-		//for(UINT k = 0; k < 1000; ++k)
-		//{
-			for(UINT j = 0; j < 3; ++j)
-			{
-				for(UINT i = 0; i < uStepCount[j]; ++i)
-				{
-					pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed, 0);
-					pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen, 1);
-					pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue, 2);
-
-					pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed2, 0);
-					pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen2, 1);
-					pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue2, 2);
-
-					pCtx->computeDispatch(4, 4, 32);
-
-					pCtx->setCSUnorderedAccessView(NULL, 0);
-					pCtx->setCSUnorderedAccessView(NULL, 1);
-					pCtx->setCSUnorderedAccessView(NULL, 2);
-
-					pCtx->setCSTexture(NULL, 0);
-					pCtx->setCSTexture(NULL, 1);
-					pCtx->setCSTexture(NULL, 2);
-
-
-					pCtx->setCSTexture(m_aLPVs[j].pGIAccumRed2, 0);
-					pCtx->setCSTexture(m_aLPVs[j].pGIAccumGreen2, 1);
-					pCtx->setCSTexture(m_aLPVs[j].pGIAccumBlue2, 2);
-
-					pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumRed, 0);
-					pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumGreen, 1);
-					pCtx->setCSUnorderedAccessView(m_aLPVs[j].pGIAccumBlue, 2);
-
-					pCtx->computeDispatch(4, 4, 32);
-
-					pCtx->setCSUnorderedAccessView(NULL, 0);
-					pCtx->setCSUnorderedAccessView(NULL, 1);
-					pCtx->setCSUnorderedAccessView(NULL, 2);
-
-					pCtx->setCSTexture(NULL, 0);
-					pCtx->setCSTexture(NULL, 1);
-					pCtx->setCSTexture(NULL, 2);
-				}
-			}
-		//}
-
-		SGCore_ShaderUnBind();
-	}
-	
-
-	{
-		pCtx->setColorTarget(pAmbientSurf);
-		//gdata::pDXDevice->setRasterizerState(NULL);
-		pCtx->setRasterizerState(gdata::rstates::pRasterizerCullNone);
-		pCtx->setBlendState(gdata::rstates::pBlendAlphaOneOne);
-		pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateLightShadowGlobal);
-
-		pCtx->setPSConstant(m_pLightingShaderDataPS, 1);
-
-		//ID idshader = gdata::shaders_id::ps::idComLightingGI;
-		ID idshaderkit = gdata::shaders_id::kit::idComLightingGI;
-
-		//SGCore_ShaderSetVRF(SHADER_TYPE_PIXEL, idshader, "g_vViewPos", &gdata::vConstCurrCamPos);
-
-	//	pCtx->setPSConstant(m_pCameraShaderDataVS, 8);
-
-		SGCore_ShaderBind(idshaderkit);
-
-		pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0);
-		pCtx->setSamplerState(gdata::rstates::pSamplerLinearBorder, 1);
-
-		pCtx->setPSTexture(m_pGBufferDepth);
-		pCtx->setPSTexture(m_pGBufferNormals, 1);
-		pCtx->setPSTexture(m_pGBufferColor, 2);
-		pCtx->setPSTexture(m_pGBufferParams, 3);
-		for(UINT i = 0; i < 3; ++i)
-		{
-			pCtx->setPSTexture(m_aLPVs[i].pGIAccumRed,   4 + i);
-			pCtx->setPSTexture(m_aLPVs[i].pGIAccumGreen, 7 + i);
-			pCtx->setPSTexture(m_aLPVs[i].pGIAccumBlue,  10 + i);
-		}
-
-		SGCore_ScreenQuadDraw();
-
-		pCtx->setPSTexture(NULL, 2);
-		pCtx->setPSTexture(NULL, 3);
-		pCtx->setPSTexture(NULL, 4);
-
-		SGCore_ShaderUnBind();
-		pCtx->setSamplerState(gdata::rstates::pSamplerLinearClamp, 1);
-	}
-
-
-
-	pCtx->setDepthStencilState(gdata::rstates::pDepthStencilStateNoZ);
-	pCtx->setRasterizerState(NULL);
-	pCtx->setBlendState(NULL);
-	
-	//pCtx->setColorTarget(NULL, 1);
-	
-	mem_release(pAmbientSurf);
-
-	//-------------------------------
-
-	//теперь необходимо все смешать чтобы получить итоговую освещенную картинку
-	//{{
-	
-	pCtx->setSamplerState(gdata::rstates::pSamplerPointClamp, 0);
-	pCtx->setSamplerState(gdata::rstates::pSamplerLinearClamp, 1);
-
-	IGXSurface *pComLightSurf = m_pLightTotal->getMipmap();
-	pCtx->setColorTarget(pComLightSurf);
-
-	//очищаем рт (в старой версии было многопроходное смешивание)
-	pCtx->clear(GX_CLEAR_COLOR);
-
-	pCtx->setPSTexture(m_pGBufferColor);
-	pCtx->setPSTexture(m_pLightAmbientDiffuse, 1);
-	//pCtx->setPSTexture(m_pLightSpecular, 2);
-	pCtx->setPSTexture(m_pGBufferNormals, 3);
-	pCtx->setPSTexture(m_pGBufferDepth, 4);
-	//gdata::pDXDevice->setTexture(SGCore_GbufferGetRT(DS_RT_ADAPTEDLUM), 4);
-	pCtx->setPSTexture(m_pGBufferParams, 5);
-
-	SGCore_ShaderBind(gdata::shaders_id::kit::idBlendAmbientSpecDiffColor);
-
-	SGCore_ScreenQuadDraw();
-
-	mem_release(pComLightSurf);
-	//}}
-
-	SGCore_ShaderUnBind();
-
-	pCtx->setColorTarget(pBackBuf);
-	mem_release(pBackBuf);
-
-	//Sleep(16);
 }
 void CRenderPipeline::renderPostprocessMain()
 {
@@ -1627,7 +930,7 @@ void CRenderPipeline::renderTransparent()
 	IGXSurface *pBackBuff = pCtx->getColorTarget();
 
 	//pCtx->setPSConstant(m_pSceneShaderDataPS, SCR_SCENE);
-	pCtx->setVSConstant(m_pCameraShaderDataVS, SCR_CAMERA);
+	pCtx->setVSConstant(m_pCameraShaderData, SCR_CAMERA);
 	rfunc::SetRenderSceneFilter();
 
 	m_pMaterialSystem->bindRenderPass(m_pRenderPassTransparency);
@@ -1644,12 +947,13 @@ void CRenderPipeline::renderTransparent()
 	pCtx->setPSTexture(m_pGBufferDepth, 2);
 //	pCtx->setPSTexture(m_pGBufferParams, 3);
 
-	for(UINT i = 0; i < 3; ++i)
-	{
-		pCtx->setPSTexture(m_aLPVs[i].pGIAccumRed, 5 + i);
-		pCtx->setPSTexture(m_aLPVs[i].pGIAccumGreen, 8 + i);
-		pCtx->setPSTexture(m_aLPVs[i].pGIAccumBlue, 11 + i);
-	}
+	//! @todo implement me!
+	// for(UINT i = 0; i < 3; ++i)
+	// {
+	// 	pCtx->setPSTexture(m_aLPVs[i].pGIAccumRed, 5 + i);
+	// 	pCtx->setPSTexture(m_aLPVs[i].pGIAccumGreen, 8 + i);
+	// 	pCtx->setPSTexture(m_aLPVs[i].pGIAccumBlue, 11 + i);
+	// }
 
 	m_iRefractiveSource = -1;
 	IGXSurface *pSceneTarget = m_pSceneTexture->asRenderTarget();
@@ -2241,10 +1545,13 @@ void CRenderPipeline::renderEditor2D()
 	float3 vCamPos;
 	SRender_GetCamera()->getPosition(&vCamPos);
 
-	m_cameraShaderData.vs.mVP = SMMatrixTranspose(mVP);
-	m_cameraShaderData.vs.vPosCam = vCamPos;
-	m_pCameraShaderDataVS->update(&m_cameraShaderData.vs);
-	m_pDevice->getThreadContext()->setVSConstant(m_pCameraShaderDataVS, SCR_CAMERA);
+	m_cameraShaderData.mVP = SMMatrixTranspose(mVP);
+	m_cameraShaderData.vPosCam = vCamPos;
+	m_pCameraShaderData->update(&m_cameraShaderData);
+	m_pDevice->getThreadContext()->setVSConstant(m_pCameraShaderData, SCR_CAMERA);
+	m_pDevice->getThreadContext()->setVSConstant(m_pCameraShaderData, SCR_OBSERVER_CAMERA);
+	m_pDevice->getThreadContext()->setPSConstant(m_pCameraShaderData, SCR_OBSERVER_CAMERA);
+	m_pDevice->getThreadContext()->setGSConstant(m_pCameraShaderData, SCR_OBSERVER_CAMERA);
 
 	renderStage(XRS_EDITOR_2D);
 }
diff --git a/source/render/RenderPipeline.h b/source/render/RenderPipeline.h
index a64ac3fd3e103d6ab3f932d93fbe1c75721671bd..7597aec36a917d9533d7b9e92cae9f2fd8d0ed2c 100644
--- a/source/render/RenderPipeline.h
+++ b/source/render/RenderPipeline.h
@@ -5,14 +5,10 @@
 #include <xcommon/IXRenderPipeline.h>
 #include <common/array.h>
 #include <light/IXLightSystem.h>
-#include "ShadowCache.h"
 #include <xUI/IXUI.h>
 #include "OcclusionCuller.h"
 
 #define MAX_TRANSPARENCY_CLIP_PANES 4
-#define LPV_CASCADES_COUNT 3
-#define LPV_GRID_SIZE 32
-#define LPV_STEP_COUNT 6
 
 class CRenderPipeline: public IXRenderPipeline
 {
@@ -24,7 +20,7 @@ public:
 
 	void updateVisibility() override;
 
-	void renderFrame() override;
+	void renderFrame(float fDeltaTime) override;
 	void endFrame() override;
 
 	SX_ALIGNED_OP_MEM2();
@@ -46,10 +42,6 @@ protected:
 	void renderPostprocessFinal() override;
 	void renderEditor2D() override;
 
-	void showGICubes();
-
-	void toneMapping();
-
 protected:
 	UINT getIndexForStage(X_RENDER_STAGE stage);
 
@@ -94,13 +86,7 @@ protected:
 
 	//! Буфер освещения
 	IGXTexture2D *m_pLightAmbientDiffuse = NULL;
-	//! Буфер яркости
-	IGXTexture2D *m_pLightLuminance = NULL;
-	IGXTexture2D *m_pLightLuminance32 = NULL;
-	IGXTexture2D *m_pLightLuminance1 = NULL;
-	IGXTexture2D *m_pAdaptedLuminance[2];
-	UINT m_uCurrAdaptedLuminanceTarget = 0;
-
+	
 	//! Буфер освещения
 	IGXTexture2D *m_pLightTotal = NULL;
 
@@ -121,14 +107,7 @@ protected:
 	} m_frameShaderData;
 	IGXConstantBuffer *m_pFrameShaderData = NULL;
 
-	struct
-	{
-		float fAdaptationSpeed;
-		float fBaseValue;
-		float _padding[2];
-	} m_toneMappingShaderData;
-	IGXConstantBuffer *m_pToneMappingShaderData = NULL;
-
+	
 	struct
 	{
 		/*struct
@@ -144,61 +123,14 @@ protected:
 
 	struct
 	{
-		struct
-		{
-			//SMMATRIX mV;
-			SMMATRIX mVP;
-			float3 vPosCam;
-			SMMATRIX mInvVP;
-		} vs;
-		//float4 vNearFarLayers;
+		SMMATRIX mVP;
+		float3 vPosCam;
+		SMMATRIX mInvVP;
+		SMMATRIX mInvV;
+		float2 vNearFar;
+		float3 vParamProj;
 	} m_cameraShaderData;
-	IGXConstantBuffer *m_pCameraShaderDataVS = NULL;
-	//IGXConstantBuffer *m_pCameraShaderDataPS = NULL;
-
-	struct
-	{
-		struct
-		{
-			float4 vCenterSize[LPV_CASCADES_COUNT]; // xyz: center / size; w: world size of cell in meters
-		} vs;
-		//float4 vNearFarLayers;
-	} m_lpvCentersShaderData;
-	IGXConstantBuffer *m_pLPVcentersShaderData = NULL;
-	IGXConstantBuffer *m_pLPVcurrentCascadeShaderData = NULL;
-
-	struct
-	{
-		struct
-		{
-			SMMATRIX mVP;
-			SMMATRIX mViewInv;
-			float2 vNearFar;
-			float3 vParamProj;
-		} vs;
-		struct
-		{
-			float3 vViewPos;
-		} ps;
-	} m_lightingShaderData;
-	IGXConstantBuffer *m_pLightingShaderDataVS = NULL;
-	IGXConstantBuffer *m_pLightingShaderDataPS = NULL;
-
-	//###################################
-	
-	CShadowCache *m_pShadowCache = NULL;
-
-	struct
-	{
-		struct
-		{
-			SMMATRIX mVP; // dummy
-			SMMATRIX mViewInv;
-			float2 vNearFar;
-			float3 vParamProj;
-		} vs;
-	} m_shadowShaderData;
-	IGXConstantBuffer *m_pShadowShaderDataVS = NULL;
+	IGXConstantBuffer *m_pCameraShaderData = NULL;
 
 	//###################################
 
@@ -261,27 +193,6 @@ protected:
 
 	IGXTexture2D *m_pSceneTexture = NULL;
 
-	//###################################
-	
-	struct LPVcascade
-	{
-		IGXTexture3D *pGIAccumRed = NULL;
-		IGXTexture3D *pGIAccumGreen = NULL;
-		IGXTexture3D *pGIAccumBlue = NULL;
-
-		IGXTexture3D *pGIAccumRed2 = NULL;
-		IGXTexture3D *pGIAccumGreen2 = NULL;
-		IGXTexture3D *pGIAccumBlue2 = NULL;
-	} m_aLPVs[3];
-
-	IGXRenderBuffer *m_pGICubesRB = NULL;
-	UINT m_uGICubesCount = 0;
-	ID m_idGICubesShader = -1;
-
-	ID m_idLightBoundShader = -1;
-	ID m_idLPVPropagateShader = -1;
-	ID m_idLuminanceReductionShader = -1;
-
 	//###################################
 
 	XRenderPassHandler *m_pRenderPassGBuffer = NULL;
diff --git a/source/terrax/terrax.cpp b/source/terrax/terrax.cpp
index a73832effd4129bf0cce73bbcf45588ed7091ddf..4feb12e939907f8127bafc6d198d169896b0cefb 100644
--- a/source/terrax/terrax.cpp
+++ b/source/terrax/terrax.cpp
@@ -235,9 +235,9 @@ public:
 		m_pOldPipeline->resize(uWidth, uHeight, isWindowed);
 	}
 
-	void renderFrame() override
+	void renderFrame(float fDeltaTime) override
 	{
-		m_pOldPipeline->renderFrame();
+		m_pOldPipeline->renderFrame(fDeltaTime);
 		
 		IGXContext *pDXDevice = getDevice()->getThreadContext();
 		pDXDevice->setDepthStencilState(NULL);
@@ -426,7 +426,7 @@ int main(int argc, char **argv)
 	pEngine->getCore()->execCmd("gmode editor");
 	pEngine->getCore()->execCmd("exec ../config_editor.cfg");
 	CRenderPipeline *pPipeline = new CRenderPipeline(Core_GetIXCore());
-	 XInitGuiWindow(false);
+	XInitGuiWindow(false);
 
 	RECT rcTopLeft;
 	GetClientRect(g_hTopLeftWnd, &rcTopLeft);
diff --git a/source/xEngine/Engine.cpp b/source/xEngine/Engine.cpp
index 1277e7c9e84b33ee20c2587af44e63e4d0ca9303..9f13b586665c92b096e9466cd6dcbcf3e7eed19a 100644
--- a/source/xEngine/Engine.cpp
+++ b/source/xEngine/Engine.cpp
@@ -296,7 +296,8 @@ bool CEngine::runFrame()
 
 			Core_PStartSection(PERF_SECTION_RENDER);
 			pRenderContext->getThreadContext()->beginFrame();
-			pRenderPipeline->renderFrame();
+			//! @todo use actual value
+			pRenderPipeline->renderFrame(0.016f);
 			pRenderContext->getThreadContext()->endFrame();
 			Core_PEndSection(PERF_SECTION_RENDER);
 
diff --git a/source/xcommon/IXRenderPipeline.h b/source/xcommon/IXRenderPipeline.h
index 1157676a1478644e539483806b26e886c4bf7f4f..0f73383fba4be1d1ad0eef3dcce0fd54d06535c5 100644
--- a/source/xcommon/IXRenderPipeline.h
+++ b/source/xcommon/IXRenderPipeline.h
@@ -24,7 +24,7 @@ class IXRenderPipeline: public IXUnknown
 public:
 	virtual void resize(UINT uWidth, UINT uHeight, bool isWindowed = true) = 0;
 
-	virtual void renderFrame() = 0;
+	virtual void renderFrame(float fDeltaTime) = 0;
 	virtual void endFrame() = 0;
 	virtual void updateVisibility() = 0;