I started some work in this direction. But I think this pretty inefficient. Anyway I’m not working with fuse framework anymore. So if this helps you I share my code for you:
using Uno;
using Uno.IO;
using Uno.UX;
using Uno.Graphics;
using Uno.Collections;
using Fuse.Elements;
using Fuse.Drawing;
using Fuse.Resources;
using Fuse.Drawing.Primitives;
namespace Fuse.Effects.MG {
public enum BlendingMode {
// Basic
Normal = 0,
Multiply,
Screen,
// Extended
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
SoftLight,
HardLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
// Porter/Duff Compositing
Clear,
Copy, // Same as Normal
Source, // Same as Normal
SourceIn,
SourceOut,
SourceAtop,
Destination, // Do nothing
DestinationOver,
DestinationIn,
DestinationOut,
DestinationAtop,
Xor,
// Misc
PlusDarker,
PlusLighter
}
public class BlendEffect : BasicEffect {
BlendingMode mBlendingMode;
public BlendingMode Mode {
get { return mBlendingMode; }
set {
if (mBlendingMode != value) {
mBlendingMode = value;
OnRenderingChanged();
}
}
}
public BlendEffect() : base(EffectType.Composition) {
mBlendingMode = BlendingMode.Normal;
}
public static float4 NormalBlend(float4 source, float4 dest) {
return (source + dest) * 0.5f;
}
public static float4 MultiplyBlend(float4 source, float4 dest) {
return source * dest;
}
protected override void OnRooted() {
base.OnRooted();
debug_log Element.Parent;
}
protected override void OnRender(DrawContext context, Rect rect) {
// Clip our source Element's rectangle by viewport rectangle for better performance
// Affect on Scroller's content and elements outside of viewport bound
var viewportRect = new Rect(float2(0f), context.Viewport.Size);
var actualSourceRect = Rect.Intersect(rect, viewportRect);
//var actualDestRect = Rect.Intersect(rect, viewportRect);
Element.Opacity = 0f;
Element.InvalidateVisual();
//context.Flush();
var destFramebuffer = Element.CaptureRegion(context, actualSourceRect, int2(0));
Element.Opacity = 1f;
var sourceFramebuffer = Element.CaptureRegion(context, actualSourceRect, int2(0));
debug_log rect;
if (sourceFramebuffer == null || destFramebuffer == null)
return;
var DestTexture = destFramebuffer.ColorBuffer;
draw Fuse.Drawing.Planar.Image {
DrawContext: context;
Node: Element;
Position: actualSourceRect.Position;
Size: actualSourceRect.Size;
DepthTestEnabled: false;
Invert: true;
Texture: sourceFramebuffer.ColorBuffer;
TextureColor: prev TextureColor;
PixelColor: NormalBlend(TextureColor, sample(DestTexture, TexCoord.XY, SamplerState.LinearClamp));
};
FramebufferPool.Release(destFramebuffer);
FramebufferPool.Release(sourceFramebuffer);
}
}
}