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); } }
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(); }
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(); }
/// <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); }
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); } }