Пример #1
0
        public void Blur(RenderTarget2D source, RenderTarget2D destination, float sigma)
        {
            if (width != source.Width || height != source.Height || this.sigma != sigma)
            {
                CalculateWeights(source.Width, source.Height, sigma);
            }

            effect.Parameters["Resolution"].SetValue(new Vector2(width, height));

            var intermediate = RenderTargetManager.GetTarget(device, width, height, destination.Format, name: "gaussian intermediate");

            device.SetRenderTarget(intermediate);

            effect.Parameters["Texture"].SetValue(source);
            effect.CurrentTechnique = effect.Techniques["BlurHorizontal"];
            quad.Draw(effect);

            device.SetRenderTarget(destination);

            effect.Parameters["Texture"].SetValue(intermediate);
            effect.CurrentTechnique = effect.Techniques["BlurVertical"];
            quad.Draw(effect);

            RenderTargetManager.RecycleTarget(intermediate);
        }
Пример #2
0
        private void CalculateLuminance(Renderer renderer, Box <Vector2> resolution, GraphicsDevice device, Texture2D lightBuffer)
        {
            var tmp = previous;

            previous = current;
            current  = tmp;

            // calculate luminance map
            var luminanceMap = RenderTargetManager.GetTarget(device, 1024, 1024, SurfaceFormat.Single, mipMap: true, name: "luminance map");

            device.SetRenderTarget(luminanceMap);
            device.BlendState = BlendState.Opaque;
            device.Clear(Color.Transparent);
            calculateLuminance.Parameters["Texture"].SetValue(lightBuffer);
            quad.Draw(calculateLuminance, renderer.Data);
            Output("luminance", luminanceMap);

            // read bottom mipmap to find average luminance
            averageLuminance = RenderTargetManager.GetTarget(device, 1, 1, SurfaceFormat.Single, name: "average luminance");
            device.SetRenderTarget(averageLuminance);
            readLuminance.Parameters["Texture"].SetValue(luminanceMap);
            quad.Draw(readLuminance, renderer.Data);

            // adapt towards the current luminance
            device.SetRenderTarget(adaptedLuminance[current]);
            adaptLuminance.Parameters["Texture"].SetValue(averageLuminance);
            adaptLuminance.Parameters["PreviousAdaption"].SetValue(adaptedLuminance[previous]);
            quad.Draw(adaptLuminance, renderer.Data);
        }
Пример #3
0
        public override void Draw(Renderer renderer)
        {
            var metadata = renderer.Data;
            var device   = renderer.Device;

            var resolution = metadata.Get <Vector2>("resolution").Value;
            var width      = (int)resolution.X;
            var height     = (int)resolution.Y;

            var depth   = RenderTargetManager.GetTarget(device, width, height, SurfaceFormat.Single, DepthFormat.Depth24Stencil8, name: "depth");
            var normals = RenderTargetManager.GetTarget(device, width, height, SurfaceFormat.Rgba1010102, name: "normals");
            var diffuse = RenderTargetManager.GetTarget(device, width, height, SurfaceFormat.Color, name: "diffuse");

            device.SetRenderTargets(depth, normals, diffuse);
            device.BlendState = BlendState.Opaque;
            device.Clear(Color.Black);

            device.DepthStencilState = DepthStencilState.None;
            quad.Draw(clear, metadata);
            device.DepthStencilState = DepthStencilState.Default;

            device.BlendState = BlendState.Opaque;

            foreach (var geometryProvider in renderer.Scene.FindManagers <IGeometryProvider>())
            {
                geometryProvider.Draw("gbuffer", metadata);
            }

            Output("gbuffer_depth", depth);
            Output("gbuffer_normals", normals);
            Output("gbuffer_diffuse", diffuse);

            DownsampleDepth(renderer, depth);
        }
Пример #4
0
        private void DownsampleDepth(Renderer renderer, RenderTarget2D depth)
        {
            var downsampled = RenderTargetManager.GetTarget(renderer.Device, depth.Width / 2, depth.Height / 2, SurfaceFormat.Single, name: "downsample depth");

            scale.Scale(depth, downsampled);
            Output("gbuffer_depth_downsample", downsampled);
        }
Пример #5
0
        public override void Draw(Renderer renderer)
        {
            var resolution = renderer.Data.Get <Vector2>("resolution").Value;

            //if (renderer.Data.Get<float>("ssao_radiosityintensity").Value > 0)
            //    ssaoMaterial.CurrentTechnique = ssaoMaterial.Techniques["SSGI"];
            //else
            //{
            if (renderer.Data.Get <bool>("ssao_highquality").Value)
            {
                ssaoMaterial.CurrentTechnique = ssaoMaterial.Techniques["HQ_SSAO"];
            }
            else
            {
                ssaoMaterial.CurrentTechnique = ssaoMaterial.Techniques["LQ_SSAO"];
            }
            //}

            var unblured = RenderTargetManager.GetTarget(renderer.Device, (int)resolution.X, (int)resolution.Y, surfaceFormat: SurfaceFormat.HalfVector4, name: "ssao unblurred");//, SurfaceFormat.HalfVector4);

            renderer.Device.SetRenderTarget(unblured);
            renderer.Device.Clear(Color.Transparent);
            renderer.Device.BlendState = BlendState.Opaque;
            quad.Draw(ssaoMaterial, renderer.Data);

            ssao = RenderTargetManager.GetTarget(renderer.Device, (int)resolution.X, (int)resolution.Y, SurfaceFormat.HalfVector4, name: "ssao");
            renderer.Device.SetRenderTarget(ssao);
            renderer.Device.Clear(Color.Transparent);
            ssaoBlurMaterial.Parameters["SSAO"].SetValue(unblured);
            quad.Draw(ssaoBlurMaterial, renderer.Data);
            RenderTargetManager.RecycleTarget(unblured);

            Output("ssao", ssao);
        }
Пример #6
0
        public void Scale(RenderTarget2D source, RenderTarget2D destination)
        {
            effect.CurrentTechnique = source.Format.IsFloatingPoint() ? effect.Techniques["Software"] : effect.Techniques["Hardware"];

            Vector2 resolution  = new Vector2(source.Width, source.Height);
            float   ScaleFactor = (destination.Width > source.Width) ? 2 : 0.5f;

            RenderTarget2D input  = source;
            RenderTarget2D output = null;

            while (IntermediateNeeded(resolution, destination, ScaleFactor))
            {
                resolution *= ScaleFactor;

                output = RenderTargetManager.GetTarget(device, (int)resolution.X, (int)resolution.Y, source.Format, name: "scaled");
                Draw(input, output);

                if (input != source)
                {
                    RenderTargetManager.RecycleTarget(input);
                }
                input = output;
            }

            Draw(input, destination);

            if (input != source)
            {
                RenderTargetManager.RecycleTarget(input);
            }
        }
Пример #7
0
            public override void Draw(Renderer renderer)
            {
                KeyboardState keyboard = Keyboard.GetState();

                if (keyboard.IsKeyDown(Keys.Space) && previousKeyboard.IsKeyUp(Keys.Space))
                {
                    drawGBuffer = !drawGBuffer;
                }
                previousKeyboard = keyboard;

                var metadata   = renderer.Data;
                var resolution = renderer.Data.Get <Vector2>("resolution").Value;
                var targetInfo = new RenderTargetInfo()
                {
                    Width = (int)resolution.X, Height = (int)resolution.Y, SurfaceFormat = SurfaceFormat.Rgba64
                };
                var target = RenderTargetManager.GetTarget(renderer.Device, targetInfo);

                renderer.Device.SetRenderTarget(target);

                var depth   = metadata.Get <Texture2D>("gbuffer_depth").Value;
                var normals = metadata.Get <Texture2D>("gbuffer_normals").Value;
                var diffuse = metadata.Get <Texture2D>("gbuffer_diffuse").Value;
                var light   = metadata.Get <Texture2D>("lightbuffer").Value;

                //using (var stream = File.Create("lightbuffer.jpg"))
                //    light.SaveAsJpeg(stream, light.Width, light.Height);

                var halfWidth  = (int)(resolution.X / 2);
                var halfHeight = (int)(resolution.Y / 2);

                batch.GraphicsDevice.Clear(Color.Black);
                batch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);

                if (drawGBuffer)
                {
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
                    batch.Draw(depth, new Rectangle(0, 0, halfWidth, halfHeight), Color.White);
                    batch.Draw(light, new Rectangle(halfWidth, halfHeight, halfWidth, halfHeight), Color.White);
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;

                    batch.Draw(normals, new Rectangle(halfWidth, 0, halfWidth, halfHeight), Color.White);
                    batch.Draw(diffuse, new Rectangle(0, halfHeight, halfWidth, halfHeight), Color.White);
                }
                else
                {
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
                    batch.Draw(light, new Rectangle(0, 0, (int)resolution.X, (int)resolution.Y), Color.White);
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;
                }

                batch.End();

                Output("scene", target);
            }
Пример #8
0
            public override void Draw(Renderer renderer)
            {
                var target = RenderTargetManager.GetTarget(renderer.Device, new RenderTargetInfo()
                {
                    Height = 50, Width = 50
                });

                renderer.Device.SetRenderTarget(target);
                spriteBatch.Begin();
                spriteBatch.DrawString(font, "B", Vector2.Zero, Color.White);
                spriteBatch.End();

                Output("b", target);
            }
Пример #9
0
            public override void Draw(Renderer renderer)
            {
                var target = RenderTargetManager.GetTarget(renderer.Device, 1280, 720);

                renderer.Device.SetRenderTarget(target);

                var metadata = renderer.Data;
                var c        = metadata.Get <Texture2D>("c").Value;

                spriteBatch.Begin();
                spriteBatch.Draw(c, new Rectangle(590, 335, 100, 50), Color.White);
                spriteBatch.End();

                Output("d", target);
            }
Пример #10
0
        private void ToneMap(Renderer renderer, Box <Vector2> resolution, GraphicsDevice device, Texture2D lightBuffer)
        {
            var toneMapped = RenderTargetManager.GetTarget(device, (int)resolution.Value.X, (int)resolution.Value.Y, SurfaceFormat.Color, depthFormat: DepthFormat.Depth24Stencil8, name: "tone mapped");

            device.SetRenderTarget(toneMapped);
            device.Clear(Color.Transparent);
            device.DepthStencilState = DepthStencilState.None;
            device.BlendState        = BlendState.Opaque;

            toneMap.Parameters["Texture"].SetValue(lightBuffer);
            toneMap.Parameters["Luminance"].SetValue(adaptedLuminance[current]);
            toneMap.Parameters["MinExposure"].SetValue(renderer.Data.Get <float>("hdr_minexposure").Value);
            toneMap.Parameters["MaxExposure"].SetValue(renderer.Data.Get <float>("hdr_maxexposure").Value);
            quad.Draw(toneMap, renderer.Data);
            Output("tonemapped", toneMapped);
        }
Пример #11
0
        private void DrawShadowMap(Renderer renderer, LightData data)
        {
            var light = data.Light;

            var target = RenderTargetManager.GetTarget(renderer.Device, light.ShadowResolution, light.ShadowResolution, SurfaceFormat.Single, DepthFormat.Depth24Stencil8, name: "spot light shadow map");

            renderer.Device.SetRenderTarget(target);
            renderer.Device.Clear(Color.Black);

            var resolution         = renderer.Data.Get <Vector2>("resolution");
            var previousResolution = resolution.Value;

            resolution.Value = new Vector2(light.ShadowResolution);

            renderer.Device.DepthStencilState = DepthStencilState.Default;
            renderer.Device.BlendState        = BlendState.Opaque;
            renderer.Device.RasterizerState   = RasterizerState.CullCounterClockwise;

            var view         = renderer.Data.Get <View>("activeview");
            var previousView = view.Value;

            view.Value = shadowView;

            data.View = Matrix.CreateLookAt(
                light.Position,
                light.Position + light.Direction,
                light.Direction == Vector3.Up || light.Direction == Vector3.Down ? Vector3.Right : Vector3.Up);
            data.Projection = Matrix.CreatePerspectiveFieldOfView(light.Angle, 1, 1, light.Range);

            shadowView.Camera.View       = data.View;
            shadowView.Camera.Projection = data.Projection;
            shadowView.Camera.NearClip   = 1;
            shadowView.Camera.FarClip    = light.Range;
            shadowView.Viewport          = new Viewport(0, 0, light.ShadowResolution, light.ShadowResolution);
            shadowView.SetMetadata(renderer.Data);

            foreach (var item in renderer.Scene.FindManagers <IGeometryProvider>())
            {
                item.Draw("shadows_viewlength", renderer.Data);
            }

            data.ShadowMap   = target;
            resolution.Value = previousResolution;
            previousView.SetMetadata(renderer.Data);
            view.Value = previousView;
        }
Пример #12
0
        private void Bloom(Renderer renderer, Box <Vector2> resolution, GraphicsDevice device, Texture2D lightBuffer)
        {
            var screenResolution  = resolution.Value;
            var halfResolution    = screenResolution / 2;
            var quarterResolution = halfResolution / 2;

            // downsample the light buffer to half resolution, and threshold at the same time
            var thresholded = RenderTargetManager.GetTarget(device, (int)halfResolution.X, (int)halfResolution.Y, SurfaceFormat.Rgba64, name: "bloom thresholded");

            device.SetRenderTarget(thresholded);
            bloom.Parameters["Resolution"].SetValue(halfResolution);
            bloom.Parameters["Threshold"].SetValue(renderer.Data.Get <float>("hdr_bloomthreshold").Value);
            bloom.Parameters["MinExposure"].SetValue(renderer.Data.Get <float>("hdr_minexposure").Value);
            bloom.Parameters["MaxExposure"].SetValue(renderer.Data.Get <float>("hdr_maxexposure").Value);
            bloom.Parameters["Texture"].SetValue(lightBuffer);
            bloom.Parameters["Luminance"].SetValue(adaptedLuminance[current]);
            bloom.CurrentTechnique = bloom.Techniques["ThresholdDownsample2X"];
            quad.Draw(bloom);

            // downsample again to quarter resolution
            var downsample = RenderTargetManager.GetTarget(device, (int)quarterResolution.X, (int)quarterResolution.Y, SurfaceFormat.Rgba64, name: "bloom downsampled");

            device.SetRenderTarget(downsample);
            bloom.Parameters["Resolution"].SetValue(quarterResolution);
            bloom.Parameters["Texture"].SetValue(thresholded);
            bloom.CurrentTechnique = bloom.Techniques["Scale"];
            quad.Draw(bloom);

            // blur the target
            var blurred = RenderTargetManager.GetTarget(device, (int)quarterResolution.X, (int)quarterResolution.Y, SurfaceFormat.Rgba64, name: "bloom blurred");

            gaussian.Blur(downsample, blurred, renderer.Data.Get <float>("hdr_bloomblurammount").Value);

            // upscale back to half resolution
            device.SetRenderTarget(thresholded);
            bloom.Parameters["Resolution"].SetValue(halfResolution);
            bloom.Parameters["Texture"].SetValue(blurred);
            quad.Draw(bloom);

            // output result
            Output("bloom", thresholded);

            // cleanup temp render targets
            RenderTargetManager.RecycleTarget(downsample);
            RenderTargetManager.RecycleTarget(blurred);
        }
Пример #13
0
            public override void Draw(Renderer renderer)
            {
                var resolution = renderer.Data.Get <Vector2>("resolution").Value;
                var targetInfo = new RenderTargetInfo()
                {
                    Width = (int)resolution.X, Height = (int)resolution.Y
                };
                var target = RenderTargetManager.GetTarget(renderer.Device, targetInfo);

                renderer.Device.SetRenderTarget(target);

                batch.Begin();
                batch.DrawString(Font, "This is being drawn by a RenderPhase!", new Vector2(640, 360), Color.White);
                batch.End();

                Output("scene", target);
            }
Пример #14
0
            public override void Draw(Renderer renderer)
            {
                var target = RenderTargetManager.GetTarget(renderer.Device, 50, 100);

                renderer.Device.SetRenderTarget(target);

                var metadata = renderer.Data;
                var a        = metadata.Get <Texture2D>("a").Value;
                var b        = metadata.Get <Texture2D>("b").Value;

                spriteBatch.Begin();
                spriteBatch.Draw(a, new Rectangle(0, 0, 50, 50), Color.White);
                spriteBatch.Draw(b, new Rectangle(50, 0, 50, 50), Color.White);
                spriteBatch.End();

                Output("c", target);
            }
Пример #15
0
            public override void Draw(Renderer renderer)
            {
                var metadata   = renderer.Data;
                var resolution = renderer.Data.Get <Vector2>("resolution").Value;
                var targetInfo = new RenderTargetInfo()
                {
                    Width = (int)resolution.X, Height = (int)resolution.Y, SurfaceFormat = SurfaceFormat.Rgba64, DepthFormat = DepthFormat.Depth24Stencil8
                };
                var target = RenderTargetManager.GetTarget(renderer.Device, targetInfo);

                renderer.Device.SetRenderTarget(target);

                var light     = metadata.Get <Texture2D>("tonemapped").Value;
                var luminance = metadata.Get <Texture2D>("luminancemap").Value;

                //using (var stream = File.Create("luminance.jpg"))
                //    light.SaveAsJpeg(stream, light.Width, light.Height);

                var width  = (int)resolution.X;
                var height = (int)resolution.Y;

                batch.GraphicsDevice.Clear(Color.Black);
                batch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);

                if (drawScene)
                {
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
                    batch.Draw(light, new Rectangle(0, 0, width, height), Color.White);
                    //batch.Draw(luminance, new Rectangle(50, height - (height / 5) - 50, height / 5, height / 5), Color.White);
                    //batch.Draw(toneMap.AdaptedLuminance, new Rectangle(50 + 20 + (height / 5), height - (height / 5) - 50, height / 5, height / 5), Color.White);
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;
                }
                else
                {
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
                    batch.Draw(luminance, new Rectangle(0, 0, width, height), Color.White);
                    batch.GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;
                }

                batch.End();

                Output("scene", target);
            }
Пример #16
0
        public override void Draw(Renderer renderer)
        {
            var resolution = renderer.Data.Get <Vector2>("resolution").Value;
            var targetInfo = new RenderTargetInfo()
            {
                Width            = (int)resolution.X,
                Height           = (int)resolution.Y,
                SurfaceFormat    = SurfaceFormat.Color,
                DepthFormat      = DepthFormat.None,
                MultiSampleCount = 4
            };

            var target = RenderTargetManager.GetTarget(renderer.Device, targetInfo);

            renderer.Device.SetRenderTarget(target);
            renderer.Device.Clear(Colour);

            Output("scene", target);
        }
Пример #17
0
        public override void Draw(Renderer renderer)
        {
            var metadata = renderer.Data;
            var device   = renderer.Device;

            var resolution = metadata.Get <Vector2>("resolution").Value;
            var width      = (int)resolution.X;
            var height     = (int)resolution.Y;

            var target = RenderTargetManager.GetTarget(device, width, height, SurfaceFormat.Color, DepthFormat.None, name: "edges");

            device.SetRenderTarget(target);
            device.BlendState = BlendState.Opaque;
            device.Clear(Color.Black);

            edgeDetect.Parameters["TexelSize"].SetValue(new Vector2(1f / width, 1f / height));
            quad.Draw(edgeDetect, metadata);

            Output("edges", target);
        }
Пример #18
0
            public override void Draw(Renderer renderer)
            {
                var metadata   = renderer.Data;
                var resolution = renderer.Data.Get <Vector2>("resolution").Value;
                var targetInfo = new RenderTargetInfo()
                {
                    Width = (int)resolution.X, Height = (int)resolution.Y
                };
                var target = RenderTargetManager.GetTarget(renderer.Device, targetInfo);

                renderer.Device.SetRenderTarget(target);

                var depth   = metadata.Get <Texture2D>("gbuffer_depth").Value;
                var normals = metadata.Get <Texture2D>("gbuffer_normals").Value;
                var diffuse = metadata.Get <Texture2D>("gbuffer_diffuse").Value;

                //Save(depth, "depth.jpg");
                //Save(normals, "normal.jpg");
                //Save(diffuse, "diffuse.jpg");

                var halfWidth  = (int)(resolution.X / 2);
                var halfHeight = (int)(resolution.Y / 2);

                batch.GraphicsDevice.Clear(Color.Black);
                batch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);

                batch.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
                batch.Draw(depth, new Rectangle(0, 0, halfWidth, halfHeight), Color.White);
                batch.GraphicsDevice.SamplerStates[0] = SamplerState.LinearClamp;

                batch.Draw(normals, new Rectangle(halfWidth, 0, halfWidth, halfHeight), Color.White);
                batch.Draw(diffuse, new Rectangle(0, halfHeight, halfWidth, halfHeight), Color.White);
                batch.End();

                Output("scene", target);
            }
Пример #19
0
        public override void Draw(Renderer renderer)
        {
            var metadata = renderer.Data;
            var device   = renderer.Device;

            var resolution = metadata.Get <Vector2>("resolution").Value;
            var width      = (int)resolution.X;
            var height     = (int)resolution.Y;

            // prepare direct lights
            for (int i = 0; i < directLights.Count; i++)
            {
                directLights[i].Prepare(renderer);
            }

            // set and clear direct light buffer
            directLightBuffer = RenderTargetManager.GetTarget(device, width, height, SurfaceFormat.HdrBlendable, DepthFormat.Depth24Stencil8);
            device.SetRenderTarget(directLightBuffer);
            device.Clear(Color.Transparent);

            // work around for a bug in xna 4.0
            renderer.Device.SamplerStates[0] = SamplerState.LinearClamp;
            renderer.Device.SamplerStates[0] = SamplerState.PointClamp;

            // set render states to draw opaque geometry
            device.BlendState        = BlendState.Opaque;
            device.DepthStencilState = DepthStencilState.Default;

            // restore depth
            quad.Draw(restoreDepth, metadata);

            // set render states to additive blend
            device.BlendState = BlendState.Additive;

            // draw direct lights
            for (int i = 0; i < directLights.Count; i++)
            {
                directLights[i].Draw(renderer);
            }

            // output direct lighting
            Output("directlighting", directLightBuffer);

            // prepare indirect lights
            for (int i = 0; i < indirectLights.Count; i++)
            {
                indirectLights[i].Prepare(renderer);
            }

            // set and clear indirect light buffer
            indirectLightBuffer = RenderTargetManager.GetTarget(device, width, height, SurfaceFormat.HdrBlendable, DepthFormat.Depth24Stencil8);
            device.SetRenderTarget(indirectLightBuffer);
            device.Clear(Color.Transparent);

            //draw indirect lights
            for (int i = 0; i < indirectLights.Count; i++)
            {
                indirectLights[i].Draw(renderer);
            }

            // blend direct lighting into the indirect light buffer
            copyTexture.Parameters["Texture"].SetValue(directLightBuffer);
            quad.Draw(copyTexture, metadata);

            // output resulting light buffer
            Output("lightbuffer", indirectLightBuffer);
        }