// Fit shadow camera's ortho frustum to camera frustum private void UpdateShadowCamera(Camera camera, VirtualLight light) { var min = Vector3.Infinity; var max = Vector3.NegativeInfinity; for (var i = 0; i < 8; i++) { var p = light.PointsFrustum[i]; Projector.UnprojectVector(p, camera.projectionMatrix, camera.matrixWorld); p.Apply(light.ShadowCamera.matrixWorldInverse); min.Min(p); min.Max(p); } var ortho = light.ShadowCamera as OrthographicCamera; if (ortho != null) { ortho.left = min.x; ortho.right = max.x; ortho.top = max.y; ortho.bottom = min.y; } else { throw new NotImplementedException("Should this just ignore the perspective version?"); } // can't really fit near/far //shadowCamera.near = _min.z; //shadowCamera.far = _max.z; light.ShadowCamera.UpdateProjectionMatrix(); }
private VirtualLight CreateVirtualLight(Light light, int cascade) { var hasShadow = light as HasShadow; var virtualLight = new VirtualLight(light.Color) { UseOnlyShadow = true, DoesCastShadow = true, ShadowCameraNear = hasShadow.ShadowCameraNear, ShadowCameraFar = hasShadow.ShadowCameraFar, ShadowCameraLeft = hasShadow.ShadowCameraLeft, ShadowCameraRight = hasShadow.ShadowCameraRight, ShadowCameraBottom = hasShadow.ShadowCameraBottom, ShadowCameraTop = hasShadow.ShadowCameraTop, ShadowCameraVisible = hasShadow.ShadowCameraVisible, ShadowDarkness = hasShadow.ShadowDarkness, ShadowBias = hasShadow.ShadowCascadeBias[cascade], ShadowMapWidth = hasShadow.ShadowCascadeWidth[cascade], ShadowMapHeight = hasShadow.ShadowCascadeHeight[cascade], PointsWorld = new List <Vector3>(), PointsFrustum = new List <Vector3>() }; for (var i = 0; i < 8; i++) { virtualLight.PointsWorld.Add(Vector3.Zero); } var nearZ = hasShadow.ShadowCascadeNearZ[cascade]; var farZ = hasShadow.ShadowCascadeFarZ[cascade]; virtualLight.PointsFrustum.Add(new Vector3(-1, -1, nearZ)); virtualLight.PointsFrustum.Add(new Vector3(1, -1, nearZ)); virtualLight.PointsFrustum.Add(new Vector3(-1, 1, nearZ)); virtualLight.PointsFrustum.Add(new Vector3(1, 1, nearZ)); virtualLight.PointsFrustum.Add(new Vector3(-1, -1, farZ)); virtualLight.PointsFrustum.Add(new Vector3(1, -1, farZ)); virtualLight.PointsFrustum.Add(new Vector3(-1, 1, farZ)); virtualLight.PointsFrustum.Add(new Vector3(1, 1, farZ)); return(virtualLight); }