/// <summary>
        /// Draw all directional lights, set up some shader variables first
        /// </summary>
        /// <param name="dirLights"></param>
        /// <param name="cameraOrigin"></param>
        private void DrawDirectionalLights(List <DirectionalLight> dirLights, Vector3 cameraOrigin)
        {
            if (dirLights.Count < 1)
            {
                return;
            }

            _graphicsDevice.DepthStencilState = DepthStencilState.Default;
            _graphicsDevice.RasterizerState   = RasterizerState.CullCounterClockwise;

            //If nothing has changed we don't need to update
            if (_viewProjectionHasChanged)
            {
                Shaders.deferredDirectionalLightParameterViewProjection.SetValue(_viewProjection);
                Shaders.deferredDirectionalLightParameterCameraPosition.SetValue(cameraOrigin);
                Shaders.deferredDirectionalLightParameterInverseViewProjection.SetValue(_inverseViewProjection);
            }

            _graphicsDevice.DepthStencilState = DepthStencilState.None;

            for (int index = 0; index < dirLights.Count; index++)
            {
                DirectionalLight light = dirLights[index];
                DrawDirectionalLight(light);
            }
        }
Beispiel #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //  HELPER FUNCTIONS
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Spawn a directional light (omni light). This light covers everything and comes from a single point from infinte distance.
        /// Good for something like a sun
        /// </summary>
        /// <param name="direction">The direction the light is facing in world space coordinates</param>
        /// <param name="intensity"></param>
        /// <param name="color"></param>
        /// <param name="position">The position is only relevant if drawing shadows</param>
        /// <param name="drawShadows"></param>
        /// <param name="shadowWorldSize">WorldSize is the width/height of the view projection for shadow mapping</param>
        /// <param name="shadowDepth">FarClip for shadow mapping</param>
        /// <param name="shadowResolution"></param>
        /// <param name="shadowFilteringFiltering"></param>
        /// <param name="screenspaceShadowBlur"></param>
        /// <param name="staticshadows">These shadows will not be updated once they are created, moving objects will be shadowed incorrectly</param>
        /// <returns></returns>
        private DirectionalLight AddDirectionalLight(Vector3 direction, int intensity, Color color, Vector3 position = default(Vector3), bool drawShadows = false, float shadowWorldSize = 100, float shadowDepth = 100, int shadowResolution = 512, DirectionalLight.ShadowFilteringTypes shadowFilteringFiltering = DirectionalLight.ShadowFilteringTypes.Poisson, bool screenspaceShadowBlur = false, bool staticshadows = false)
        {
            DirectionalLight light = new DirectionalLight(color: color,
                                                          intensity: intensity,
                                                          direction: direction,
                                                          position: position,
                                                          castShadows: drawShadows,
                                                          shadowSize: shadowWorldSize,
                                                          shadowDepth: shadowDepth,
                                                          shadowResolution: shadowResolution,
                                                          shadowFiltering: shadowFilteringFiltering,
                                                          screenspaceshadowblur: screenspaceShadowBlur,
                                                          staticshadows: staticshadows);

            DirectionalLights.Add(light);
            return(light);
        }
        /// <summary>
        /// Draw the individual light, full screen effect
        /// </summary>
        /// <param name="light"></param>
        private void DrawDirectionalLight(DirectionalLight light)
        {
            if (!light.IsEnabled)
            {
                return;
            }

            if (_viewProjectionHasChanged)
            {
                light.DirectionViewSpace            = Vector3.Transform(light.Direction, _viewIT);
                light.LightViewProjection_ViewSpace = _inverseView * light.LightViewProjection;
                light.LightView_ViewSpace           = _inverseView * light.LightView;
            }

            Shaders.deferredDirectionalLightParameter_LightColor.SetValue(light.ColorV3);
            Shaders.deferredDirectionalLightParameter_LightDirection.SetValue(light.DirectionViewSpace);
            Shaders.deferredDirectionalLightParameter_LightIntensity.SetValue(light.Intensity);
            light.ApplyShader();
            _fullScreenTriangle.Draw(_graphicsDevice);
        }
Beispiel #4
0
        /// <summary>
        /// Main Logic for the editor part
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="entities"></param>
        /// <param name="data"></param>
        public void Update(GameTime gameTime,
                           List <BasicEntity> entities,
                           List <Decal> decals,
                           List <PointLight> pointLights,
                           List <DirectionalLight> dirLights,
                           EnvironmentSample envSample,
                           List <DebugEntity> debugEntities,
                           EditorReceivedData data,
                           MeshMaterialLibrary meshMaterialLibrary)
        {
            if (!GameSettings.e_enableeditor)
            {
                return;
            }

            if (!DebugScreen.ConsoleOpen)
            {
                if (Input.WasKeyPressed(Keys.R))
                {
                    GameStats.e_gizmoMode = GizmoModes.Rotation;
                }
                if (Input.WasKeyPressed(Keys.T))
                {
                    GameStats.e_gizmoMode = GizmoModes.Translation;
                }
                if (Input.WasKeyPressed(Keys.Z))
                {
                    GameStats.e_gizmoMode = GizmoModes.Scale;
                }
            }

            _gizmoMode = GameStats.e_gizmoMode;

            int hoveredId = data.HoveredId;

            if (_gizmoTransformationMode)
            {
                if (Input.mouseState.LeftButton == ButtonState.Pressed)
                {
                    GizmoControl(_gizmoId, data);
                }
                else
                {
                    _gizmoTransformationMode = false;
                }
            }
            else if (Input.WasLMBClicked() && !GUIControl.UIWasUsed)
            {
                previousMouseX = Input.mouseState.X;
                previousMouseY = Input.mouseState.Y;

                //Gizmos
                if (hoveredId >= 1 && hoveredId <= 3)
                {
                    _gizmoId = hoveredId;
                    GizmoControl(_gizmoId, data);
                    return;
                }

                if (hoveredId <= 0)
                {
                    SelectedObject = null;
                    return;
                }

                bool foundnew = false;
                //Get the selected entity!
                for (int index = 0; index < entities.Count; index++)
                {
                    var VARIABLE = entities[index];
                    if (VARIABLE.Id == hoveredId)
                    {
                        SelectedObject = VARIABLE;
                        foundnew       = true;
                        break;
                    }
                }
                if (foundnew == false)
                {
                    for (int index = 0; index < decals.Count; index++)
                    {
                        Decal decal = decals[index];
                        if (decal.Id == hoveredId)
                        {
                            SelectedObject = decal;
                            break;
                        }
                    }

                    for (int index = 0; index < pointLights.Count; index++)
                    {
                        PointLight pointLight = pointLights[index];
                        if (pointLight.Id == hoveredId)
                        {
                            SelectedObject = pointLight;
                            break;
                        }
                    }

                    for (int index = 0; index < dirLights.Count; index++)
                    {
                        DirectionalLight directionalLight = dirLights[index];
                        if (directionalLight.Id == hoveredId)
                        {
                            SelectedObject = directionalLight;
                            break;
                        }
                    }

                    {
                        if (envSample.Id == hoveredId)
                        {
                            SelectedObject = envSample;
                        }
                    }

                    for (int index = 0; index < debugEntities.Count; index++)
                    {
                        DirectionalLight debugEntity = dirLights[index];
                        if (debugEntity.Id == hoveredId)
                        {
                            SelectedObject = debugEntity;
                            break;
                        }
                    }
                }
            }

            //Controls

            if (Input.WasKeyPressed(Keys.Delete))
            {
                //Find object
                if (SelectedObject is BasicEntity)
                {
                    entities.Remove((BasicEntity)SelectedObject);
                    meshMaterialLibrary.DeleteFromRegistry((BasicEntity)SelectedObject);

                    SelectedObject = null;
                }
                else if (SelectedObject is Decal)
                {
                    decals.Remove((Decal)SelectedObject);

                    SelectedObject = null;
                }
                else if (SelectedObject is PointLight)
                {
                    pointLights.Remove((PointLight)SelectedObject);

                    SelectedObject = null;
                }
                else if (SelectedObject is DirectionalLight)
                {
                    dirLights.Remove((DirectionalLight)SelectedObject);

                    SelectedObject = null;
                }
            }

            if (Input.WasKeyPressed(Keys.Insert) || (Input.keyboardState.IsKeyDown(Keys.LeftControl) && Input.WasKeyPressed(Keys.C)))
            {
                if (SelectedObject is BasicEntity)
                {
                    BasicEntity copy = (BasicEntity)SelectedObject.Clone;
                    copy.RegisterInLibrary(meshMaterialLibrary);

                    entities.Add(copy);
                }
                else if (SelectedObject is Decal)
                {
                    Decal copy = (Decal)SelectedObject.Clone;
                    decals.Add(copy);
                }
                else if (SelectedObject is PointLight)
                {
                    PointLight copy = (PointLight)SelectedObject.Clone;
                    pointLights.Add(copy);
                }
                else if (SelectedObject is DirectionalLight)
                {
                    DirectionalLight copy = (DirectionalLight)SelectedObject.Clone;
                    dirLights.Add(copy);
                }
            }
        }
Beispiel #5
0
        public void DrawBillboards(List <Decal> decals, List <PointLight> lights, List <DirectionalLight> dirLights, EnvironmentSample envSample, List <DebugEntity> debug, Matrix staticViewProjection, Matrix view, EditorLogic.EditorSendData sendData)
        {
            _graphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            _graphicsDevice.SetVertexBuffer(_billboardBuffer.VBuffer);
            _graphicsDevice.Indices = (_billboardBuffer.IBuffer);

            Shaders.BillboardEffect.CurrentTechnique = Shaders.BillboardEffectTechnique_Billboard;

            Shaders.BillboardEffectParameter_IdColor.SetValue(Color.Gray.ToVector3());

            //Decals

            Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconDecal);
            for (int index = 0; index < decals.Count; index++)
            {
                var decal = decals[index];
                DrawBillboard(decal, staticViewProjection, view, sendData);
            }

            //Lights

            Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconLight);
            for (int index = 0; index < lights.Count; index++)
            {
                var light = lights[index];
                DrawBillboard(light, staticViewProjection, view, sendData);
            }

            //DirectionalLights
            for (var index = 0; index < dirLights.Count; index++)
            {
                DirectionalLight light = dirLights[index];
                DrawBillboard(light, staticViewProjection, view, sendData);

                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position, light.Direction * 10, 1, Color.Black, light.Color);
                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position + Vector3.UnitX * 10, light.Direction * 10, 1, Color.Black,
                                 light.Color);
                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position - Vector3.UnitX * 10, light.Direction * 10, 1, Color.Black,
                                 light.Color);
                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position + Vector3.UnitY * 10, light.Direction * 10, 1, Color.Black,
                                 light.Color);
                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position - Vector3.UnitY * 10, light.Direction * 10, 1, Color.Black,
                                 light.Color);
                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position + Vector3.UnitZ * 10, light.Direction * 10, 1, Color.Black,
                                 light.Color);
                HelperGeometryManager.GetInstance()
                .AddLineStartDir(light.Position - Vector3.UnitZ * 10, light.Direction * 10, 1, Color.Black,
                                 light.Color);

                if (light.CastShadows)
                {
                    BoundingFrustum boundingFrustumShadow = new BoundingFrustum(light.LightViewProjection);

                    HelperGeometryManager.GetInstance().CreateBoundingBoxLines(boundingFrustumShadow);
                }
            }

            //EnvMap

            Shaders.BillboardEffectParameter_Texture.SetValue(_assets.IconEnvmap);

            DrawBillboard(envSample, staticViewProjection, view, sendData);

            //Dbg
            for (int index = 0; index < debug.Count; index++)
            {
                var dbgEntity = debug[index];
                DrawBillboard(dbgEntity, staticViewProjection, view, sendData);
            }
        }
Beispiel #6
0
        public void Draw(GraphicsDevice graphicsDevice, MeshMaterialLibrary meshMaterialLibrary, List <BasicEntity> entities, List <PointLight> pointLights, List <DirectionalLight> dirLights, Camera camera)
        {
            _pass = Passes.Omnidirectional;

            //Go through all our point lights
            for (int index = 0; index < pointLights.Count; index++)
            {
                PointLight light = pointLights[index];

                if (!light.IsEnabled)
                {
                    continue;
                }

                //If we don't see the light we shouldn't update. This is actually wrong, can lead to mistakes,
                //if we implement it like this we should rerender once we enter visible space again.
                //if (_boundingFrustum.Contains(light.BoundingSphere) == ContainmentType.Disjoint)
                //{
                //    continue;
                //}

                if (light.CastShadows)
                {
                    //A poing light has 6 shadow maps, add that to our stat counter. These are total shadow maps, not updated ones
                    GameStats.shadowMaps += 6;

                    //Update if we didn't initialize yet or if we are dynamic
                    if (!light.StaticShadows || light.ShadowMap == null)
                    {
                        CreateShadowCubeMap(graphicsDevice, light, light.ShadowResolution, meshMaterialLibrary, entities);

                        light.HasChanged  = false;
                        camera.HasChanged = true;
                    }
                }
            }

            _pass = Passes.Directional;

            int dirLightShadowedWithSSBlur = 0;

            for (int index = 0; index < dirLights.Count; index++)
            {
                DirectionalLight light = dirLights[index];
                if (!light.IsEnabled)
                {
                    continue;
                }

                if (light.CastShadows)
                {
                    GameStats.shadowMaps += 1;

                    CreateShadowMapDirectionalLight(graphicsDevice, light, light.ShadowResolution, meshMaterialLibrary, entities);

                    camera.HasChanged = true;
                    light.HasChanged  = false;

                    if (light.ScreenSpaceShadowBlur)
                    {
                        dirLightShadowedWithSSBlur++;
                    }
                }

                if (dirLightShadowedWithSSBlur > 1)
                {
                    throw new NotImplementedException(
                              "Only one shadowed DirectionalLight with screen space blur is supported right now");
                }
            }
        }
Beispiel #7
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);
            //}
        }