Create an Effect Layer
Required Elements
There are a few requirements to properly define an effect layer.
Base Class
Each effect layer needs to inherit from the base class EffectLayerBase
, which implements some base functionality for
your layer. However, there are some more specialized base classes available, which can further reduce the complexity of
your effect layers, depending on the canvas type you are targeting.
EffectLayerBase
: used for effect layers that target an addressable panel canvas type, or for custom handling of other canvas types.StripEffectLayerBase
: used for effect layers that target an addressable strip canvas type.PixelEffectLayerBase
: used for effect layers that target a single pixel canvas type.
Class Attribute
The class attribute EffectLayer
is required to give the layer a name, category and other additional meta-information.
Here is a list of properties that can be set for each render node via the attribute.
Name
: layer nameCategory
: layer categorySubCategory
: layer subcategoryDescription
: layer descriptionTags
: collection of layer tagsTargetCanvas
: the target canvas type of this render node (Pixel
,Strip
,Panel
). Default isPanel
.
Constructor
Your effect layer must have a constructor with IExtensionApi
, the canvas width and height as parameters. The base class
requires these parameters.
Override Render Method
Override the corresponding render method of the base class and implement your render logic for the node there. See the code examples below for more information.
Optional Update Method
If your render node needs to be updated with each frame step, you can override the Update(float dt)
method and
implement your update logic there.
Warning
This update method is not called within the render thread. As such, you must not interact with any GPU bound render resources within this method.
Optional Initialize Method
If you need to initialize some resources for your layer, this might be the perfect place for it. It will be called from the render thread.
Optional Terminate Method
If you have initialized some resources for your layer via Initialize, you can uninitialize them here. It will be called from the render thread.
Code
EffectLayerBase
A full example of an effect layer named "Example" that fills the canvas black is displayed below.
[EffectLayer(Name = "Example")]
public class ExampleEffectLayer : EffectLayerBase
{
public ExampleEffectLayer(IExtensionApi api, int canvasWidth, int canvasHeight)
: base(api, canvasWidth, canvasHeight)
{
}
// optional
public override void Initialize()
{
}
// optional
public override void Terminate()
{
}
// optional
public override void Update(float dt)
{
}
// required
public override void Render(IRender render)
{
var canvas = render.GetCanvas();
canvas.Clear(SKColors.Black);
}
}
StripEffectLayerBase
The base class StripEffectLayerBase
is designed to simplify creating effect layers that target a strip canvas type,
where addressable pixels are aligned along the longer side of the canvas. The other canvas dimension will be duplicated
from the initial strip line.
Info
Using this base class will override the TargetCanvas
to Strip
.
Here is an example effect layer that defines a gradient from one bindable color setting to another across the strip canvas.
[EffectLayer(Name = "Strip Gradient Fill")]
public class StripGradientColorLayer : StripEffectLayerBase
{
[BindableLayerSetting]
public SKColor ColorBegin { get; set; }
[BindableLayerSetting]
public SKColor ColorEnd { get; set; }
public StripGradientColorLayer(IExtensionApi api, int canvasWidth, int canvasHeight)
: base(api, canvasWidth, canvasHeight)
{
}
// Notice, how this method draws a rectangle with one pixel height across the strip length.
protected override void RenderStrip(SKCanvas canvas)
{
canvas.Clear();
using var paint = new SKPaint();
paint.Style = SKPaintStyle.Fill;
paint.Shader = SKShader.CreateLinearGradient(new SKPoint(0, 0),
new SKPoint(StripLength, 0),
new[] { ColorBegin, ColorEnd },
SKShaderTileMode.Clamp);
canvas.DrawRect(0, 0, StripLength, 1, paint);
}
}
PixelEffectLayerBase
The base class PixelEffectLayerBase
is designed to simplify creating effect layers that target a pixel canvas type,
where the color is mapped across the whole canvas.
Info
Using this base class will override the TargetCanvas
to Pixel
.
Here is an example of such a effect layer, which takes in a color as bindable setting, and applies it to the whole canvas.
[EffectLayer(Name = "Color Fill")]
public class FillBasicColorLayer : PixelEffectLayerBase
{
[BindableLayerSetting]
public SKColor Color { get; set; } = DefaultValues.PrimaryColor;
public FillBasicColorLayer(IExtensionApi api, int canvasWidth, int canvasHeight)
: base(api, canvasWidth, canvasHeight)
{
}
// Notice, how this method only returns a single color.
protected override SKColor RenderPixel() => Color;
}