Ejemplo n.º 1
0
        public void SetSpotLightParameters(SpotLight light, Microsoft.Xna.Framework.Graphics.Effect effect, Vector3 cameraPos)
        {
            bool shadowed = light.Shadowed && this.shadowMapIndices.ContainsKey(light);

            effect.CurrentTechnique = effect.Techniques[shadowed ? "SpotLightShadowed" : "SpotLight"];
            if (shadowed)
            {
                effect.Parameters["ShadowMap" + Model.SamplerPostfix].SetValue(this.spotShadowMaps[this.shadowMapIndices[light]]);
                effect.Parameters["ShadowMapSize"].SetValue(this.spotShadowMapSize);
            }

            float horizontalScale = (float)Math.Sin(light.FieldOfView * 0.5f) * light.Attenuation;
            float depthScale      = (float)Math.Cos(light.FieldOfView * 0.5f) * light.Attenuation;

            effect.Parameters["SpotLightViewProjectionMatrix"].SetValue(Matrix.CreateTranslation(cameraPos) * light.ViewProjection);
            effect.Parameters["SpotLightPosition"].SetValue(light.Position - cameraPos);

            Matrix rotation = Matrix.CreateFromQuaternion(light.Orientation);

            rotation.Forward *= -1.0f;
            effect.Parameters["SpotLightDirection"].SetValue(rotation.Forward);
            effect.Parameters["WorldMatrix"].SetValue(Matrix.CreateScale(horizontalScale, horizontalScale, depthScale) * rotation * Matrix.CreateTranslation(light.Position - cameraPos));

            effect.Parameters["SpotLightRadius"].SetValue(depthScale);
            effect.Parameters["SpotLightColor"].SetValue(light.Color);
            effect.Parameters["Cookie" + Model.SamplerPostfix].SetValue(light.CookieTexture);
        }
Ejemplo n.º 2
0
 public void RenderSpotShadowMap(SpotLight light, int index)
 {
     this.shadowCamera.View.Value = light.View;
     this.shadowCamera.SetPerspectiveProjection(light.FieldOfView, new Point(this.spotShadowMapSize, this.spotShadowMapSize), 1.0f, Math.Max(2.0f, light.Attenuation));
     this.main.GraphicsDevice.SetRenderTarget(this.spotShadowMaps[index]);
     this.main.GraphicsDevice.Clear(new Color(0, 255, 255));
     this.main.DrawScene(this.shadowRenderParameters);
 }
Ejemplo n.º 3
0
        public override Entity Create(Main main)
        {
            Entity result = new Entity(main, "SpotLight");

            Transform transform = new Transform();
            result.Add("Transform", transform);
            SpotLight spotLight = new SpotLight();
            result.Add("SpotLight", spotLight);

            return result;
        }
Ejemplo n.º 4
0
        public void PostProcess(RenderTarget2D result, RenderParameters parameters)
        {
            if (this.needBufferReallocation())
            {
                return;
            }

            Vector3         originalCameraPosition  = parameters.Camera.Position;
            Matrix          originalViewMatrix      = parameters.Camera.View;
            BoundingFrustum originalBoundingFrustum = parameters.Camera.BoundingFrustum;

            parameters.Camera.Position.Value = Vector3.Zero;
            Matrix newViewMatrix = originalViewMatrix;

            newViewMatrix.Translation    = Vector3.Zero;
            parameters.Camera.View.Value = newViewMatrix;

            RasterizerState originalState = this.main.GraphicsDevice.RasterizerState;

            bool enableSSAO = this.allowSSAO && this.EnableSSAO;

            if (enableSSAO)
            {
                // Down-sample depth buffer
                this.downsampleEffect.CurrentTechnique = this.downsampleEffect.Techniques["DownsampleDepth"];
                this.sources2[0]      = this.depthBuffer;
                this.sources2[1]      = this.normalBuffer;
                this.destinations2[0] = this.halfDepthBuffer;
                this.destinations2[1] = this.halfBuffer1;
                if (!this.preparePostProcess(this.sources2, this.destinations2, this.downsampleEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                // Compute SSAO
                parameters.Camera.SetParameters(this.ssaoEffect);
                this.ssaoEffect.CurrentTechnique = this.ssaoEffect.Techniques["SSAO"];
                this.sources2[0]      = this.halfDepthBuffer;
                this.sources2[1]      = this.halfBuffer1;
                this.destinations1[0] = this.halfBuffer2;
                if (!this.preparePostProcess(this.sources2, this.destinations1, this.ssaoEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                // Blur
                this.ssaoEffect.CurrentTechnique = this.ssaoEffect.Techniques["BlurHorizontal"];
                this.sources2[0]      = this.halfBuffer2;
                this.sources2[1]      = this.halfDepthBuffer;
                this.destinations1[0] = this.halfBuffer1;
                if (!this.preparePostProcess(this.sources2, this.destinations1, this.ssaoEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                this.ssaoEffect.CurrentTechnique = this.ssaoEffect.Techniques["Composite"];
                this.sources2[0]      = this.halfBuffer1;
                this.sources2[1]      = this.halfDepthBuffer;
                this.destinations1[0] = this.halfBuffer2;
                if (!this.preparePostProcess(this.sources2, this.destinations1, this.ssaoEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);
            }

            // Global lighting
            this.destinations2[0] = this.lightingBuffer;
            this.destinations2[1] = this.specularBuffer;
            if (!this.setTargets(this.destinations2))
            {
                return;
            }
            string globalLightTechnique = "GlobalLight";

            if (this.lightingManager.EnableGlobalShadowMap && this.lightingManager.HasGlobalShadowLight)
            {
                if (parameters.IsMainRender)
                {
                    if (this.lightingManager.HasGlobalShadowLightClouds)
                    {
                        if (this.lightingManager.EnableDetailGlobalShadowMap)
                        {
                            globalLightTechnique = "GlobalLightDetailShadowClouds";
                        }
                        else
                        {
                            globalLightTechnique = "GlobalLightShadowClouds";
                        }
                    }
                    else
                    {
                        if (this.lightingManager.EnableDetailGlobalShadowMap)
                        {
                            globalLightTechnique = "GlobalLightDetailShadow";
                        }
                        else
                        {
                            globalLightTechnique = "GlobalLightShadow";
                        }
                    }
                }
                else
                {
                    globalLightTechnique = "GlobalLightShadow";
                }
            }
            Renderer.globalLightEffect.CurrentTechnique = Renderer.globalLightEffect.Techniques[globalLightTechnique];
            parameters.Camera.SetParameters(Renderer.globalLightEffect);
            this.lightingManager.SetGlobalLightParameters(Renderer.globalLightEffect, parameters.Camera, originalCameraPosition);
            Renderer.globalLightEffect.Parameters["Materials"].SetValue(parameters.MaterialData);
            this.sources3[0]      = this.depthBuffer;
            this.sources3[1]      = this.normalBuffer;
            this.sources3[2]      = this.colorBuffer1;
            this.destinations2[0] = this.lightingBuffer;
            this.destinations2[1] = this.specularBuffer;
            this.setTargetParameters(this.sources3, this.destinations2, Renderer.globalLightEffect);
            this.applyEffect(Renderer.globalLightEffect);
            Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

            // Spot and point lights
            if (!parameters.ReverseCullOrder)
            {
                this.main.GraphicsDevice.RasterizerState = this.reverseCullState;
            }

            // HACK
            // Increase the far plane to prevent clipping back faces of huge lights
            float originalFarPlane = parameters.Camera.FarPlaneDistance;

            parameters.Camera.FarPlaneDistance.Value *= 4.0f;
            parameters.Camera.SetParameters(Renderer.pointLightEffect);
            parameters.Camera.SetParameters(Renderer.spotLightEffect);
            parameters.Camera.FarPlaneDistance.Value = originalFarPlane;

            // Spot lights
            Renderer.spotLightEffect.Parameters["Materials"].SetValue(parameters.MaterialData);
            this.setTargetParameters(this.sources3, this.destinations2, Renderer.spotLightEffect);
            for (int i = 0; i < SpotLight.All.Count; i++)
            {
                SpotLight light = SpotLight.All[i];
                if (!light.Enabled || light.Suspended || light.Attenuation == 0.0f || light.Color.Value.LengthSquared() == 0.0f || !originalBoundingFrustum.Intersects(light.BoundingFrustum))
                {
                    continue;
                }

                this.lightingManager.SetSpotLightParameters(light, Renderer.spotLightEffect, originalCameraPosition);
                this.applyEffect(Renderer.spotLightEffect);
                this.drawModel(Renderer.spotLightModel);
            }

            // Point lights
            Renderer.pointLightEffect.Parameters["Materials"].SetValue(parameters.MaterialData);
            this.setTargetParameters(this.sources3, this.destinations2, Renderer.pointLightEffect);
            for (int i = 0; i < PointLight.All.Count; i++)
            {
                PointLight light = PointLight.All[i];
                if (!light.Enabled || light.Suspended || light.Attenuation == 0.0f || light.Color.Value.LengthSquared() == 0.0f || !originalBoundingFrustum.Intersects(light.BoundingSphere))
                {
                    continue;
                }
                this.lightingManager.SetPointLightParameters(light, Renderer.pointLightEffect, originalCameraPosition);
                this.applyEffect(Renderer.pointLightEffect);
                this.drawModel(Renderer.pointLightModel);
            }

            if (!parameters.ReverseCullOrder)
            {
                this.main.GraphicsDevice.RasterizerState = originalState;
            }

            RenderTarget2D colorSource      = this.colorBuffer1;
            RenderTarget2D colorDestination = this.hdrBuffer2;
            RenderTarget2D colorTemp        = null;

            // Compositing
            this.compositeEffect.CurrentTechnique = this.compositeEffect.Techniques[enableSSAO ? "CompositeSSAO" : "Composite"];
            this.lightingManager.SetCompositeParameters(this.compositeEffect);
            parameters.Camera.SetParameters(this.compositeEffect);
            this.compositeEffect.Parameters["Materials"].SetValue(parameters.MaterialData);
            RenderTarget2D[] compositeSources;
            if (enableSSAO)
            {
                compositeSources    = this.sources4;
                compositeSources[3] = this.halfBuffer2;
            }
            else
            {
                compositeSources = this.sources3;
            }

            compositeSources[0] = colorSource;
            compositeSources[1] = this.lightingBuffer;
            compositeSources[2] = this.specularBuffer;

            this.destinations1[0] = colorDestination;

            if (!this.preparePostProcess(compositeSources, this.destinations1, this.compositeEffect))
            {
                return;
            }

            Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

            bool enableBloom      = this.allowBloom && this.EnableBloom;
            bool enableMotionBlur = this.MotionBlurAmount > 0.0f;

#if VR
            if (this.main.VR)
            {
                enableMotionBlur = false;
            }
#endif

            bool enableBlur = this.BlurAmount > 0.0f;

            // Swap the color buffers
            colorSource      = this.hdrBuffer2;
            colorDestination = enableBloom || this.allowToneMapping || enableBlur || enableMotionBlur ? this.hdrBuffer1 : result;

            parameters.DepthBuffer = this.depthBuffer;
            parameters.FrameBuffer = colorSource;

            // Alpha components

            // Drawing to the color destination
            this.destinations1[0] = colorDestination;
            if (!this.setTargets(this.destinations1))
            {
                return;
            }

            // Copy the color source to the destination
            this.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, originalState);
            this.spriteBatch.Draw(colorSource, Vector2.Zero, Color.White);
            this.spriteBatch.End();

            parameters.Camera.Position.Value = originalCameraPosition;
            parameters.Camera.View.Value     = originalViewMatrix;

            this.main.DrawAlphaComponents(parameters);
            this.main.DrawPostAlphaComponents(parameters);

            // Swap the color buffers
            colorTemp              = colorDestination;
            colorDestination       = colorSource;
            parameters.FrameBuffer = colorSource = colorTemp;

            // Bloom
            if (enableBloom)
            {
                this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["Downsample"];
                this.sources1[0]      = colorSource;
                this.destinations1[0] = this.halfBuffer1;
                if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["BlurHorizontal"];
                this.sources1[0]      = this.halfBuffer1;
                this.destinations1[0] = this.halfBuffer2;
                if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["BlurVertical"];
                this.sources1[0]      = this.halfBuffer2;
                this.destinations1[0] = this.halfBuffer1;
                if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["Composite"];
                this.sources2[0]      = colorSource;
                this.sources2[1]      = this.halfBuffer1;
                this.destinations1[0] = enableBlur || enableMotionBlur ? this.colorBuffer2 : result;
                if (!this.preparePostProcess(this.sources2, this.destinations1, this.bloomEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                // Swap the color buffers
                colorDestination = this.colorBuffer1;
                colorSource      = this.colorBuffer2;
            }
            else if (this.allowToneMapping)
            {
                this.bloomEffect.CurrentTechnique = this.bloomEffect.Techniques["ToneMapOnly"];
                this.sources1[0]      = colorSource;
                this.destinations1[0] = enableBlur || enableMotionBlur ? this.colorBuffer2 : result;
                if (!this.preparePostProcess(this.sources1, this.destinations1, this.bloomEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                // Swap the color buffers
                colorDestination = this.colorBuffer1;
                colorSource      = this.colorBuffer2;
            }

            // Motion blur
            if (enableMotionBlur)
            {
                this.motionBlurEffect.CurrentTechnique = this.motionBlurEffect.Techniques["MotionBlur"];
                parameters.Camera.SetParameters(this.motionBlurEffect);

                // If we just reallocated our buffers, don't use the velocity buffer from the last frame because it will be empty
                this.sources3[0]      = colorSource;
                this.sources3[1]      = this.normalBuffer;
                this.sources3[2]      = this.justReallocatedBuffers ? this.normalBuffer : this.normalBufferLastFrame;
                this.destinations1[0] = enableBlur ? colorDestination : result;
                if (!this.preparePostProcess(this.sources3, this.destinations1, this.motionBlurEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);

                // Swap the velocity buffers
                RenderTarget2D temp = this.normalBufferLastFrame;
                this.normalBufferLastFrame = this.normalBuffer;
                this.normalBuffer          = temp;

                // Swap the color buffers
                colorTemp        = colorDestination;
                colorDestination = colorSource;
                colorSource      = colorTemp;
            }

            if (enableBlur)
            {
                // Blur
                this.blurEffect.CurrentTechnique = this.blurEffect.Techniques["BlurHorizontal"];
                parameters.Camera.SetParameters(this.blurEffect);
                this.sources1[0]      = colorSource;
                this.destinations1[0] = colorDestination;
                if (!this.preparePostProcess(this.sources1, this.destinations1, this.blurEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);
                this.blurEffect.CurrentTechnique = this.blurEffect.Techniques["Composite"];

                // Swap the color buffers
                colorTemp        = colorDestination;
                colorDestination = colorSource;
                colorSource      = colorTemp;

                this.sources1[0]      = colorSource;
                this.destinations1[0] = result;
                if (!this.preparePostProcess(this.sources1, this.destinations1, this.blurEffect))
                {
                    return;
                }
                Renderer.quad.DrawAlpha(this.main.GameTime, RenderParameters.Default);
            }

            parameters.DepthBuffer = null;
            parameters.FrameBuffer = null;

            this.justReallocatedBuffers = false;
        }