Example #1
0
        /// <summary>
        /// Create the projection matrices
        /// </summary>
        /// <param name="camera"></param>
        /// <param name="meshMaterialLibrary"></param>
        /// <param name="entities"></param>
        private void UpdateViewProjection(Camera camera, MeshMaterialLibrary meshMaterialLibrary, List <BasicEntity> entities)
        {
            _viewProjectionHasChanged = camera.HasChanged;

            //If the camera didn't do anything we don't need to update this stuff
            if (_viewProjectionHasChanged)
            {
                //We have processed the change, now setup for next frame as false
                camera.HasChanged = false;
                camera.HasMoved   = false;

                //View matrix
                _view        = Matrix.CreateLookAt(camera.Position, camera.Lookat, camera.Up);
                _inverseView = Matrix.Invert(_view);

                _projection = Matrix.CreatePerspectiveFieldOfView(camera.FieldOfView,
                                                                  GameSettings.g_ScreenWidth / (float)GameSettings.g_ScreenHeight, 1, GameSettings.g_FarPlane);

                Shaders.GBufferEffectParameter_Camera.SetValue(camera.Position);

                _viewProjection = _view * _projection;

                //this is the unjittered viewProjection. For some effects we don't want the jittered one
                _staticViewProjection = _viewProjection;

                //Transformation for TAA - from current view back to the old view projection
                _currentViewToPreviousViewProjection = Matrix.Invert(_view) * _previousViewProjection;

                _previousViewProjection = _viewProjection;
                _inverseViewProjection  = Matrix.Invert(_viewProjection);

                if (_boundingFrustum == null)
                {
                    _boundingFrustum = new BoundingFrustum(_staticViewProjection);
                }
                else
                {
                    _boundingFrustum.Matrix = _staticViewProjection;
                }

                Matrix id = Matrix.Identity;
            }

            //We need to update whether or not entities are in our boundingFrustum and then cull them or not!
            meshMaterialLibrary.FrustumCulling(entities, _boundingFrustum, _viewProjectionHasChanged, camera.Position);

            //Performance Profiler
            if (GameSettings.d_profiler)
            {
                long performanceCurrentTime = _performanceTimer.ElapsedTicks;
                GameStats.d_profileUpdateViewProjection = performanceCurrentTime - _performancePreviousTime;

                _performancePreviousTime = performanceCurrentTime;
            }
        }
Example #2
0
        /// <summary>
        /// Only one shadow map needed for a directional light
        /// </summary>
        /// <param name="light"></param>
        /// <param name="shadowResolution"></param>
        /// <param name="meshMaterialLibrary"></param>
        /// <param name="entities"></param>
        private void CreateShadowMapDirectionalLight(GraphicsDevice graphicsDevice, DirectionalLight light, int shadowResolution, MeshMaterialLibrary meshMaterialLibrary, List <BasicEntity> entities)
        {
            //Create a renderTarget if we don't have one yet
            if (light.ShadowMap == null)
            {
                //if (lightSource.ShadowFiltering != DirectionalLightSource.ShadowFilteringTypes.VSM)
                //{
                light.ShadowMap = new RenderTarget2D(graphicsDevice, shadowResolution, shadowResolution, false,
                                                     SurfaceFormat.Single, DepthFormat.Depth24, 0, RenderTargetUsage.DiscardContents);
                //}
                //else //For a VSM shadowMap we need 2 components
                //{
                //    lightSource.ShadowMap = new RenderTarget2D(_graphicsDevice, shadowResolution, shadowResolution, false,
                //       SurfaceFormat.Vector2, DepthFormat.Depth24, 0, RenderTargetUsage.DiscardContents);
                //}
            }

            if (light.HasChanged)
            {
                Matrix lightProjection = Matrix.CreateOrthographic(light.ShadowSize, light.ShadowSize,
                                                                   -light.ShadowDepth, light.ShadowDepth);
                Matrix lightView = Matrix.CreateLookAt(light.Position, light.Position + light.Direction, Vector3.Down);

                light.LightView           = lightView;
                light.LightViewProjection = lightView * lightProjection;

                _boundingFrustumShadow = new BoundingFrustum(light.LightViewProjection);

                graphicsDevice.SetRenderTarget(light.ShadowMap);
                graphicsDevice.Clear(ClearOptions.DepthBuffer, Color.White, 1, 0);

                meshMaterialLibrary.FrustumCulling(entities, _boundingFrustumShadow, true, light.Position);

                // Rendering!
                _FarClip.SetValue(light.ShadowDepth);
                _SizeBias.SetValue(GameSettings.ShadowBias * 2048 / light.ShadowResolution);

                meshMaterialLibrary.Draw(MeshMaterialLibrary.RenderType.ShadowLinear,
                                         light.LightViewProjection, light.HasChanged, false, false, 0, light.LightView, renderModule: this);
            }
            else
            {
                _boundingFrustumShadow = new BoundingFrustum(light.LightViewProjection);

                bool hasAnyObjectMoved = meshMaterialLibrary.FrustumCulling(entities: entities, boundingFrustrum: _boundingFrustumShadow, hasCameraChanged: false, cameraPosition: light.Position);

                if (!hasAnyObjectMoved)
                {
                    return;
                }

                meshMaterialLibrary.FrustumCulling(entities: entities, boundingFrustrum: _boundingFrustumShadow, hasCameraChanged: true, cameraPosition: light.Position);

                graphicsDevice.SetRenderTarget(light.ShadowMap);
                graphicsDevice.Clear(ClearOptions.DepthBuffer, Color.White, 1, 0);

                _FarClip.SetValue(light.ShadowDepth);
                _SizeBias.SetValue(GameSettings.ShadowBias * 2048 / light.ShadowResolution);

                meshMaterialLibrary.Draw(MeshMaterialLibrary.RenderType.ShadowLinear,
                                         light.LightViewProjection, false, true, false, 0, light.LightView, renderModule: this);
            }

            //Blur!
            //if (lightSource.ShadowFiltering == DirectionalLightSource.ShadowFilteringTypes.VSM)
            //{
            //    lightSource.ShadowMap = _gaussianBlur.DrawGaussianBlur(lightSource.ShadowMap);
            //}
        }
Example #3
0
        /// <summary>
        /// Create the shadow map for each cubemapside, then combine into one cubemap
        /// </summary>
        /// <param name="light"></param>
        /// <param name="size"></param>
        /// <param name="meshMaterialLibrary"></param>
        /// <param name="entities"></param>
        private void CreateShadowCubeMap(GraphicsDevice graphicsDevice, PointLight light, int size, MeshMaterialLibrary meshMaterialLibrary, List <BasicEntity> entities)
        {
            //For VSM we need 2 channels, -> Vector2
            //todo: check if we need preserve contents
            if (light.ShadowMap == null)
            {
                light.ShadowMap = new RenderTarget2D(graphicsDevice, size, size * 6, false, SurfaceFormat.HalfSingle, DepthFormat.Depth24, 0, RenderTargetUsage.PreserveContents);
            }

            Matrix      lightViewProjection = new Matrix();
            CubeMapFace cubeMapFace; // = CubeMapFace.NegativeX;

            if (light.HasChanged)
            {
                graphicsDevice.SetRenderTarget(light.ShadowMap);

                Matrix lightProjection = Matrix.CreatePerspectiveFieldOfView((float)(Math.PI / 2), 1, 1, light.Radius);
                Matrix lightView; // = identity

                //Reset the blur array
                light.faceBlurCount = new int[6];

                graphicsDevice.SetRenderTarget(light.ShadowMap);
                graphicsDevice.Clear(Color.Black);

                for (int i = 0; i < 6; i++)
                {
                    // render the scene to all cubemap faces
                    cubeMapFace = (CubeMapFace)i;
                    switch (cubeMapFace)
                    {
                    case CubeMapFace.PositiveX:
                    {
                        lightView           = Matrix.CreateLookAt(light.Position, light.Position + Vector3.UnitX, Vector3.UnitZ);
                        lightViewProjection = lightView * lightProjection;
                        light.LightViewProjectionPositiveX = lightViewProjection;
                        break;
                    }

                    case CubeMapFace.NegativeX:
                    {
                        lightView           = Matrix.CreateLookAt(light.Position, light.Position - Vector3.UnitX, Vector3.UnitZ);
                        lightViewProjection = lightView * lightProjection;
                        light.LightViewProjectionNegativeX = lightViewProjection;
                        break;
                    }

                    case CubeMapFace.PositiveY:
                    {
                        lightView           = Matrix.CreateLookAt(light.Position, light.Position + Vector3.UnitY, Vector3.UnitZ);
                        lightViewProjection = lightView * lightProjection;
                        light.LightViewProjectionPositiveY = lightViewProjection;
                        break;
                    }

                    case CubeMapFace.NegativeY:
                    {
                        lightView           = Matrix.CreateLookAt(light.Position, light.Position - Vector3.UnitY, Vector3.UnitZ);
                        lightViewProjection = lightView * lightProjection;
                        light.LightViewProjectionNegativeY = lightViewProjection;
                        break;
                    }

                    case CubeMapFace.PositiveZ:
                    {
                        lightView           = Matrix.CreateLookAt(light.Position, light.Position + Vector3.UnitZ, Vector3.UnitX);
                        lightViewProjection = lightView * lightProjection;
                        light.LightViewProjectionPositiveZ = lightViewProjection;
                        break;
                    }

                    case CubeMapFace.NegativeZ:
                    {
                        lightView           = Matrix.CreateLookAt(light.Position, light.Position - Vector3.UnitZ, Vector3.UnitX);
                        lightViewProjection = lightView * lightProjection;
                        light.LightViewProjectionNegativeZ = lightViewProjection;
                        break;
                    }
                    }

                    if (_boundingFrustumShadow != null)
                    {
                        _boundingFrustumShadow.Matrix = lightViewProjection;
                    }
                    else
                    {
                        _boundingFrustumShadow = new BoundingFrustum(lightViewProjection);
                    }

                    meshMaterialLibrary.FrustumCulling(entities, _boundingFrustumShadow, true, light.Position);

                    // Rendering!

                    graphicsDevice.Viewport = new Viewport(0, light.ShadowResolution * (int)cubeMapFace, light.ShadowResolution, light.ShadowResolution);
                    //_graphicsDevice.ScissorRectangle = new Rectangle(0, light.ShadowResolution* (int) cubeMapFace,  light.ShadowResolution, light.ShadowResolution);

                    _FarClip.SetValue(light.Radius);
                    _LightPositionWS.SetValue(light.Position);

                    graphicsDevice.ScissorRectangle = new Rectangle(0, light.ShadowResolution * (int)cubeMapFace, light.ShadowResolution, light.ShadowResolution);

                    meshMaterialLibrary.Draw(renderType: MeshMaterialLibrary.RenderType.ShadowOmnidirectional,
                                             viewProjection: lightViewProjection,
                                             lightViewPointChanged: true,
                                             hasAnyObjectMoved: light.HasChanged,
                                             renderModule: this);
                }
            }
            else
            {
                bool draw = false;

                for (int i = 0; i < 6; i++)
                {
                    // render the scene to all cubemap faces
                    cubeMapFace = (CubeMapFace)i;

                    switch (cubeMapFace)
                    {
                    case CubeMapFace.NegativeX:
                        lightViewProjection = light.LightViewProjectionNegativeX;
                        break;

                    case CubeMapFace.NegativeY:
                        lightViewProjection = light.LightViewProjectionNegativeY;
                        break;

                    case CubeMapFace.NegativeZ:
                        lightViewProjection = light.LightViewProjectionNegativeZ;
                        break;

                    case CubeMapFace.PositiveX:
                        lightViewProjection = light.LightViewProjectionPositiveX;
                        break;

                    case CubeMapFace.PositiveY:
                        lightViewProjection = light.LightViewProjectionPositiveY;
                        break;

                    case CubeMapFace.PositiveZ:
                        lightViewProjection = light.LightViewProjectionPositiveZ;
                        break;
                    }

                    if (_boundingFrustumShadow != null)
                    {
                        _boundingFrustumShadow.Matrix = lightViewProjection;
                    }
                    else
                    {
                        _boundingFrustumShadow = new BoundingFrustum(lightViewProjection);
                    }

                    bool hasAnyObjectMoved = meshMaterialLibrary.FrustumCulling(entities, _boundingFrustumShadow, false, light.Position);

                    if (!hasAnyObjectMoved)
                    {
                        continue;
                    }

                    if (!draw)
                    {
                        graphicsDevice.SetRenderTarget(light.ShadowMap);
                        draw = true;
                    }

                    graphicsDevice.Viewport = new Viewport(0, light.ShadowResolution * (int)cubeMapFace, light.ShadowResolution, light.ShadowResolution);

                    //_graphicsDevice.Clear(Color.TransparentBlack);
                    //_graphicsDevice.Clear(ClearOptions.DepthBuffer, Color.White, 0, 0);
                    graphicsDevice.ScissorRectangle = new Rectangle(0, light.ShadowResolution * (int)cubeMapFace, light.ShadowResolution, light.ShadowResolution);

                    meshMaterialLibrary.Draw(renderType: MeshMaterialLibrary.RenderType.ShadowOmnidirectional,
                                             viewProjection: lightViewProjection,
                                             lightViewPointChanged: light.HasChanged,
                                             hasAnyObjectMoved: true,
                                             renderModule: this);
                }
            }
        }