Alpha paste to Canvas help.

For questions about using Classic.

Post » Wed Sep 12, 2012 7:14 pm

I've been using the Canvas object in conjunction with Image Manipulator to store data in color (RGB) channels for later retrieval. I've reached a point where I require a fourth storage channel (Alpha) for this purpose, but I'm unable to paste to it, without destroying existing data in the color channels.

I've tried Erase, Mask and most of Fisholith's Effects, but as mentioned they destroy the RGB data.

An example of what I need would be pasting a pixel with RGBA values of 1 1 1 .3 onto a Canvas with .5 .8 .3 1 and getting .5 .8 .3 .3 as a result - the source RGB would be disgarded and the destination A would be replaced with source A.

I've started writing an Effect for this purpose, but I've hit a snag with relative Sprite sizes (I'm guessing):

// AlphaReplace
// Funky Koval
// PS 2.0
// Replaces BG alpha with FG alpha preserving color values.

// Foreground texture
texture ForegroundTexture;

// Foreground sampler
sampler2D foreground = sampler_state {
    Texture = (ForegroundTexture);
    MinFilter = Point;
    MagFilter = Point;
    MipFilter = Point;
};

// Background texture
texture BackgroundTexture;

// Background sampler
sampler2D background = sampler_state {
    Texture = (BackgroundTexture);
    MinFilter = Point;
    MagFilter = Point;
    MipFilter = Point;
};

// Effect function
float4 EffectProcess( float2 Tex : TEXCOORD0 ) : COLOR0
{
    float4 bg = tex2D(background, Tex);
    float4 fg = tex2D(foreground, Tex);     

    
    bg.a=fg.a;
    
    return bg;
}

// ConstructEffect
technique ConstructEffect
{
    pass p0
    {
        VertexShader = null;
        PixelShader = compile ps_2_0 EffectProcess();
    }
}


Any help would be most appreciated.
B
8
S
2
G
2
Posts: 85
Reputation: 1,218

Post » Wed Sep 12, 2012 8:08 pm

Why not just draw a point using canvas?
It has r,g,b, and opacity, which is your alpha channel basically.
Image Image
B
161
S
48
G
90
Posts: 7,354
Reputation: 66,763

Post » Thu Sep 13, 2012 1:47 am

If it'S just about pasting some pixels I would do what newt said.

However, the effect code you posted, can't work.
1) due to some issue (but I never found out what's causing it), you can't return the background without involving the foreground in any way. It's almost as if the returned value is only considered valid if the foreground texture was altered.
2) Colors have premultiplied alpha. That is, the value of the alpha channel is present in each color channel additionally. If you change an alpha value, you need to first calculate the old one out of the rgb channels.

Example:
bg.rgb /= bg.a;
bg.a = fg.a;
bg.rgb *= bg.a;

3) Remember that you are always altering the foreground texture, no matter what value you return. It might be what you intended, but I just wanted to make it clear.

I didn't test it, but maybe the following works? (Assuming it is applied to a 1-pixel-sprite)

float4 EffectProcess( float2 Tex : TEXCOORD0 ) : COLOR0
{
     float4 bg = tex2D(background, Tex);
     float4 fg = tex2D(foreground, Tex);
     float4 color;

     bg.rgb /= bg.a;
     color = float4(bg.r, bg.g, bg.b, fg.a);
     color.rgb *= color.a;
     
     return color;
}


EDIT: While I was thinking about it...You will never see if it works. You're pasting the background color to the foreground. So no matter what alpha value, it will always look like the background tulamide2012-09-13 01:53:29
Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu Sep 13, 2012 5:11 pm

newt:
That won't work, since the data is not explicitly set by me - it is dynamically generated.

Tulamide
While the logic seems correct, the shader does not work - it may be pasting the new RGBA data, but as you've mentioned, it doesn't clear the "old" BG first.

I've managed to find a solution, however - see the attached .cap file - best way to verify that it works is to hover your mouse over a spot and press the left mouse button to perform the paste. You'll see that the RGB values stay intact while A gets correctly modified.

The visuals are not important - as long as the Image Manipulator picks up the correct data, all is good. Requires NuovoFill, ChannelToAlpha and AlphaReplacer.

As the shader I've made is useful for a very narrow range of cases, I'll just post it here instead of the Addons forum:

// AlphaReplacer
// Funky Koval
// PS 0.0
// Replaces BG.A with FG.A. FG.RGB must be zeroed out.

// ConstructEffect
technique ConstructEffect
{
    pass p0
    {
        VertexShader = null;
        PixelShader = null;
     AlphaBlendEnable = TRUE;
     SrcBlend        = INVSRCALPHA;
     DestBlend        = INVSRCCOLOR;       
    }

}


Thank you everyone for the assist.

http://www.sendspace.com/file/2tys8o
B
8
S
2
G
2
Posts: 85
Reputation: 1,218


Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 1 guest