/// <summary> /// Performs luminance measurement, tonemapping, applies bloom. /// </summary> /// <param name="target">LDR target.</param> /// <param name="hdrImage">HDR source image.</param> public void Render(GameTime gameTime, RenderTargetSurface target, ShaderResource hdrImage) { var device = Game.GraphicsDevice; var filter = Game.GetService <Filter>(); var ds = Game.GetService <DebugStrings>(); // // Rough downsampling of source HDR-image : // filter.StretchRect(averageLum.Surface, hdrImage); averageLum.BuildMipmaps(); // // Make bloom : // filter.StretchRect(bloom0.Surface, hdrImage); bloom0.BuildMipmaps(); filter.GaussBlur(bloom0, bloom1, Config.GaussBlurSigma, 0); filter.GaussBlur(bloom0, bloom1, Config.GaussBlurSigma, 1); filter.GaussBlur(bloom0, bloom1, Config.GaussBlurSigma, 2); filter.GaussBlur(bloom0, bloom1, Config.GaussBlurSigma, 3); // // Setup parameters : // var paramsData = new Params(); paramsData.AdaptationRate = 1 - (float)Math.Pow(0.5f, gameTime.ElapsedSec / Config.AdaptationHalfLife); paramsData.LuminanceLowBound = Config.LuminanceLowBound; paramsData.LuminanceHighBound = Config.LuminanceHighBound; paramsData.KeyValue = Config.KeyValue; paramsData.BloomAmount = Config.BloomAmount; paramsCB.SetData(paramsData); device.PixelShaderConstants[0] = paramsCB; // // Measure and adapt : // device.SetTargets(null, measuredNew); device.PixelShaderResources[0] = averageLum; device.PixelShaderResources[1] = measuredOld; device.PipelineState = factory[(int)(Flags.MEASURE_ADAPT)]; device.Draw(3, 0); // // Tonemap and compose : // device.SetTargets(null, target); device.PixelShaderResources[0] = hdrImage; // averageLum; device.PixelShaderResources[1] = measuredNew; // averageLum; device.PixelShaderResources[2] = bloom0; // averageLum; device.PixelShaderResources[3] = Game.GetService <SpriteBatch>().TextureWhite; device.PixelShaderSamplers[0] = SamplerState.LinearClamp; Flags op = Flags.LINEAR; if (Config.TonemappingOperator == TonemappingOperator.Filmic) { op = Flags.FILMIC; } if (Config.TonemappingOperator == TonemappingOperator.Linear) { op = Flags.LINEAR; } if (Config.TonemappingOperator == TonemappingOperator.Reinhard) { op = Flags.REINHARD; } device.PipelineState = factory[(int)(Flags.TONEMAPPING | op)]; device.Draw(3, 0); device.ResetStates(); // swap luminanice buffers : Misc.Swap(ref measuredNew, ref measuredOld); }
/// <summary> /// Performs luminance measurement, tonemapping, applies bloom. /// </summary> /// <param name="target">LDR target.</param> /// <param name="hdrImage">HDR source image.</param> public void Render(GameTime gameTime, RenderTargetSurface target, ShaderResource hdrImage, RenderWorld viewLayer) { var device = Game.GraphicsDevice; var filter = Game.RenderSystem.Filter; var settings = viewLayer.HdrSettings; using (new PixEvent("HDR Postprocessing")) { // // Rough downsampling of source HDR-image : // filter.StretchRect(averageLum.Surface, hdrImage, SamplerState.PointClamp); averageLum.BuildMipmaps(); // // Make bloom : // filter.StretchRect(viewLayer.Bloom0.Surface, hdrImage, SamplerState.LinearClamp); viewLayer.Bloom0.BuildMipmaps(); filter.GaussBlur(viewLayer.Bloom0, viewLayer.Bloom1, settings.GaussBlurSigma, 0); filter.GaussBlur(viewLayer.Bloom0, viewLayer.Bloom1, settings.GaussBlurSigma, 1); filter.GaussBlur(viewLayer.Bloom0, viewLayer.Bloom1, settings.GaussBlurSigma, 2); filter.GaussBlur(viewLayer.Bloom0, viewLayer.Bloom1, settings.GaussBlurSigma, 3); // // Setup parameters : // var paramsData = new Params(); paramsData.AdaptationRate = 1 - (float)Math.Pow(0.5f, gameTime.ElapsedSec / settings.AdaptationHalfLife); paramsData.LuminanceLowBound = settings.LuminanceLowBound; paramsData.LuminanceHighBound = settings.LuminanceHighBound; paramsData.KeyValue = settings.KeyValue; paramsData.BloomAmount = settings.BloomAmount; paramsData.DirtMaskLerpFactor = settings.DirtMaskLerpFactor; paramsData.DirtAmount = settings.DirtAmount; paramsData.Saturation = settings.Saturation; paramsData.MaximumOutputValue = settings.MaximumOutputValue; paramsData.MinimumOutputValue = settings.MinimumOutputValue; paramsData.DitherAmount = settings.DitherAmount; paramsCB.SetData(paramsData); device.PixelShaderConstants[0] = paramsCB; // // Measure and adapt : // device.SetTargets(null, viewLayer.MeasuredNew); device.PixelShaderResources[0] = averageLum; device.PixelShaderResources[1] = viewLayer.MeasuredOld; device.PipelineState = factory[(int)(Flags.MEASURE_ADAPT)]; device.Draw(3, 0); // // Tonemap and compose : // device.SetTargets(null, target); device.PixelShaderResources[0] = hdrImage; // averageLum; device.PixelShaderResources[1] = viewLayer.MeasuredNew; // averageLum; device.PixelShaderResources[2] = viewLayer.Bloom0; // averageLum; device.PixelShaderResources[3] = settings.DirtMask1 == null ? whiteTex.Srv : settings.DirtMask1.Srv; device.PixelShaderResources[4] = settings.DirtMask2 == null ? whiteTex.Srv : settings.DirtMask2.Srv; device.PixelShaderResources[5] = noiseTex.Srv; device.PixelShaderSamplers[0] = SamplerState.LinearClamp; Flags op = Flags.LINEAR; if (settings.TonemappingOperator == TonemappingOperator.Filmic) { op = Flags.FILMIC; } if (settings.TonemappingOperator == TonemappingOperator.Linear) { op = Flags.LINEAR; } if (settings.TonemappingOperator == TonemappingOperator.Reinhard) { op = Flags.REINHARD; } device.PipelineState = factory[(int)(Flags.TONEMAPPING | op)]; device.Draw(3, 0); device.ResetStates(); // swap luminanice buffers : Misc.Swap(ref viewLayer.MeasuredNew, ref viewLayer.MeasuredOld); } }