Skip to content

How to Apply Two PixelShaderEffects Sequentially #995

@ngocducdim

Description

@ngocducdim

Hi, I’m working with two PixelShaderEffect instances:

  • First Effect – Applies a 4-corner perspective warp to an image.

  • Second Effect – Applies Thin-Plate Spline (TPS) warping, using the output of the first effect as its input.

  • The goal is to first warp the image at the corners using the first effect, then apply TPS warping on the already warped image using the second effect.

Question:

  • How can I chain or draw these two PixelShaderEffects sequentially so that the second one operates on the result of the first?

Output:

  • First effect( perspective warp at 4 corner) is fine

Image

  • But once I draw a second effect it throw System.Runtime.InteropServices.COMException: '' without details

Image

Image

Code

  • My code to draw this two effects:
if (drawingLayer.Layer.ProjectiveTransformResult != null)
{
    var perspectiveRs = drawingLayer.Layer.ProjectiveTransformResult.PerspectiveMatrix;
    var shaderBytes = App.ServiceProvider.GetRequiredService<AppState>().PerspectiveShaderBytes;
    var shaderEffect = new PixelShaderEffect(shaderBytes)
    {
        Source1 = drawingLayer.FullViewBitmap,
    };

    // Set shader parameters
    shaderEffect.Properties["OriginalImageSize"] = new Vector2((float)layerWidthNm, (float)layerHeightNm);
    shaderEffect.Properties["CurrentImageSize"] = new Vector2((float)drawingLayer.FullViewBitmap.Bounds.Width, (float)drawingLayer.FullViewBitmap.Bounds.Height);
    shaderEffect.Properties["M11"] = perspectiveRs.M11;
    shaderEffect.Properties["M12"] = perspectiveRs.M12;
    shaderEffect.Properties["M13"] = perspectiveRs.M13;
    shaderEffect.Properties["M21"] = perspectiveRs.M21;
    shaderEffect.Properties["M22"] = perspectiveRs.M22;
    shaderEffect.Properties["M23"] = perspectiveRs.M23;
    shaderEffect.Properties["M31"] = perspectiveRs.M31;
    shaderEffect.Properties["M32"] = perspectiveRs.M32;
    shaderEffect.Properties["M33"] = perspectiveRs.M33;
    var cmdList = new CanvasCommandList(ds);
    var dsCmd = cmdList.CreateDrawingSession();
    dsCmd.DrawImage(shaderEffect);
    effect = cmdList;                
}

if (drawingLayer.Layer.PythonTPSResult != null)
{
    var shaderBytes = App.ServiceProvider.GetRequiredService<AppState>().ShaderBytes;
    var secondShaderEffect = new PixelShaderEffect(shaderBytes)
    {
        Source1 = effect ?? drawingLayer.FullViewBitmap, // this not work, it throw System.Runtime.InteropServices.COMException: ''
        //Source1 = drawingLayer.FullViewBitmap, // this work
    };
    secondShaderEffect.Properties["smallImageSize"] = new Vector2((float)drawingLayer.FullViewBitmap.Bounds.Width, (float)drawingLayer.FullViewBitmap.Bounds.Height);
    secondShaderEffect.Properties["originalImageSize"] = new Vector2((float)layerWidthNm, (float)layerHeightNm);
    secondShaderEffect.Properties["imgScale"] = new Vector2(
        (float)drawingLayer.FullViewBitmap.Bounds.Width / (float)layerWidthNm,
        (float)drawingLayer.FullViewBitmap.Bounds.Height / (float)layerHeightNm
        );

    secondShaderEffect.Properties["numControlPoints"] = drawingLayer.Layer.PythonTPSResult.numControlPoints;
    secondShaderEffect.Properties["srcPoints"] = drawingLayer.Layer.PythonTPSResult.srcPoints;
    secondShaderEffect.Properties["splineMappings"] = drawingLayer.Layer.PythonTPSResult.splineMappings;

    var test = new TintEffect()
    {
        Source = effect ?? drawingLayer.FullViewBitmap,
        Color = Colors.Red
    };
    effect = secondShaderEffect;
}

if (effect != null)
{
    ds.DrawImage(effect);
}
else
{
    ds.DrawImage(drawingLayer.FullViewBitmap);
}

// Restore previous transform
ds.Transform = previousTransform;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions