My goal is to apply any shader written in SKSL to an image. I am aware that this feature is available in Skia but not in SkiaSharp, but I see that there has been some effort recently to port the functionality. I've been trying to replicate a solution for one of the pre-release versions that one of the contributors made here: https://github.com/mono/SkiaSharp/issues/1319#issuecomment-640529824 but I had to make a few changes to my code and shader as they weren't seemingly compatible with the latest pre-release version (2.88.0-preview.232). Here is mine for reference:
// input values
SKBitmap bmp = new SKBitmap(1000, 1000);
SKCanvas canvas = new SKCanvas(bmp);
float threshold = 1.05f;
float exponent = 1.5f;
// shader
var src = @"
in fragmentProcessor color_map;
uniform float scale;
uniform half exp;
uniform float3 in_colors0;
half4 main(float2 p) {
half4 texColor = sample(color_map, p);
if (length(abs(in_colors0 - pow(texColor.rgb, half3(exp)))) < scale)
discard;
return texColor;
}";
using var effect = SKRuntimeEffect.Create(src, out var errorText);
// input values
var inputs = new SKRuntimeEffectUniforms(effect);
inputs["scale"] = threshold;
inputs["exp"] = exponent;
inputs["in_colors0"] = new[] {1f, 1f, 1f};
// shader values
using var blueShirt = SKImage.FromEncodedData(Path.Combine(PathToImages, "blue-shirt.jpg"));
using var textureShader = blueShirt.ToShader();
var children = new SKRuntimeEffectChildren(effect);
children["color_map"] = textureShader;
// create actual shader
using var shader = effect.ToShader(true, inputs, children);
// draw as normal
canvas.Clear(SKColors.Black);
using var paint = new SKPaint { Shader = shader };
canvas.DrawRect(SKRect.Create(400, 400), paint);
However, I get a System.Runtime.InteropServices.SEHException: 'External component has thrown an exception.' on canvas.DrawRect() which I believe is either a problem with my shader or that this feature is not yet fully supported. Besides manually modifying individual pixels with C# which should be a lot slower than a shader operation, is the latter not possible within the current realm of SkiaSharp? If not, I think I'll be needing to load an image into some library with OpenGL bindings (like OpenTK), apply the shader, take a screenshot of the canvas, then load that image into SkiaSharp, which I imagine is not a great solution. I'd like to see possible solutions even outside of Skia.