Просмотр исходного кода

Better light grid depth slice distribution

BearishSun 8 лет назад
Родитель
Сommit
f95bf9e749
1 измененных файлов с 23 добавлено и 14 удалено
  1. 23 14
      Data/Raw/Engine/Includes/LightGridCommon.bslinc

+ 23 - 14
Data/Raw/Engine/Includes/LightGridCommon.bslinc

@@ -25,18 +25,28 @@ Technique : base("LightGridCommon") =
 			
 			
 			float calcViewZFromCellZ(uint cellZ)
 			float calcViewZFromCellZ(uint cellZ)
 			{
 			{
-				// TODO - Need better Z distribution. Currently I uniformly distribute in view space, but this
-				// results in very elongated cells along Z
-				float viewZ = gNearFar.x + (gNearFar.y - gNearFar.x) * cellZ / (float)gGridSize.z;
+				// We don't want to subdivide depth uniformly because XY sizes will be much
+				// smaller closer to the near plane, and larger towards far plane. We want 
+				// our cells to be as close to cube shape as possible, so that width/height/depth
+				// are all similar. Ideally we would use either width or height as calculated for
+				// purposes of the projection matrix, for the depth. But since we'll be splitting
+				// the depth range into multiple slices, in practice this ends up with many tiny
+				// cells close to the near plane. Instead we use a square function, which is
+				// somewhere between the two extremes:
+				//  view = slice^2
 				
 				
+				// We need it in range [near, far] so we normalize and scale
+				//  view = slice^2 / maxSlices^2 * (far - near) + near
+				
+				// Note: Some of these calculations could be moved to CPU
+				float viewZ = (pow(cellZ, 2) / pow(gGridSize.z, 2)) * (gNearFar.y - gNearFar.x) + gNearFar.x; 
 				return -viewZ;
 				return -viewZ;
 			}
 			}
 			
 			
 			uint calcCellZFromViewZ(float viewZ)
 			uint calcCellZFromViewZ(float viewZ)
 			{
 			{
-				// TODO - Need better Z distribution. Currently I uniformly distribute in view space, but this
-				// results in very elongated cells along Z
-				uint cellZ = min((gGridSize.z * (-viewZ - gNearFar.x))/(gNearFar.y - gNearFar.x), gGridSize.z);
+				// Inverse of calculation in calcViewZFromCellZ
+				uint cellZ = min((uint)floor(sqrt(((-viewZ - gNearFar.x)*pow(gGridSize.z, 2))/(gNearFar.y - gNearFar.x))), gGridSize.z);
 				
 				
 				return cellZ;
 				return cellZ;
 			}
 			}
@@ -81,18 +91,17 @@ Technique : base("LightGridCommon") =
 			
 			
 			float calcViewZFromCellZ(uint cellZ)
 			float calcViewZFromCellZ(uint cellZ)
 			{
 			{
-				// TODO - Need better Z distribution. Currently I uniformly distribute in view space, but this
-				// results in very elongated cells along Z
-				float viewZ = gNearFar.x + (gNearFar.y - gNearFar.x) * cellZ / float(gGridSize.z);
-				
+				// See HLSL version for reasons behind this formulation
+			
+				// Note: Some of these calculations could be moved to CPU
+				float viewZ = (pow(cellZ, 2) / pow(gGridSize.z, 2)) * (gNearFar.y - gNearFar.x) + gNearFar.x; 
 				return -viewZ;
 				return -viewZ;
 			}
 			}
-						
+			
 			uint calcCellZFromViewZ(float viewZ)
 			uint calcCellZFromViewZ(float viewZ)
 			{
 			{
-				// TODO - Need better Z distribution. Currently I uniformly distribute in view space, but this
-				// results in very elongated cells along Z
-				uint cellZ = min(uint((gGridSize.z * (-viewZ - gNearFar.x))/(gNearFar.y - gNearFar.x)), gGridSize.z);
+				// Inverse of calculation in calcViewZFromCellZ
+				uint cellZ = min(uint(floor(sqrt(((-viewZ - gNearFar.x)*pow(gGridSize.z, 2))/(gNearFar.y - gNearFar.x)))), gGridSize.z);
 				
 				
 				return cellZ;
 				return cellZ;
 			}
 			}