public GaussianBlurShader(GaussianBlur gaussianBlur, int radius) { Radius = radius; this.gaussianBlur = gaussianBlur; // Craete ImageEffectShader blurH = gaussianBlur.ToLoadAndUnload(new ImageEffectShader("GaussianBlurEffect", true)); blurV = gaussianBlur.ToLoadAndUnload(new ImageEffectShader("GaussianBlurEffect", true)); blurH.Initialize(gaussianBlur.Context); blurV.Initialize(gaussianBlur.Context); // Setup Horizontal parameters blurH.Parameters.Set(GaussianBlurKeys.VerticalBlur, false); blurV.Parameters.Set(GaussianBlurKeys.VerticalBlur, true); var size = radius * 2 + 1; nameGaussianBlurH = string.Format("GaussianBlurH{0}x{0}", size); nameGaussianBlurV = string.Format("GaussianBlurV{0}x{0}", size); // TODO: cache if necessary offsetsWeights = GaussianUtil.Calculate1D(this.Radius, gaussianBlur.SigmaRatio); // Update permutation parameters blurH.Parameters.Set(GaussianBlurKeys.Count, offsetsWeights.Length); blurV.Parameters.Set(GaussianBlurKeys.Count, offsetsWeights.Length); blurH.EffectInstance.UpdateEffect(gaussianBlur.Context.GraphicsDevice); blurV.EffectInstance.UpdateEffect(gaussianBlur.Context.GraphicsDevice); // Update parameters blurH.Parameters.Set(GaussianBlurShaderKeys.OffsetsWeights, offsetsWeights); blurV.Parameters.Set(GaussianBlurShaderKeys.OffsetsWeights, offsetsWeights); }
public void Draw(RenderDrawContext context, float sigmaRatio, Texture inputTexture, Texture outputTexture) { // Check if we need to regenerate offsetsWeights if (offsetsWeights == null || this.sigmaRatio != sigmaRatio) { offsetsWeights = GaussianUtil.Calculate1D(Radius, sigmaRatio); // Update parameters blurH.Parameters.Set(GaussianBlurShaderKeys.OffsetsWeights, offsetsWeights); blurV.Parameters.Set(GaussianBlurShaderKeys.OffsetsWeights, offsetsWeights); this.sigmaRatio = sigmaRatio; } // Get a temporary texture for the intermediate pass // This texture will be allocated only in the scope of this draw and returned to the pool at the exit of this method var desc = inputTexture.Description; desc.MultisampleCount = MultisampleCount.None; // TODO we should have a method to get a non-multisampled RT var outputTextureH = gaussianBlur.NewScopedRenderTarget2D(desc); // Horizontal pass blurH.SetInput(inputTexture); blurH.SetOutput(outputTextureH); blurH.Draw(context, nameGaussianBlurH); // Vertical pass blurV.SetInput(outputTextureH); blurV.SetOutput(outputTexture); blurV.Draw(context, nameGaussianBlurV); }
protected override void DrawCore(RenderDrawContext context) { // Update the weight array if necessary if (weightsDirty || tapCount == 0) { weightsDirty = false; Vector2[] gaussianWeights = GaussianUtil.Calculate1D((int)Radius, 2f, true); tapCount = gaussianWeights.Length; tapWeights = new float[tapCount]; for (int i = 0; i < tapCount; i++) { tapWeights[i] = gaussianWeights[i].Y; } } var originalTexture = GetSafeInput(0); var outputTexture = GetSafeOutput(0); var tapNumber = 2 * tapCount - 1; directionalBlurEffect.Parameters.Set(DepthAwareDirectionalBlurKeys.Count, tapCount); directionalBlurEffect.Parameters.Set(DepthAwareDirectionalBlurKeys.TotalTap, tapNumber); directionalBlurEffect.EffectInstance.UpdateEffect(context.GraphicsDevice); directionalBlurEffect.Parameters.Set(DepthAwareDirectionalBlurUtilKeys.Radius, Radius); directionalBlurEffect.Parameters.Set(DepthAwareDirectionalBlurUtilKeys.TapWeights, tapWeights); // Blur in one direction var blurAngle = 0f; directionalBlurEffect.Parameters.Set(DepthAwareDirectionalBlurUtilKeys.Direction, new Vector2((float)Math.Cos(blurAngle), (float)Math.Sin(blurAngle))); var firstBlurTexture = NewScopedRenderTarget2D(originalTexture.Description); directionalBlurEffect.SetInput(0, originalTexture); directionalBlurEffect.SetOutput(firstBlurTexture); directionalBlurEffect.Draw(context, "GaussianBokehPass1_tap{0}_radius{1}", tapNumber, (int)Radius); // Second blur pass to ouput the final result blurAngle = MathUtil.PiOverTwo; directionalBlurEffect.Parameters.Set(DepthAwareDirectionalBlurUtilKeys.Direction, new Vector2((float)Math.Cos(blurAngle), (float)Math.Sin(blurAngle))); directionalBlurEffect.SetInput(0, firstBlurTexture); directionalBlurEffect.SetOutput(outputTexture); directionalBlurEffect.Draw(context, "GaussianBokehPass2_tap{0}_radius{1}", tapNumber, (int)Radius); }
protected override void DrawCore(RenderDrawContext context) { // Updates the weight array if necessary if (weightsDirty || tapCount == 0) { weightsDirty = false; Vector2[] gaussianWeights = GaussianUtil.Calculate1D((int)radius, 2f, true); tapCount = gaussianWeights.Length; tapWeights = gaussianWeights; } var originalTexture = GetSafeInput(0); var outputTexture = GetSafeOutput(0); cocBlurEffect.Parameters.Set(DepthAwareDirectionalBlurKeys.Count, tapCount); cocBlurEffect.EffectInstance.UpdateEffect(context.GraphicsDevice); cocBlurEffect.Parameters.Set(CoCMapBlurShaderKeys.Radius, radius); cocBlurEffect.Parameters.Set(CoCMapBlurShaderKeys.OffsetsWeights, tapWeights); var tapNumber = 2 * tapCount - 1; // Blur in one direction var blurAngle = 0f; cocBlurEffect.Parameters.Set(CoCMapBlurShaderKeys.Direction, new Vector2(MathF.Cos(blurAngle), MathF.Sin(blurAngle))); var firstBlurTexture = NewScopedRenderTarget2D(originalTexture.Description); cocBlurEffect.SetInput(0, originalTexture); cocBlurEffect.SetOutput(firstBlurTexture); cocBlurEffect.Draw(context, "CoCMapBlurPass1_tap{0}_radius{1}", tapNumber, (int)radius); // Second blur pass to ouput the final result blurAngle = MathUtil.PiOverTwo; cocBlurEffect.Parameters.Set(CoCMapBlurShaderKeys.Direction, new Vector2(MathF.Cos(blurAngle), MathF.Sin(blurAngle))); cocBlurEffect.SetInput(0, firstBlurTexture); cocBlurEffect.SetOutput(outputTexture); cocBlurEffect.Draw(context, "CoCMapBlurPass2_tap{0}_radius{1}", tapNumber, (int)radius); }