Ejemplo n.º 1
0
        public void Initialize(RenderView renderView, RenderLight renderLight, IDirectLight light, LightShadowMap shadowMap, int size, ILightShadowMapRenderer renderer)
        {
            if (renderView == null)
            {
                throw new ArgumentNullException(nameof(renderView));
            }
            if (renderLight == null)
            {
                throw new ArgumentNullException(nameof(renderLight));
            }
            if (light == null)
            {
                throw new ArgumentNullException(nameof(light));
            }
            if (shadowMap == null)
            {
                throw new ArgumentNullException(nameof(shadowMap));
            }
            if (renderer == null)
            {
                throw new ArgumentNullException(nameof(renderer));
            }

            RenderView   = renderView;
            RenderLight  = renderLight;
            Light        = light;
            Shadow       = shadowMap;
            Size         = size;
            FilterType   = Shadow.Filter == null || !Shadow.Filter.RequiresCustomBuffer() ? null : Shadow.Filter.GetType();
            Renderer     = renderer;
            Atlas        = null; // Reset the atlas, It will be setup after
            CascadeCount = 1;

            ShadowType = renderer.GetShadowType(Shadow);
        }
Ejemplo n.º 2
0
        protected override void OnSceneManagementGetObjectsForShadowGeneration( Camera camera,
			RenderLight light, Set<SceneNode> outSceneNodes,
			Set<StaticMeshObject> outStaticMeshObjects )
        {
            float farClipDistance = NearFarClipDistance.Maximum;

            LowLevelSceneManagement.WalkForShadowGeneration( camera, light, farClipDistance,
                outSceneNodes, outStaticMeshObjects );
        }
Ejemplo n.º 3
0
        public LightShadowMapTexture FindShadowMap(RenderView renderView, RenderLight light)
        {
            foreach (var shadowMap in shadowMaps)
            {
                if (shadowMap.RenderView == renderView && shadowMap.RenderLight == light)
                {
                    return(shadowMap);
                }
            }

            return(null);
        }
        public static void WalkForShadowGeneration( Camera camera, RenderLight light,
            float farClipDistance, Set<SceneNode> outSceneNodes,
            Set<StaticMeshObject> outStaticMeshObjects)
        {
            switch( light.Type )
            {
            case RenderLightType.Spot:
                WalkSpotLightShadowGeneration( camera, light, outSceneNodes,
                    outStaticMeshObjects );
                break;

            case RenderLightType.Point:
                WalkPointLightShadowGeneration( camera, light, outSceneNodes,
                    outStaticMeshObjects );
                break;

            case RenderLightType.Directional:
                WalkDirectionalLightShadowGeneration( camera, light, farClipDistance,
                    outSceneNodes, outStaticMeshObjects );
                break;
            }
        }
Ejemplo n.º 5
0
        void GetShadowCastersForLight( Camera mainCamera, RenderLight light, int directionalLightPSSMTextureIndex,
			Vec3 pointLightFaceDirection, List<SceneNode> outSceneNodes, List<StaticMeshObject> outStaticMeshObjects )
        {
            switch( light.Type )
            {
            case RenderLightType.Spot:
                WalkSpotLightShadowGeneration( mainCamera, light, outSceneNodes, outStaticMeshObjects );
                break;

            case RenderLightType.Point:
                WalkPointLightShadowGeneration( mainCamera, light, pointLightFaceDirection,
                    outSceneNodes, outStaticMeshObjects );
                break;

            case RenderLightType.Directional:
                WalkDirectionalLightShadowGeneration( mainCamera, light,
                    directionalLightPSSMTextureIndex, outSceneNodes, outStaticMeshObjects );
                break;
            }
        }
Ejemplo n.º 6
0
 public bool Update(RenderLight light) => true;
Ejemplo n.º 7
0
        public virtual LightShadowMapTexture CreateShadowMapTexture(RenderView renderView, RenderLight renderLight, IDirectLight light, int shadowMapSize)
        {
            var shadowMap = shadowMaps.Add();

            shadowMap.Initialize(renderView, renderLight, light, light.Shadow, shadowMapSize, this);
            return(shadowMap);
        }
Ejemplo n.º 8
0
        static bool IsIntersects( RenderLight light, Bounds bounds )
        {
            if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot )
            {
                //check by bounding sphere
                {
                    Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar );
                    if( !lightSphere.IsIntersectsBounds( ref bounds ) )
                        return false;
                }

                //check by spot light clip planes
                if( light.Type == RenderLightType.Spot )
                {
                    Vec3 boundsCenter = bounds.GetCenter();
                    Vec3 boundsHalfSize = boundsCenter - bounds.Minimum;

                    foreach( Plane plane in light.SpotLightClipPlanes )
                    {
                        if( plane.GetSide( ref boundsCenter, ref boundsHalfSize ) == Plane.Side.Positive )
                            return false;
                    }
                }
            }

            return true;
        }
Ejemplo n.º 9
0
        static Plane[] GetClipPlanesForPointLightShadowGeneration( Camera mainCamera,
			RenderLight light, Vec3 pointLightFaceDirection )
        {
            Plane[] clipPlanes = new Plane[ 5 ];

            Vec3 direction = pointLightFaceDirection;

            float attenuationRange = light.AttenuationFar;

            Vec3[] points = new Vec3[ 4 ];

            if( direction.Equals( Vec3.XAxis, .01f ) )
            {
                points[ 0 ] = new Vec3( 1, -1, -1 );
                points[ 1 ] = new Vec3( 1, -1, 1 );
                points[ 2 ] = new Vec3( 1, 1, 1 );
                points[ 3 ] = new Vec3( 1, 1, -1 );
                clipPlanes[ 4 ] = new Plane( direction, light.Position.X + attenuationRange );
            }
            else if( direction.Equals( -Vec3.XAxis, .01f ) )
            {
                points[ 0 ] = new Vec3( -1, 1, -1 );
                points[ 1 ] = new Vec3( -1, 1, 1 );
                points[ 2 ] = new Vec3( -1, -1, 1 );
                points[ 3 ] = new Vec3( -1, -1, -1 );
                clipPlanes[ 4 ] = new Plane( direction, -( light.Position.X - attenuationRange ) );
            }
            else if( direction.Equals( Vec3.YAxis, .01f ) )
            {
                points[ 0 ] = new Vec3( 1, 1, -1 );
                points[ 1 ] = new Vec3( 1, 1, 1 );
                points[ 2 ] = new Vec3( -1, 1, 1 );
                points[ 3 ] = new Vec3( -1, 1, -1 );
                clipPlanes[ 4 ] = new Plane( direction, light.Position.Y + attenuationRange );
            }
            else if( direction.Equals( -Vec3.YAxis, .01f ) )
            {
                points[ 0 ] = new Vec3( -1, -1, -1 );
                points[ 1 ] = new Vec3( -1, -1, 1 );
                points[ 2 ] = new Vec3( 1, -1, 1 );
                points[ 3 ] = new Vec3( 1, -1, -1 );
                clipPlanes[ 4 ] = new Plane( direction, -( light.Position.Y - attenuationRange ) );
            }
            else if( direction.Equals( Vec3.ZAxis, .01f ) )
            {
                points[ 0 ] = new Vec3( -1, 1, 1 );
                points[ 1 ] = new Vec3( 1, 1, 1 );
                points[ 2 ] = new Vec3( 1, -1, 1 );
                points[ 3 ] = new Vec3( -1, -1, 1 );
                clipPlanes[ 4 ] = new Plane( direction, light.Position.Z + attenuationRange );
            }
            else if( direction.Equals( -Vec3.ZAxis, .01f ) )
            {
                points[ 0 ] = new Vec3( -1, -1, -1 );
                points[ 1 ] = new Vec3( 1, -1, -1 );
                points[ 2 ] = new Vec3( 1, 1, -1 );
                points[ 3 ] = new Vec3( -1, 1, -1 );
                clipPlanes[ 4 ] = new Plane( direction, -( light.Position.Z - attenuationRange ) );
            }
            else
            {
                Log.Fatal( "MyRenderingLowLevelMethods: GetClipPlanesForPointLightShadowGeneration: Internal error." );
            }

            for( int n = 0; n < 4; n++ )
            {
                clipPlanes[ n ] = Plane.FromPoints( light.Position,
                    light.Position + points[ n ], light.Position + points[ ( n + 1 ) % 4 ] );
            }

            return clipPlanes;
        }
Ejemplo n.º 10
0
        public override void OnGetShadowmapCameraSetup( Camera mainCamera, RenderLight light,
			int directionalLightPSSMTextureIndex, int pointLightFaceIndex, Camera lightCamera,
			ref bool skipThisShadowmap )
        {
            if( light.Type == RenderLightType.Directional )
            {
                //Directional light

                float orthoWindowSize;
                Vec3 lightCameraPosition;
                Vec3 lightCameraUp;

                Vec3[] cornerPoints;
                {
                    if( SceneManager.Instance.IsShadowTechniquePSSM() )
                    {
                        float[] splitDistances = SceneManager.Instance.ShadowDirectionalLightSplitDistances;

                        float nearSplitDistance = splitDistances[ directionalLightPSSMTextureIndex ];
                        float farSplitDistance = splitDistances[ directionalLightPSSMTextureIndex + 1 ];
                        bool lastTextureIndex = directionalLightPSSMTextureIndex ==
                            SceneManager.Instance.ShadowDirectionalLightSplitTextureCount - 1;

                        GetDirectionalLightCameraCornerPoints( mainCamera, nearSplitDistance, farSplitDistance,
                            lastTextureIndex, out cornerPoints );
                    }
                    else
                    {
                        GetDirectionalLightCameraCornerPoints( mainCamera, mainCamera.NearClipDistance,
                            SceneManager.Instance.ShadowFarDistance, true, out cornerPoints );
                    }
                }

                Vec3 destinationPoint = GetDirectionalLightCameraDestinationPoint( mainCamera, cornerPoints );

                lightCameraPosition = destinationPoint - light.Direction * directionalLightExtrusionDistance;

                lightCameraUp = Vec3.ZAxis;
                if( Math.Abs( Vec3.Dot( lightCameraUp, light.Direction ) ) >= .99f )
                    lightCameraUp = Vec3.YAxis;

                float maxDistance = 0;
                {
                    foreach( Vec3 point in cornerPoints )
                    {
                        float distance = ( point - destinationPoint ).Length();
                        if( distance > maxDistance )
                            maxDistance = distance;
                    }
                }

                orthoWindowSize = maxDistance * 2 * 1.05f;
                //fix epsilon error
                orthoWindowSize = ( (int)( orthoWindowSize / 5 ) ) * 5 + 5;

                //fix jittering
                {
                    Quat lightRotation = Quat.FromDirectionZAxisUp( light.Direction );

                    //convert world space camera position into light space
                    Vec3 lightSpacePos = lightRotation.GetInverse() * lightCameraPosition;

                    //snap to nearest texel
                    float textureSize = SceneManager.Instance.ShadowDirectionalLightTextureSize;
                    float worldTexelSize = orthoWindowSize / textureSize;
                    lightSpacePos.Y -= (float)Math.IEEERemainder( lightSpacePos.Y, worldTexelSize );
                    lightSpacePos.Z -= (float)Math.IEEERemainder( lightSpacePos.Z, worldTexelSize );

                    //convert back to world space
                    lightCameraPosition = lightRotation * lightSpacePos;
                }

                lightCamera.ProjectionType = ProjectionTypes.Orthographic;
                lightCamera.AspectRatio = 1;
                lightCamera.OrthoWindowHeight = orthoWindowSize;
                lightCamera.NearClipDistance = mainCamera.NearClipDistance;
                lightCamera.FarClipDistance = shadowMapFarClipDistance;
                lightCamera.Position = lightCameraPosition;
                lightCamera.FixedUp = lightCameraUp;
                lightCamera.Direction = light.Direction;
            }
            else if( light.Type == RenderLightType.Spot )
            {
                //Spot light

                Degree fov = new Radian( light.SpotlightOuterAngle * 1.05f ).InDegrees();
                if( fov > 179 )
                    fov = 179;

                Vec3 up = Vec3.ZAxis;
                if( Math.Abs( Vec3.Dot( up, light.Direction ) ) >= 1.0f )
                    up = Vec3.YAxis;

                lightCamera.ProjectionType = ProjectionTypes.Perspective;
                lightCamera.AspectRatio = 1;
                lightCamera.Fov = fov;
                lightCamera.NearClipDistance = mainCamera.NearClipDistance;
                lightCamera.FarClipDistance = shadowMapFarClipDistance;// light.AttenuationFar * 1.05f;
                lightCamera.Position = light.Position;
                lightCamera.FixedUp = up;
                lightCamera.Direction = light.Direction;
            }
            else
            {
                //Point light

                //you can completely skip specified faces for better performance.
                //use "skipThisShadowmap" parameter for this.
                //example:
                //if( pointLightFaceIndex == 3 )
                //   skipThisShadowmap = true;

                Vec3 dir = Vec3.Zero;
                Vec3 up = Vec3.Zero;

                switch( pointLightFaceIndex )
                {
                case 0: dir = -Vec3.YAxis; up = Vec3.ZAxis; break;
                case 1: dir = Vec3.YAxis; up = Vec3.ZAxis; break;
                case 2: dir = Vec3.ZAxis; up = -Vec3.XAxis; break;
                case 3: dir = -Vec3.ZAxis; up = Vec3.XAxis; break;
                case 4: dir = Vec3.XAxis; up = Vec3.ZAxis; break;
                case 5: dir = -Vec3.XAxis; up = Vec3.ZAxis; break;
                }

                lightCamera.ProjectionType = ProjectionTypes.Perspective;
                lightCamera.AspectRatio = 1;
                lightCamera.Fov = 90;
                lightCamera.NearClipDistance = mainCamera.NearClipDistance;
                lightCamera.FarClipDistance = shadowMapFarClipDistance;// light.AttenuationFar * 1.05f;
                lightCamera.Position = light.Position;
                lightCamera.FixedUp = up;
                lightCamera.Direction = dir;
            }
        }
        static Plane[] GetClipPlanesForDirectionalLightShadowGeneration( Camera camera,
            RenderLight light, float farClipDistance)
        {
            float shadowFarDistance = SceneManager.Instance.ShadowFarDistance;

            Frustum cameraFrustum = FrustumUtils.GetFrustumByCamera( camera, farClipDistance );

            Vec3 cameraPosition = cameraFrustum.Origin;

            Vec3 farCenterPoint;
            {
                float distance = shadowFarDistance;
                //small border
                distance *= 1.05f;

                //not optimal
                distance *= MathFunctions.Sqrt( 2 );

                farCenterPoint = cameraPosition + cameraFrustum.Axis.Item0 * distance;
            }
            Vec3 pyramidCenter = ( cameraPosition + farCenterPoint ) * .5f;

            Plane farPlane;
            {
                Vec3 normal = ( farCenterPoint - cameraPosition ).GetNormalize();
                float distance = Vec3.Dot( normal, farCenterPoint );
                farPlane = new Plane( normal, distance );
            }

            Vec3[] farCorners = new Vec3[ 4 ];
            {
                //4 - top-right far, 5 - top-left far, 6 - bottom-left far, 7 - bottom-right far.
                Vec3[] points = camera.GetWorldSpaceCorners();

                for( int n = 0; n < 4; n++ )
                {
                    Ray ray = new Ray( cameraPosition, points[ n + 4 ] - cameraPosition );
                    float scale;
                    farPlane.RayIntersection( ray, out scale );
                    farCorners[ n ] = ray.GetPointOnRay( scale );
                }
            }

            Vec3[] pyramidPoints = new Vec3[ 5 ];
            {
                pyramidPoints[ 0 ] = cameraPosition;
                for( int n = 0; n < 4; n++ )
                    pyramidPoints[ n + 1 ] = farCorners[ n ];
            }

            Line[] pyramidEdges = new Line[ 8 ];
            {
                for( int n = 0; n < 4; n++ )
                {
                    pyramidEdges[ n ] = new Line( cameraPosition, farCorners[ n ] );
                    pyramidEdges[ n + 4 ] = new Line( farCorners[ n ],
                        farCorners[ ( n + 1 ) % 4 ] );
                }
            }

            List<Plane> clipPlanes = new List<Plane>( 7 );
            {
                Vec3 lightDirectionOffset = light.Direction * 10000.0f;

                //back planes
                {
                    if( farPlane.GetSide( farCenterPoint - lightDirectionOffset ) ==
                        Plane.Side.Negative )
                    {
                        clipPlanes.Add( farPlane );
                    }

                    for( int n = 0; n < 4; n++ )
                    {
                        Plane plane = Plane.FromPoints( cameraPosition, farCorners[ n ],
                            farCorners[ ( n + 1 ) % 4 ] );

                        if( plane.GetSide( cameraPosition - lightDirectionOffset ) ==
                            Plane.Side.Negative )
                        {
                            clipPlanes.Add( farPlane );
                        }
                    }
                }

                //generate edge planes
                foreach( Line pyramidEdge in pyramidEdges )
                {
                    Vec3 p1 = pyramidEdge.Start;
                    Vec3 p2 = pyramidEdge.End;
                    Vec3 p3 = p1 - lightDirectionOffset;

                    Plane plane;
                    {
                        plane = Plane.FromPoints( p1, p2, p3 );
                        if( plane.GetSide( pyramidCenter ) == Plane.Side.Positive )
                            plane = Plane.FromPoints( p2, p1, p3 );
                    }

                    bool existsPyramidPointsOnBothSides = false;
                    {
                        Plane.Side side = Plane.Side.No;
                        bool sideInitialized = false;

                        foreach( Vec3 pyramidPoint in pyramidPoints )
                        {
                            if( pyramidPoint.Equals( pyramidEdge.Start, .00001f ) )
                                continue;
                            if( pyramidPoint.Equals( pyramidEdge.End, .00001f ) )
                                continue;

                            Plane.Side s = plane.GetSide( pyramidPoint );

                            if( sideInitialized )
                            {
                                if( side == Plane.Side.Negative && s == Plane.Side.Positive ||
                                    side == Plane.Side.Positive && s == Plane.Side.Negative )
                                {
                                    existsPyramidPointsOnBothSides = true;
                                    break;
                                }
                            }
                            else
                            {
                                side = s;
                                sideInitialized = true;
                            }
                        }
                    }
                    if( existsPyramidPointsOnBothSides )
                        continue;

                    clipPlanes.Add( plane );
                }
            }

            return clipPlanes.ToArray();
        }
        static void WalkSpotLightShadowGeneration( Camera camera, RenderLight light,
            Set<SceneNode> outSceneNodes, Set<StaticMeshObject> outStaticMeshObjects)
        {
            Plane[] clipPlanes = GetClipPlanesForSpotLightShadowGeneration( camera, light );
            Sphere clipSphere = new Sphere( light.Position, light.AttenuationRange );

            SceneManager.Instance._SceneGraph.GetObjects( clipPlanes,
                _SceneObjectGroups.SceneNode | _SceneObjectGroups.StaticMeshObject,
                delegate( _ISceneObject sceneObject )
                {
                    //clip by sphere
                    if( !clipSphere.IsIntersectsBounds( sceneObject._SceneData.Bounds ) )
                        return;

                    _SceneObjectGroups objGroups = sceneObject._SceneData.Groups;

                    //StaticMeshObject
                    if( ( objGroups & _SceneObjectGroups.StaticMeshObject ) != 0 )
                    {
                        StaticMeshObject staticMeshObject = (StaticMeshObject)sceneObject;

                        if( !staticMeshObject.Visible )
                            return;
                        if( !staticMeshObject.CastShadows )
                            return;

                        outStaticMeshObjects.Add( staticMeshObject );
                        return;
                    }

                    //SceneNode
                    if( ( objGroups & _SceneObjectGroups.SceneNode ) != 0 )
                    {
                        SceneNode sceneNode = (SceneNode)sceneObject;

                        if( !sceneNode.Visible )
                            return;
                        //if( !x.CastShadows )
                        //{
                        //   can be optimized
                        //}
                        outSceneNodes.Add( sceneNode );
                        return;
                    }

                    Log.Fatal( "InternalSceneManagement: WalkSpotLightShadowGeneration: invalid sceneObject." );
                } );
        }
        static void WalkPointLightShadowGeneration( Camera camera, RenderLight light,
            Set<SceneNode> outSceneNodes, Set<StaticMeshObject> outStaticMeshObjects)
        {
            //not optimal. need consider camera frustum.

            float range = light.AttenuationRange;
            if( range >= 10000.0f )
                range = 10000.0f;
            Sphere sphere = new Sphere( light.Position, range );

            SceneManager.Instance._SceneGraph.GetObjects( ref sphere,
                _SceneObjectGroups.SceneNode | _SceneObjectGroups.StaticMeshObject,
                delegate( _ISceneObject sceneObject )
                {
                    _SceneObjectGroups objGroups = sceneObject._SceneData.Groups;

                    //StaticMeshObject
                    if( ( objGroups & _SceneObjectGroups.StaticMeshObject ) != 0 )
                    {
                        StaticMeshObject staticMeshObject = (StaticMeshObject)sceneObject;

                        if( !staticMeshObject.Visible )
                            return;
                        if( !staticMeshObject.CastShadows )
                            return;
                        outStaticMeshObjects.Add( staticMeshObject );
                        return;
                    }

                    //SceneNode
                    if( ( objGroups & _SceneObjectGroups.SceneNode ) != 0 )
                    {
                        SceneNode sceneNode = (SceneNode)sceneObject;

                        if( !sceneNode.Visible )
                            return;
                        //if( !x.CastShadows )
                        //{
                        //   can be optimized
                        //}
                        outSceneNodes.Add( sceneNode );
                        return;
                    }

                    Log.Fatal( "InternalSceneManagement: WalkPointLightShadowGeneration: invalid sceneObject." );
                } );
        }
        static void WalkDirectionalLightShadowGeneration( Camera camera, RenderLight light,
            float farClipDistance, Set<SceneNode> outSceneNodes,
            Set<StaticMeshObject> outStaticMeshObjects)
        {
            Plane[] clipPlanes = GetClipPlanesForDirectionalLightShadowGeneration( camera,
                light, farClipDistance );

            SceneManager.Instance._SceneGraph.GetObjects( clipPlanes,
                _SceneObjectGroups.SceneNode | _SceneObjectGroups.StaticMeshObject,
                delegate( _ISceneObject sceneObject )
                {
                    _SceneObjectGroups objGroups = sceneObject._SceneData.Groups;

                    //StaticMeshObject
                    if( ( objGroups & _SceneObjectGroups.StaticMeshObject ) != 0 )
                    {
                        StaticMeshObject staticMeshObject = (StaticMeshObject)sceneObject;

                        if( !staticMeshObject.Visible )
                            return;
                        if( !staticMeshObject.CastShadows )
                            return;
                        outStaticMeshObjects.Add( staticMeshObject );
                        return;
                    }

                    //SceneNode
                    if( ( objGroups & _SceneObjectGroups.SceneNode ) != 0 )
                    {
                        SceneNode sceneNode = (SceneNode)sceneObject;

                        if( !sceneNode.Visible )
                            return;
                        //if( !x.CastShadows )
                        //{
                        //   can be optimized
                        //}
                        outSceneNodes.Add( sceneNode );
                        return;
                    }

                    Log.Fatal( "InternalSceneManagement: WalkDirectionalLightShadowGeneration: invalid sceneObject." );
                } );
        }
        static Plane[] GetClipPlanesForSpotLightShadowGeneration( Camera camera, RenderLight light )
        {
            Quat rotation = Quat.FromDirectionZAxisUp( light.Direction );

            Plane[] clipPlanes = new Plane[ 9 ];

            //side planes
            Plane[] sideClipPlanes = light.GetSpotSideClipPlanes();
            for( int n = 0; n < 8; n++ )
                clipPlanes[ n ] = sideClipPlanes[ n ];

            //far plane
            float range = light.AttenuationRange;
            if( range > 10000 )
                range = 10000;
            Vec3 dir1 = rotation * Vec3.YAxis;
            Vec3 dir2 = rotation * Vec3.ZAxis;
            Vec3 p = light.Position + light.Direction * range;
            clipPlanes[ 8 ] = Plane.FromVectors( dir1, dir2, p );

            return clipPlanes;
        }
Ejemplo n.º 16
0
        //static bool IsIntersects( RenderLight light, Sphere boundingSphere )
        //{
        //   if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot )
        //   {
        //      //check by bounding sphere
        //      {
        //         float range = light.AttenuationFar;
        //         Sphere lightSphere = new Sphere( light.Position, range );
        //         if( !lightSphere.IsIntersectsSphere( ref boundingSphere ) )
        //            return false;
        //      }
        //      //check by spot light clip planes
        //      if( light.Type == RenderLightType.Spot )
        //      {
        //         foreach( Plane plane in light.SpotLightClipPlanes )
        //         {
        //            if( plane.GetDistance( boundingSphere.Origin ) > boundingSphere.Radius )
        //               return false;
        //         }
        //      }
        //   }
        //   return true;
        //}
        public override void OnSceneManagementGetAffectingLightsForObject( Camera camera,
			RenderLight[] affectingLights, StaticMeshObject staticMeshObject )
        {
            if( tempLightArray.Length != affectingLights.Length )
                tempLightArray = new RenderLight[ affectingLights.Length ];

            int count = 0;

            foreach( RenderLight light in affectingLights )
            {
                if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot )
                {
                    if( !IsIntersects( light, staticMeshObject.Bounds ) )
                        continue;
                }

                tempLightArray[ count ] = light;
                count++;
            }

            staticMeshObject.SetAffectingLights( tempLightArray, count );
        }
		static ConvexPolyhedron MakeConvexPolyhedronForPointLight( RenderLight light )
		{
			float radius = light.AttenuationFar;
			radius /= MathFunctions.Cos( MathFunctions.PI * 2.0f / 32.0f );

			Vec3[] vertices;
			int[] indices;
			GeometryGenerator.GenerateSphere( radius, 8, 8, false, out vertices, out indices );

			for( int n = 0; n < vertices.Length; n++ )
				vertices[ n ] = light.Position + vertices[ n ];

			return new ConvexPolyhedron( vertices, indices, .0001f );
		}
Ejemplo n.º 18
0
        public override void OnSceneManagementGetAffectingLightsForObject( Camera camera,
			RenderLight[] affectingLights, SceneNode sceneNode )
        {
            if( tempLightArray.Length != affectingLights.Length )
                tempLightArray = new RenderLight[ affectingLights.Length ];

            int count = 0;

            foreach( RenderLight light in affectingLights )
            {
                //Sphere boundingSphere = new Sphere( sceneNode.Position, 0 );
                //{
                //   for( int n = 0; n < sceneNode.MovableObjects.Count; n++ )
                //   {
                //      MovableObject movableObject = sceneNode.MovableObjects[ n ];

                //      float radius = movableObject._GetBoundingRadius();
                //      if( radius > boundingSphere.Radius )
                //         boundingSphere.Radius = radius;
                //   }
                //}

                if( light.Type == RenderLightType.Point || light.Type == RenderLightType.Spot )
                {
                    Bounds bounds;
                    sceneNode.GetWorldBounds( out bounds );
                    if( !IsIntersects( light, bounds ) )
                        continue;
                }

                tempLightArray[ count ] = light;
                count++;
            }

            sceneNode.SetAffectingLights( tempLightArray, count );
        }
		static ConvexPolyhedron MakeConvexPolyhedronForSpotLight( RenderLight light )
		{
			float outerAngle = light.SpotlightOuterAngle;
			if( outerAngle < new Degree( 1 ).InRadians() )
				outerAngle = new Degree( 1 ).InRadians();
			if( outerAngle > new Degree( 179 ).InRadians() )
				outerAngle = new Degree( 179 ).InRadians();

			List<Vec3> vertices = new List<Vec3>( 10 );
			List<ConvexPolyhedron.Face> faces = new List<ConvexPolyhedron.Face>( 16 );

			Mat3 worldRotation = Quat.FromDirectionZAxisUp( light.Direction ).ToMat3();

			float sideAngle;
			{
				float radius = MathFunctions.Sin( outerAngle / 2 ) * light.AttenuationFar;

				float l = MathFunctions.Sqrt( light.AttenuationFar * light.AttenuationFar - radius * radius );
				radius /= MathFunctions.Cos( MathFunctions.PI * 2 / 16 );

				sideAngle = MathFunctions.ATan( radius / l );
			}

			Vec3 farPoint;
			{
				Mat3 pointRotation = worldRotation * Mat3.FromRotateByY( outerAngle / 4 );
				Vec3 direction = pointRotation * Vec3.XAxis;
				Vec3 point = light.Position + direction * light.AttenuationFar;

				Plane plane = Plane.FromPointAndNormal( point, direction );
				Ray ray = new Ray( light.Position, light.Direction * light.AttenuationFar );

				float scale;
				plane.RayIntersection( ray, out scale );
				farPoint = ray.GetPointOnRay( scale * 1.05f );
			}

			vertices.Add( light.Position );
			vertices.Add( farPoint );

			for( int nAxisAngle = 0; nAxisAngle < 8; nAxisAngle++ )
			{
				float axisAngle = ( MathFunctions.PI * 2 ) * ( (float)nAxisAngle / 8 );

				Mat3 worldAxisRotation = worldRotation * Mat3.FromRotateByX( axisAngle );

				Plane sidePlane;
				{
					Mat3 sideAngleRotation = Mat3.FromRotateByY( sideAngle + MathFunctions.PI / 2 );
					Mat3 pointRotation = worldAxisRotation * sideAngleRotation;
					sidePlane = Plane.FromPointAndNormal( light.Position, pointRotation * Vec3.XAxis );
				}

				{
					Mat3 pointRotation = worldAxisRotation * Mat3.FromRotateByY( outerAngle / 4 );
					Vec3 direction = pointRotation * Vec3.XAxis;
					Vec3 point = light.Position + direction * ( light.AttenuationFar * 1.05f );

					Ray ray = new Ray( farPoint, point - farPoint );

					float scale;
					sidePlane.RayIntersection( ray, out scale );
					Vec3 p = ray.GetPointOnRay( scale );

					vertices.Add( p );
				}
			}

			for( int n = 0; n < 8; n++ )
			{
				faces.Add( new ConvexPolyhedron.Face( 0, n + 2, ( n + 1 ) % 8 + 2 ) );
				faces.Add( new ConvexPolyhedron.Face( 1, ( n + 1 ) % 8 + 2, n + 2 ) );
			}

			//foreach( ConvexPolyhedron.Face face in faces )
			//{
			//   camera.DebugGeometry.Color = new ColorValue( 0, 0, 1 );
			//   Vec3 p0 = vertices[ face.Vertex0 ];
			//   Vec3 p1 = vertices[ face.Vertex1 ];
			//   Vec3 p2 = vertices[ face.Vertex2 ];
			//   camera.DebugGeometry.AddLine( p0, p1 );
			//   camera.DebugGeometry.AddLine( p1, p2 );
			//   camera.DebugGeometry.AddLine( p2, p0 );

			//   Vec3[] v = new Vec3[ 3 ] { p0, p1, p2 };
			//   int[] i = new int[] { 0, 1, 2 };
			//   camera.DebugGeometry.Color = new ColorValue( 0, 0, 1, .5f );
			//   camera.DebugGeometry.AddVertexIndexBuffer( v, i, Mat4.Identity, false, true );
			//}
			//camera.DebugGeometry.Color = new ColorValue( 1, 0, 0 );
			//foreach( Vec3 vertex in vertices )
			//   camera.DebugGeometry.AddSphere( new Sphere( vertex, .1f ) );

			return new ConvexPolyhedron( vertices.ToArray(), faces.ToArray(), .0001f );
		}
Ejemplo n.º 20
0
        static Plane[] GetClipPlanesForDirectionalLightShadowGeneration( Camera mainCamera,
			RenderLight light, int pssmTextureIndex )
        {
            Frustum mainFrustum = FrustumUtils.GetFrustumByCamera( mainCamera );
            if( EngineDebugSettings.FrustumTest && mainCamera.AllowFrustumTestMode )
            {
                mainFrustum.HalfWidth *= .5f;
                mainFrustum.HalfHeight *= .5f;
            }

            if( SceneManager.Instance.IsShadowTechniquePSSM() )
            {
                float[] splitDistances = SceneManager.Instance.ShadowDirectionalLightSplitDistances;

                float nearSplitDistance = splitDistances[ pssmTextureIndex ];
                float farSplitDistance = splitDistances[ pssmTextureIndex + 1 ];

                const float splitPadding = 1;

                float splitCount = splitDistances.Length - 1;
                if( pssmTextureIndex > 0 )
                    nearSplitDistance -= splitPadding;
                if( pssmTextureIndex < splitCount - 1 )
                    farSplitDistance += splitPadding;

                if( nearSplitDistance < mainCamera.NearClipDistance )
                    nearSplitDistance = mainCamera.NearClipDistance;
                if( farSplitDistance <= nearSplitDistance + .001f )
                    farSplitDistance = nearSplitDistance + .001f;

                mainFrustum.NearDistance = nearSplitDistance;
                mainFrustum.MoveFarDistance( farSplitDistance );
            }
            else
            {
                if( SceneManager.Instance.ShadowFarDistance > mainFrustum.NearDistance )
                    mainFrustum.MoveFarDistance( SceneManager.Instance.ShadowFarDistance );
            }

            List<Plane> clipPlanes = new List<Plane>( 64 );

            {
                Quat lightRotation = Quat.FromDirectionZAxisUp( light.Direction );

                Vec3[] frustumPoints = null;
                mainFrustum.ToPoints( ref frustumPoints );

                Vec3 frustumCenterPoint;
                {
                    frustumCenterPoint = Vec3.Zero;
                    foreach( Vec3 point in frustumPoints )
                        frustumCenterPoint += point;
                    frustumCenterPoint /= frustumPoints.Length;
                }

                //calculate frustum points projected to 2d from light direction.
                Vec2[] projectedFrustumPoints = new Vec2[ frustumPoints.Length ];
                {
                    //Quat invertFrustumAxis = lightCameraFrustum.Rotation.GetInverse();
                    Quat lightRotationInv = lightRotation.GetInverse();
                    Vec3 translate = frustumCenterPoint - light.Direction * 1000;

                    for( int n = 0; n < frustumPoints.Length; n++ )
                    {
                        Vec3 point = frustumPoints[ n ] - translate;
                        Vec3 localPoint = lightRotationInv * point;
                        projectedFrustumPoints[ n ] = new Vec2( localPoint.Y, localPoint.Z );
                    }
                }

                int[] edges = ConvexPolygon.GetFromPoints( projectedFrustumPoints, .001f );

                for( int n = 0; n < edges.Length; n++ )
                {
                    Vec3 point1 = frustumPoints[ edges[ n ] ];
                    Vec3 point2 = frustumPoints[ edges[ ( n + 1 ) % edges.Length ] ];

                    Plane plane = Plane.FromVectors( light.Direction,
                        ( point2 - point1 ).GetNormalize(), point1 );

                    clipPlanes.Add( plane );
                }
            }

            //add main frustum clip planes
            {
                foreach( Plane plane in mainFrustum.Planes )
                {
                    if( Vec3.Dot( plane.Normal, light.Direction ) < 0 )
                        continue;

                    clipPlanes.Add( plane );
                }
            }

            //add directionalLightExtrusionDistance clip plane
            {
                Quat rot = Quat.FromDirectionZAxisUp( light.Direction );
                Vec3 p = mainCamera.Position - light.Direction * directionalLightExtrusionDistance;
                Plane plane = Plane.FromVectors( rot * Vec3.ZAxis, rot * Vec3.YAxis, p );
                clipPlanes.Add( plane );
            }

            return clipPlanes.ToArray();
        }
Ejemplo n.º 21
0
        public override void Dispose()
        {
            base.Dispose();

            if(mMainLight != null)
                mMainLight.Dispose();

            if (mBillboardSet != null)
                mBillboardSet.Dispose();

            mMainLight = null;
            mBillboardSet = null;
        }
Ejemplo n.º 22
0
        static Plane[] GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition(
			Camera mainCamera, RenderLight light )
        {
            Frustum mainFrustum = FrustumUtils.GetFrustumByCamera( mainCamera );
            if( EngineDebugSettings.FrustumTest && mainCamera.AllowFrustumTestMode )
            {
                mainFrustum.HalfWidth *= .5f;
                mainFrustum.HalfHeight *= .5f;
            }

            if( SceneManager.Instance.ShadowFarDistance > mainFrustum.NearDistance )
                mainFrustum.MoveFarDistance( SceneManager.Instance.ShadowFarDistance );

            Vec3[] frustumPoints = null;
            mainFrustum.ToPoints( ref frustumPoints );

            //create convex hull from all camera corner points and light position.
            List<Vec3> convexHullVertices = new List<Vec3>();
            convexHullVertices.Add( mainFrustum.Origin );
            for( int n = 4; n < 8; n++ )
                convexHullVertices.Add( frustumPoints[ n ] );
            convexHullVertices.Add( light.Position );

            Plane[] hullPlanes = ConvexPolyhedron.GetConvexPolyhedronPlanesFromVertices(
                convexHullVertices, .0001f );
            return hullPlanes;
        }
        public override LightShadowMapTexture CreateShadowMapTexture(RenderView renderView, RenderLight renderLight, IDirectLight light, int shadowMapSize)
        {
            var shadowMap = base.CreateShadowMapTexture(renderView, renderLight, light, shadowMapSize);

            shadowMap.CascadeCount = ((LightDirectionalShadowMap)light.Shadow).GetCascadeCount();
            // Views with orthographic cameras cannot use cascades, we force it to 1 shadow map here.
            if (renderView.Projection.M44 == 1.0f)
            {
                shadowMap.ShadowType  &= ~(LightShadowType.CascadeMask);
                shadowMap.ShadowType  |= LightShadowType.Cascade1;
                shadowMap.CascadeCount = (int)LightShadowMapCascadeCount.OneCascade;
            }
            return(shadowMap);
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Creates the element in the world. It automatically
        /// sets up the mesh and the node.</summary>
        protected virtual void Initialise(RenderQueueGroupID renderGroup, string materialName, Vec3 scale)
        {
            mBillboardSet = SceneManager.Instance.CreateBillboardSet(2);
            mBillboardSet.CastShadows = false;
            mBillboardSet.RenderQueueGroup = renderGroup;
            mBillboardSet.MaterialName = materialName;
            mBillboardSet.DefaultSize = new Vec2(1, 1);

            // Attaches the mesh on a node
            if (mBillboardSet.ParentSceneNode == null)
            {
                mNode = new SceneNode();
                mNode.Attach(mBillboardSet);
            }
            else
                mNode = mBillboardSet.ParentSceneNode;

            // Sets up the node (Position, Scale and Rotation)
            mBillboardSet.CreateBillboard(Vec3.Zero);
            mNode.Position = Vec3.Zero;
            mNode.Scale = scale;

            mMainLight = SceneManager.Instance.CreateLight();
            mMainLight.Type = RenderLightType.Directional;
            mMainLight.AllowStaticLighting = false;
            mMainLight.CastShadows = true;
            mMainLight.Position = new Vec3(0, 0, 150);
        }
Ejemplo n.º 25
0
 public bool Update(RenderLight light)
 {
     return(true);
 }
        public override LightShadowMapTexture CreateShadowMapTexture(RenderView renderView, RenderLight renderLight, IDirectLight light, int shadowMapSize)
        {
            var shadowMapTexture = base.CreateShadowMapTexture(renderView, renderLight, light, shadowMapSize);

            shadowMapTexture.CascadeCount = 6; // 6 faces
            return(shadowMapTexture);
        }
Ejemplo n.º 27
0
        static void WalkDirectionalLightShadowGeneration( Camera mainCamera, RenderLight light,
			int pssmTextureIndex, List<SceneNode> outSceneNodes, List<StaticMeshObject> outStaticMeshObjects )
        {
            int[] sceneGraphIndexes;
            if( SceneManager.Instance.OverrideVisibleObjects != null )
            {
                sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes();
            }
            else
            {
                Plane[] clipPlanes = GetClipPlanesForDirectionalLightShadowGeneration( mainCamera, light, pssmTextureIndex );

                uint groupMask = 0;
                if( outSceneNodes != null )
                    groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode;
                if( outStaticMeshObjects != null )
                    groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject;

                sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, groupMask );
            }

            foreach( int sceneGraphIndex in sceneGraphIndexes )
            {
                SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ];

                //SceneNode
                SceneNode sceneNode = data.SceneNode;
                if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() )
                {
                    //clip volumes
                    if( !IsTotalClipVolumesContainsBounds( sceneNode.GetWorldBounds() ) )
                        outSceneNodes.Add( sceneNode );
                }

                //StaticMeshObject
                StaticMeshObject staticMeshObject = data.StaticMeshObject;
                if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows )
                {
                    //clip volumes
                    if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) )
                        outStaticMeshObjects.Add( staticMeshObject );
                }
            }
        }
Ejemplo n.º 28
0
        static void WalkPointLightShadowGeneration( Camera mainCamera, RenderLight light,
			Vec3 pointLightFaceDirection, List<SceneNode> outSceneNodes,
			List<StaticMeshObject> outStaticMeshObjects )
        {
            Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar );

            if( !pointLightFaceDirection.Equals( Vec3.Zero, .001f ) )
            {
                //shadowmap. 6 render targets.

                int[] sceneGraphIndexes;
                if( SceneManager.Instance.OverrideVisibleObjects != null )
                {
                    sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes();
                }
                else
                {
                    Plane[] clipPlanes;
                    {
                        //add point light clip planes
                        Plane[] array1 = GetClipPlanesForPointLightShadowGeneration( mainCamera, light, pointLightFaceDirection );
                        //add main frustum clip planes and light position
                        Plane[] array2 = GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition( mainCamera, light );

                        clipPlanes = new Plane[ array1.Length + array2.Length ];
                        Array.Copy( array1, 0, clipPlanes, 0, array1.Length );
                        Array.Copy( array2, 0, clipPlanes, array1.Length, array2.Length );
                    }
                    Bounds clipBounds = lightSphere.ToBounds();

                    uint groupMask = 0;
                    if( outSceneNodes != null )
                        groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode;
                    if( outStaticMeshObjects != null )
                        groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject;

                    sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, clipBounds, groupMask );
                }

                foreach( int sceneGraphIndex in sceneGraphIndexes )
                {
                    SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ];

                    //SceneNode
                    SceneNode sceneNode = data.SceneNode;
                    if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() )
                    {
                        Bounds sceneNodeBounds = sceneNode.GetWorldBounds();
                        //clip by sphere
                        if( lightSphere.IsIntersectsBounds( sceneNodeBounds ) )
                        {
                            //clip volumes
                            if( !IsTotalClipVolumesContainsBounds( sceneNodeBounds ) )
                                outSceneNodes.Add( sceneNode );
                        }
                    }

                    //StaticMeshObject
                    StaticMeshObject staticMeshObject = data.StaticMeshObject;
                    if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows )
                    {
                        //clip by sphere
                        if( lightSphere.IsIntersectsBounds( staticMeshObject.Bounds ) )
                        {
                            //clip volumes
                            if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) )
                                outStaticMeshObjects.Add( staticMeshObject );
                        }
                    }
                }
            }
            else
            {
                //stencil shadows.
                //check by sphere volume.

                int[] sceneGraphIndexes;
                if( SceneManager.Instance.OverrideVisibleObjects != null )
                {
                    sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes();
                }
                else
                {
                    Plane[] clipPlanes;
                    {
                        //add main frustum clip planes and light position
                        Plane[] array1 = GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition( mainCamera, light );

                        clipPlanes = new Plane[ 6 + array1.Length ];

                        //add 6 light clip planes.
                        clipPlanes[ 0 ] = new Plane( Vec3.XAxis, lightSphere.Origin.X + lightSphere.Radius );
                        clipPlanes[ 1 ] = new Plane( -Vec3.XAxis, -( lightSphere.Origin.X - lightSphere.Radius ) );
                        clipPlanes[ 2 ] = new Plane( Vec3.YAxis, lightSphere.Origin.Y + lightSphere.Radius );
                        clipPlanes[ 3 ] = new Plane( -Vec3.YAxis, -( lightSphere.Origin.Y - lightSphere.Radius ) );
                        clipPlanes[ 4 ] = new Plane( Vec3.ZAxis, lightSphere.Origin.Z + lightSphere.Radius );
                        clipPlanes[ 5 ] = new Plane( -Vec3.ZAxis, -( lightSphere.Origin.Z - lightSphere.Radius ) );

                        Array.Copy( array1, 0, clipPlanes, 6, array1.Length );
                    }
                    Bounds clipBounds = lightSphere.ToBounds();

                    uint groupMask = 0;
                    if( outSceneNodes != null )
                        groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode;
                    if( outStaticMeshObjects != null )
                        groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject;

                    sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, clipBounds, groupMask );
                }

                foreach( int sceneGraphIndex in sceneGraphIndexes )
                {
                    SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ];

                    //SceneNode
                    SceneNode sceneNode = data.SceneNode;
                    if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() )
                    {
                        Bounds sceneNodeBounds = sceneNode.GetWorldBounds();
                        //clip by sphere
                        if( lightSphere.IsIntersectsBounds( sceneNodeBounds ) )
                        {
                            //clip volumes
                            if( !IsTotalClipVolumesContainsBounds( sceneNodeBounds ) )
                                outSceneNodes.Add( sceneNode );
                        }
                    }

                    //StaticMeshObject
                    StaticMeshObject staticMeshObject = data.StaticMeshObject;
                    if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows )
                    {
                        //clip by sphere
                        if( lightSphere.IsIntersectsBounds( staticMeshObject.Bounds ) )
                        {
                            //clip volumes
                            if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) )
                                outStaticMeshObjects.Add( staticMeshObject );
                        }
                    }
                }
            }
        }
Ejemplo n.º 29
0
        static void WalkSpotLightShadowGeneration( Camera mainCamera, RenderLight light,
			List<SceneNode> outSceneNodes, List<StaticMeshObject> outStaticMeshObjects )
        {
            Sphere lightSphere = new Sphere( light.Position, light.AttenuationFar );

            int[] sceneGraphIndexes;
            if( SceneManager.Instance.OverrideVisibleObjects != null )
            {
                sceneGraphIndexes = GetOverrideVisibleObjectsSceneGraphIndexes();
            }
            else
            {
                Plane[] clipPlanes;
                {
                    //add spot light clip planes
                    Plane[] array1 = light.SpotLightClipPlanes;
                    //add main frustum clip planes and light position
                    Plane[] array2 = GetClipPlanesOfConvexHullAroundMainCameraAndLightPosition( mainCamera, light );

                    clipPlanes = new Plane[ array1.Length + array2.Length ];
                    Array.Copy( array1, 0, clipPlanes, 0, array1.Length );
                    Array.Copy( array2, 0, clipPlanes, array1.Length, array2.Length );
                }
                Bounds clipBounds = lightSphere.ToBounds();

                uint groupMask = 0;
                if( outSceneNodes != null )
                    groupMask |= 1 << (int)SceneManager.SceneGraphGroups.SceneNode;
                if( outStaticMeshObjects != null )
                    groupMask |= 1 << (int)SceneManager.SceneGraphGroups.StaticMeshObject;

                sceneGraphIndexes = SceneManager.Instance.SceneGraph.GetObjects( clipPlanes, clipBounds, groupMask );
            }

            foreach( int sceneGraphIndex in sceneGraphIndexes )
            {
                SceneManager.SceneGraphObjectData data = SceneManager.Instance.SceneGraphObjects[ sceneGraphIndex ];

                //SceneNode
                SceneNode sceneNode = data.SceneNode;
                if( sceneNode != null && sceneNode.Visible && sceneNode.IsContainsObjectWithCastsShadowsEnabled() )
                {
                    Bounds sceneNodeBounds = sceneNode.GetWorldBounds();
                    //clip by sphere
                    if( lightSphere.IsIntersectsBounds( sceneNodeBounds ) )
                    {
                        //clip volumes
                        if( !IsTotalClipVolumesContainsBounds( sceneNodeBounds ) )
                            outSceneNodes.Add( sceneNode );
                    }
                }

                //StaticMeshObject
                StaticMeshObject staticMeshObject = data.StaticMeshObject;
                if( staticMeshObject != null && staticMeshObject.Visible && staticMeshObject.CastShadows )
                {
                    //clip by sphere
                    if( lightSphere.IsIntersectsBounds( staticMeshObject.Bounds ) )
                    {
                        //clip volumes
                        if( !IsTotalClipVolumesContainsBounds( staticMeshObject.Bounds ) )
                            outStaticMeshObjects.Add( staticMeshObject );
                    }
                }
            }
        }
        public override LightShadowMapTexture CreateShadowMapTexture(RenderView renderView, RenderLight renderLight, IDirectLight light, int shadowMapSize)
        {
            var shadowMap = shadowMaps.Add();

            shadowMap.Initialize(renderView, renderLight, light, light.Shadow, shadowMapSize, this);
            shadowMap.CascadeCount = 2; // 2 faces
            return(shadowMap);
        }
 private static bool CanRenderLight(RenderLight renderLight, LightGroupRendererBase.ProcessLightsParameters parameters)
 {
     // Just to do some minor fake work, but ensure this is true.
     return(renderLight.Position == default);
 }