Search code examples
wpfdrawingpixel-shader

How to apply multiple shader effects to a DrawingVisual?


I have got a DrawingVisual object (dv) and draw an image after a complex transformation to its DrawingContext (dc). After the dc.Close(), I want to run multiple shader effects on the dv object. First, a custom Tint effect, then a blur effect. Later I would like to add Brightness, Saturation, etc correction also. How can I apply the effects? The DrawingVisual allows only one Effect. Is it possible to nest it into an another object, and apply the second effect to it? Then new nest, third effect, etc? Or something similar? The final object - after the effects - must be the source for a RenderTargetBitmap Render() at the end.

Code behind part:

DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
...
dc.DrawImage(...);
dc.Close();

[Apply Effects Required]

BitmapSource render = dv.RenderVisualAsBitmap(...); // custom RenderTargetBitmap rendering

Regards, Zoltan


Solution

  • You may use nested ContainerVisuals:

    var dv = new DrawingVisual { Effect = new BlurEffect() };
    
    using (var dc = dv.RenderOpen())
    {
        dc.DrawRectangle(Brushes.Red, new Pen(Brushes.Green, 5), new Rect(100, 100, 100, 100));
    }
    
    var cv = new ContainerVisual { Effect = new DropShadowEffect() };
    cv.Children.Add(dv);
    
    // more ContainerVisual here
    
    var rtb = new RenderTargetBitmap(300, 300, 96, 96, PixelFormats.Default);
    rtb.Render(cv);