public override void Initialize()
        {
            base.Initialize();

            bool isDepthStencilAsShaderResourceRequired = RenderSystem.ConfigContext.RenderPassPlugins.Any(plugin => plugin.Value.Tags.Get(RenderTargetKeys.RequireDepthStencilShaderResource));

            // By default, the MainPlugin is using the back buffer as the render target
            RenderTarget = GraphicsDevice.BackBuffer;

            // Create depth stencil
#if SILICONSTUDIO_XENKO_GRAPHICS_API_OPENGLES
            var depthStencilFormat = PixelFormat.D16_UNorm;
#else
            var depthStencilFormat = PixelFormat.D24_UNorm_S8_UInt;
#endif

            if (GraphicsDevice.DepthStencilBuffer != null)
            {
                DepthStencil = GraphicsDevice.DepthStencilBuffer;
            }
            else
            {
                var depthStencil = Texture.New2D(GraphicsDevice, RenderTarget.Width, RenderTarget.Height, depthStencilFormat, TextureFlags.DepthStencil | (isDepthStencilAsShaderResourceRequired ? TextureFlags.ShaderResource : TextureFlags.None));
                DepthStencil = depthStencil.ToDepthStencilBuffer(false);
            }

            if (DepthStencilBuffer.IsReadOnlySupported(GraphicsDevice))
            {
                DepthStencilReadOnly = DepthStencil.Texture.ToDepthStencilBuffer(true);
            }
        }
Exemple #2
0
        public void TestDepthStencilBufferWithNativeReadonly()
        {
            //// Without shaders, it is difficult to check this method without accessing internals
            //// Force to create a device
            var device = GraphicsDevice.New(DeviceCreationFlags.None, GraphicsProfile.Level_11_0);

            // Check that reaonly is not supported for depth stencil buffer
            Assert.That(DepthStencilBuffer.IsReadOnlySupported(device), Is.True);

            // Check texture creation with an array of data, with usage default to later allow SetData
            var texture = Texture2D.New(device, 256, 256, PixelFormat.D32_Float, TextureFlags.ShaderResource | TextureFlags.DepthStencil);

            // Creates a new depth stencil buffer
            var depthStencilBuffer = texture.ToDepthStencilBuffer(true);

            // Clear the depth stencil buffer with a value of 0.5f, but the depth buffer is readonly
            device.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer, 0.5f);

            var values = texture.GetData <float>();

            Assert.That(values.Length, Is.EqualTo(256 * 256));
            Assert.That(values[0], Is.EqualTo(0.0f));

            // Dispose the depth stencil buffer
            depthStencilBuffer.Dispose();

            device.Dispose();
        }
Exemple #3
0
        public void TestDepthStencilBuffer()
        {
            // Force to create a device
            var device = GraphicsDevice.New(DeviceCreationFlags.None, GraphicsProfile.Level_10_0);

            // Check that reaonly is not supported for depth stencil buffer
            Assert.That(DepthStencilBuffer.IsReadOnlySupported(device), Is.False);

            // Check texture creation with an array of data, with usage default to later allow SetData
            var texture = Texture2D.New(device, 256, 256, PixelFormat.D32_Float, TextureFlags.DepthStencil);

            // Creates a new depth stencil buffer
            var depthStencilBuffer = texture.ToDepthStencilBuffer(false);

            // Clear the depth stencil buffer with a value of 0.5f
            device.Clear(depthStencilBuffer, DepthStencilClearOptions.DepthBuffer, 0.5f);

            var values = texture.GetData <float>();

            Assert.That(values.Length, Is.EqualTo(256 * 256));
            Assert.That(values[0], Is.EqualTo(0.5f));

            // Create a new copy of the depth stencil buffer
            var textureCopy = texture.ToDepthTextureCompatible();

            device.Copy(texture, textureCopy);

            values = textureCopy.GetData <float>();
            Assert.That(values.Length, Is.EqualTo(256 * 256));
            Assert.That(values[0], Is.EqualTo(0.5f));

            // Dispose the depth stencil buffer
            depthStencilBuffer.Dispose();

            device.Dispose();
        }
Exemple #4
0
        /// <inheritdoc/>
        public override void Initialize()
        {
            base.Initialize();
            graphicsDeviceService = Services.GetServiceAs <IGraphicsDeviceService>();
            var graphicsDevice = graphicsDeviceService.GraphicsDevice;


            Parameters.AddSources(MainPlugin.ViewParameters);

            if (OfflineCompilation)
            {
                return;
            }

            // Create texture used for normal packing
            var texture2D = Texture2D.New(GraphicsDevice, 1024, 1024, 1, PixelFormat.A8_UNorm);

            texture2D.Name = "Renorm";

            // Load normal packing data
            var texDataStream = VirtualFileSystem.OpenStream("/assets/effects/gbuffer/renorm.bin", VirtualFileMode.Open, VirtualFileAccess.Read);
            var texFileLength = texDataStream.Length;
            var texData       = new byte[texFileLength];

            texDataStream.Read(texData, 0, (int)texFileLength);
            texture2D.SetData(graphicsDevice, texData);
            texDataStream.Dispose();

            // Force custom depth stencil state on main pass
            var mainDepthStencilState = MainTargetPlugin.Parameters.TryGet(EffectPlugin.DepthStencilStateKey) ?? graphicsDevice.DepthStencilStates.Default;

            MainTargetPlugin.Parameters.Set(EffectPlugin.DepthStencilStateKey, mainDepthStencilState);

            // Use depth stencil value from MainPlugin
            var defaultDescription = mainDepthStencilState.Description;

            ClearDepth = MainTargetPlugin.ClearDepth;

            // Use Default ZTest for GBuffer
            var depthStencilStateZStandard = DepthStencilState.New(GraphicsDevice, defaultDescription);

            depthStencilStateZStandard.Name = "ZStandard";

            Parameters.Set(EffectPlugin.DepthStencilStateKey, depthStencilStateZStandard);

            Parameters.Set(GBufferKeys.NormalPack, texture2D);
            Parameters.Set(TexturingKeys.PointSampler, graphicsDevice.SamplerStates.PointWrap);

            // MainPlugin is going to use the readonly depth stencil buffer
            if (DepthStencilBuffer.IsReadOnlySupported(GraphicsDevice))
            {
                MainTargetPlugin.UseDepthStencilReadOnly = true;
                MainTargetPlugin.Parameters.Set(RenderTargetKeys.DepthStencilSource, DepthStencil.Texture);
                MainTargetPlugin.DepthStencilReadOnly = DepthStencil.Texture.ToDepthStencilBuffer(true);
            }
            else
            {
                RenderPass.EndPass += (context) =>
                {
                    //context.GraphicsDevice.Copy(DepthStencil

                    //DepthStencil.SynchronizeReadonly(context.GraphicsDevice)
                };
            }

            defaultDescription = mainDepthStencilState.Description;
            defaultDescription.DepthBufferWriteEnable = false;
            DepthStencilStateZReadOnly      = DepthStencilState.New(GraphicsDevice, defaultDescription);
            DepthStencilStateZReadOnly.Name = "ZReadOnly";

            // Create normal texture (that LightPlugin will use)
            var gbufferTexture = Texture2D.New(GraphicsDevice, graphicsDevice.BackBuffer.Width, graphicsDevice.BackBuffer.Height, PixelFormat.R8G8B8A8_UNorm, TextureFlags.ShaderResource | TextureFlags.RenderTarget);

            gbufferTexture.Name = "GBufferTexture";
            Parameters.Set(GBufferBaseKeys.GBufferTexture, gbufferTexture);
            RenderTarget = gbufferTexture.ToRenderTarget();

            // Set parameters for MainPlugin
            MainTargetPlugin.Parameters.Set(GBufferBaseKeys.GBufferTexture, gbufferTexture);
        }
Exemple #5
0
        public void Initialize(IServiceRegistry registry, string effectFilename = null, string[] optionalFeatures = null)
        {
            // Missing features compared to before: ZInverse support, Picking/Wireframe, Heat Shimmering and light shafts bounding boxes.
            // Other stuff to implement: Enable features by RenderPipeline, reloading, access of plugins through a flexible interface, yebis config.
            renderSystem          = registry.GetSafeServiceAs <IRenderSystem>();
            graphicsDeviceService = registry.GetSafeServiceAs <IGraphicsDeviceService>();
            this.effectSystemOld  = registry.GetSafeServiceAs <IEffectSystemOld>();
            entitySystem          = registry.GetSafeServiceAs <IEntitySystem>();

            var rootRenderPass = renderSystem.RootRenderPass;
            var dataContext    = RenderConfigContext = renderSystem.ConfigContext;
            var graphicsDevice = graphicsDeviceService.GraphicsDevice;

            if (effectFilename == null)
            {
                effectFilename = Path.Combine("/shaders/effects.xml");
            }

            var context          = new XenkoXamlSchemaContext(dataContext);
            var xamlObjectWriter = new XamlObjectWriter(context);

            using (var fileStream = VirtualFileSystem.OpenStream(effectFilename, VirtualFileMode.Open, VirtualFileAccess.Read))
                XamlServices.Transform(new XamlXmlReader(fileStream, context), xamlObjectWriter);

            var effectConfig = (RenderConfig)xamlObjectWriter.Result;

            foreach (var renderPass in effectConfig.Content.OfType <RenderPass>())
            {
                dataContext.RenderPasses.Add(renderPass.Name, renderPass);
                rootRenderPass.AddPass(renderPass);
            }

            foreach (var item in effectConfig.Content)
            {
                var plugin = item as RenderPassPlugin;
                if (plugin != null)
                {
                    dataContext.RenderPassPlugins.Add(plugin.Name, plugin);
                }

                var setter = item as Setter;
                if (setter != null)
                {
                    PropertyPath.SetNextValue(setter.Target, setter.Property, setter.Value);
                }
            }

            MainPlugin       = dataContext.RenderPassPlugins.Select(x => x.Value).OfType <MainPlugin>().First();
            MainTargetPlugin = dataContext.RenderPassPlugins.Select(x => x.Value).OfType <RenderTargetsPlugin>().FirstOrDefault(x => x.Name == "MainTargetPlugin");

            var mainBackBuffer = graphicsDevice.BackBuffer;

            MainPlugin.RenderTarget = graphicsDevice.BackBuffer;

            // Depth Stencil target needs to be shader resource only if Yebis or GBuffer is active (need more robust way to decide)
            var depthStencilTexture = Texture.New2D(graphicsDevice, mainBackBuffer.Width, mainBackBuffer.Height, PixelFormat.D32_Float,
                                                    (RenderConfigContext.RenderPassPlugins.Any(x => x.Value is YebisPlugin || x.Value is GBufferPlugin) ? TextureFlags.ShaderResource : 0) | TextureFlags.DepthStencil);

            MainPlugin.DepthStencil = depthStencilTexture.ToDepthStencilBuffer(false);

            if (DepthStencilBuffer.IsReadOnlySupported(graphicsDevice))
            {
                MainPlugin.DepthStencilReadOnly = depthStencilTexture.ToDepthStencilBuffer(true);
            }

            // TODO: Temporary setup (should be done through an Entity and its Manager)
            HeatShimmerPlugin heatShimmerPlugin;

            if (RenderConfigContext.RenderPassPlugins.TryGetValueCast("HeatShimmerPlugin", out heatShimmerPlugin))
            {
                throw new NotImplementedException();
                //heatShimmerPlugin.BoundingBoxes.Add(new MeshData { MeshData = MeshDataHelper.CreateBox(1, 1, 1, Color.White, true), Parameters = new ParameterCollectionData { { TransformationKeys.World, Matrix.Scaling(8200, 3000, 1500) * Matrix.Translation(2700, 0, 300) } } });
                //heatShimmerPlugin.BoundingBoxes.Add(new MeshData { MeshData = MeshDataHelper.CreateBox(1, 1, 1, Color.White, true), Parameters = new ParameterCollectionData { { TransformationKeys.World, Matrix.Scaling(2000, 2000, 3500) * Matrix.RotationZ(0.5f) * Matrix.Translation(-7000, -4000, 1500) } } });
                //heatShimmerPlugin.BoundingBoxes.Add(new MeshData { MeshData = MeshDataHelper.CreateBox(1, 1, 1, Color.White, true), Parameters = new ParameterCollectionData { { TransformationKeys.World, Matrix.Scaling(2000, 3000, 3500) * Matrix.Translation(-7800, 900, 1500) } } });
            }

            // Generates intermediate render targets
            var plugins = dataContext.RenderPassPlugins
                          .OrderBy(x => rootRenderPass.Passes.IndexOf(x.Value.RenderPass)).ToArray();

            // Weave render targets from last to first plugin.
            // TODO: Instead of guessing through interface and non-null/null values, it would be better if plugin had flags to inform of its intentions.
            var currentTarget = mainBackBuffer;

            for (int i = plugins.Length - 1; i >= 0; --i)
            {
                var plugin = plugins[i];

                var targetPlugin = plugin.Value as IRenderPassPluginTarget;
                if (targetPlugin != null)
                {
                    if (targetPlugin.RenderTarget == null)
                    {
                        targetPlugin.RenderTarget = currentTarget;
                    }

                    currentTarget = targetPlugin.RenderTarget;
                }

                var sourcePlugin = plugin.Value as IRenderPassPluginSource;
                if (sourcePlugin != null)
                {
                    if (sourcePlugin.RenderSource == null)
                    {
                        sourcePlugin.RenderSource = Texture.New2D(graphicsDevice, mainBackBuffer.Width, mainBackBuffer.Height, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                    }

                    currentTarget = sourcePlugin.RenderSource.ToRenderTarget();
                }
            }

            foreach (var plugin in dataContext.RenderPassPlugins)
            {
                renderSystem.RenderPassPlugins.Add(plugin.Value);
            }

            foreach (var effectBuilder in effectConfig.Content.OfType <EffectBuilder>())
            {
                foreach (var plugin in effectBuilder.Plugins)
                {
                    plugin.Services = registry;
                }
                this.effectSystemOld.Effects.Add(effectBuilder);
            }

#if XENKO_YEBIS
            YebisPlugin yebisPlugin;
            if (RenderConfigContext.RenderPassPlugins.TryGetValueCast("YebisPlugin", out yebisPlugin))
            {
                yebisPlugin.AntiAlias = true;

                yebisPlugin.ToneMap.Gamma = 2.2f;
                yebisPlugin.ToneMap.Type  = ToneMapType.SensiToMetric;
                yebisPlugin.ToneMap.AutoExposure.Enable                    = true;
                yebisPlugin.ToneMap.AutoExposure.MiddleGray                = 0.25f;
                yebisPlugin.ToneMap.AutoExposure.AdaptationSensitivity     = 0.5f;
                yebisPlugin.ToneMap.AutoExposure.AdaptationScale           = 0.8f;
                yebisPlugin.ToneMap.AutoExposure.AdaptationSpeedLimit      = 4.0f;
                yebisPlugin.ToneMap.AutoExposure.DarkAdaptationSensitivity = 0.9f;
                yebisPlugin.ToneMap.AutoExposure.DarkAdaptationScale       = 0.6f;
                yebisPlugin.ToneMap.AutoExposure.DarkAdaptationSpeedLimit  = 4.0f;
                yebisPlugin.ToneMap.AutoExposure.LightDarkExposureBorder   = 1.0f;

                yebisPlugin.Glare.Enable = true;
                //yebisPlugin.Glare.RemapFactor = 1.0f;
                //yebisPlugin.Glare.Threshold = 0.0f;

                yebisPlugin.Lens.Vignette.Enable = true;

                yebisPlugin.Lens.Distortion.Enable         = false;
                yebisPlugin.Lens.Distortion.Power          = 0.2f;
                yebisPlugin.Lens.Distortion.EdgeSmoothness = 0.2f;

                yebisPlugin.DepthOfField.Enable            = true;
                yebisPlugin.DepthOfField.AutoFocus         = true;
                yebisPlugin.DepthOfField.Aperture          = 2.0f;
                yebisPlugin.DepthOfField.ImageSensorHeight = 40.0f;

                //yebisPlugin.ColorCorrection.ColorTemperature = 4500;

                yebisPlugin.HeatShimmer.Enable = false;
                //YebisPlugin.LightShaft.Enable = true;
                //YebisPlugin.LightShaft.ScreenPosition = new Vector2(0.5f, 0.1f);
            }
#endif

            // Adds the particle system if the ParticlePlugin is used in the config
            ParticlePlugin particlePlugin;
            if (RenderConfigContext.RenderPassPlugins.TryGetValueCast("ParticlePlugin", out particlePlugin))
            {
                var particleSystem = new ParticleProcessor(particlePlugin);
                entitySystem.Processors.Add(particleSystem);
            }
        }