public static DepthReadback GetDepthReadback(RenderContext context) { var sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current); DepthReadback depthReadBack; for (int i = 0; i < sceneCameraRenderer.PostRenderers.Count; i++) { depthReadBack = sceneCameraRenderer.PostRenderers[i] as DepthReadback; if (depthReadBack != null) { return(depthReadBack); } } depthReadBack = new DepthReadback(); sceneCameraRenderer.PostRenderers.Add(depthReadBack); return(depthReadBack); }
public static DepthReadback GetDepthReadback(RenderContext context) { var sceneCameraRenderer = context.Tags.Get(SceneCameraRenderer.Current); DepthReadback depthReadBack; for (int i = 0; i < sceneCameraRenderer.PostRenderers.Count; i++) { depthReadBack = sceneCameraRenderer.PostRenderers[i] as DepthReadback; if (depthReadBack != null) { return depthReadBack; } } depthReadBack = new DepthReadback(); sceneCameraRenderer.PostRenderers.Add(depthReadBack); return depthReadBack; }
private Vector2 ComputeCascadeSplits(RenderContext context, ShadowMapRenderer shadowContext, ref LightShadowMapTexture lightShadowMap) { var shadow = (LightDirectionalShadowMap)lightShadowMap.Shadow; var cameraNear = shadowContext.Camera.NearClipPlane; var cameraFar = shadowContext.Camera.FarClipPlane; var cameraRange = cameraFar - cameraNear; var minDistance = cameraNear + LightDirectionalShadowMap.DepthRangeParameters.DefaultMinDistance; var maxDistance = cameraNear + LightDirectionalShadowMap.DepthRangeParameters.DefaultMaxDistance; if (shadow.DepthRange.IsAutomatic) { var depthReadBack = DepthReadback.GetDepthReadback(context); if (depthReadBack.IsResultAvailable) { var depthMinMax = depthReadBack.DepthMinMax; minDistance = ToLinearDepth(depthMinMax.X, ref shadowContext.Camera.ProjectionMatrix); // Reserve 1/3 of the guard distance for the min distance minDistance = Math.Max(cameraNear, minDistance - shadow.DepthRange.GuardDistance / 3); // Reserve 2/3 of the guard distance for the max distance var guardMaxDistance = minDistance + shadow.DepthRange.GuardDistance * 2 / 3; maxDistance = ToLinearDepth(depthMinMax.Y, ref shadowContext.Camera.ProjectionMatrix); maxDistance = Math.Max(maxDistance, guardMaxDistance); } } else { minDistance = cameraNear + shadow.DepthRange.ManualMinDistance; maxDistance = cameraNear + shadow.DepthRange.ManualMaxDistance; } var manualPartitionMode = shadow.PartitionMode as LightDirectionalShadowMap.PartitionManual; var logarithmicPartitionMode = shadow.PartitionMode as LightDirectionalShadowMap.PartitionLogarithmic; if (logarithmicPartitionMode != null) { var minZ = minDistance; var maxZ = maxDistance; var range = maxZ - minZ; var ratio = maxZ / minZ; var logRatio = MathUtil.Clamp(1.0f - logarithmicPartitionMode.PSSMFactor, 0.0f, 1.0f); for (int cascadeLevel = 0; cascadeLevel < lightShadowMap.CascadeCount; ++cascadeLevel) { // Compute cascade split (between znear and zfar) float distrib = (float)(cascadeLevel + 1) / lightShadowMap.CascadeCount; float logZ = (float)(minZ * Math.Pow(ratio, distrib)); float uniformZ = minZ + range * distrib; float distance = MathUtil.Lerp(uniformZ, logZ, logRatio); cascadeSplitRatios[cascadeLevel] = distance; } } else if (manualPartitionMode != null) { if (lightShadowMap.CascadeCount == 1) { cascadeSplitRatios[0] = minDistance + manualPartitionMode.SplitDistance1 * maxDistance; } else if (lightShadowMap.CascadeCount == 2) { cascadeSplitRatios[0] = minDistance + manualPartitionMode.SplitDistance1 * maxDistance; cascadeSplitRatios[1] = minDistance + manualPartitionMode.SplitDistance3 * maxDistance; } else if (lightShadowMap.CascadeCount == 4) { cascadeSplitRatios[0] = minDistance + manualPartitionMode.SplitDistance0 * maxDistance; cascadeSplitRatios[1] = minDistance + manualPartitionMode.SplitDistance1 * maxDistance; cascadeSplitRatios[2] = minDistance + manualPartitionMode.SplitDistance2 * maxDistance; cascadeSplitRatios[3] = minDistance + manualPartitionMode.SplitDistance3 * maxDistance; } } // Convert distance splits to ratios cascade in the range [0, 1] for (int i = 0; i < cascadeSplitRatios.Length; i++) { cascadeSplitRatios[i] = (cascadeSplitRatios[i] - cameraNear) / cameraRange; } return(new Vector2(minDistance, maxDistance)); }