Alpha processing in WPF pixel shader effect

Is there anything unusual about how the alpha component is handled in a pixel shader? I have a WPF application for which my artist gives me grayscale images for use as a background, and the application paints these images in accordance with the current state. So I wrote a pixel shader (using the WPF pixel shader effects library infrastructure) to use as an effect for an image element. The shader takes color as a parameter, which it converts to HSL so that it can manipulate brightness. Then, for each gray pixel, it calculates a color whose brightness is interpolated between the color parameter and white in proportion to the brightness of the original pixel.

float4 main(float2 uv : TEXCOORD) : COLOR { float4 src = tex2D(implicitInputSampler, uv); // ...Do messy computation involving src brightness and color parameter... float4 dst; dst.r = ... dst.g = ... dst.b = ... dst.a = src.a; return dst; } 

This works fine on pixels where alpha = 1. But where alpha = 0, the resulting pixels are highlighted in white, and do not look like the background of the window. So I made a small change:

 float4 main(float2 uv : TEXCOORD) : COLOR { float4 src = tex2D(implicitInputSampler, uv); if (src.a == 0) return src; ... 

and now the transparent parts are really transparent. What for? Why did this dst.a = src.a statement dst.a = src.a do this in the first version? Unfortunately, even this is only a partial correction, because it looks like pixels with 0 <alpha; 1 go white.

Does anyone know that I don't understand about alpha?

+7
pixel wpf alphablending pixel-shader
source share
3 answers

After a few more searches on the Internet, I found that I was absent.

According to an article on MSDN : "WPF uses pre-multiplied alpha throughout a number of performance reasons, so the way we interpret the color values ​​in a custom pixel shader."

Thus, the correction turns out to be a throw in multiplication by alpha:

 float4 main(float2 uv : TEXCOORD) : COLOR { ... dst.rgb *= src.a; return dst; } 

And now my conclusion looks the way I expect.

+21
source share

0 <alpha; 1 go white

What ranges do you expect here?

All values ​​will be in the range of 0.0 and 1.0 ... pixel shaders do not work in discrete 256 color ranges, they are a floating point, where 1.0 is the maximum intensity.

If your calculations end up setting r / g / b to> 1.0, you will get white ...

http://www.facewound.com/tutorials/shader1/

-one
source share

Dude I'm working on an XNA game and I had to use a grayscale pixel shader and I had the same problem you are facing. I don’t know if you are familiar with the XNA environment or not, but I solved the problem by changing the SpriteBatch drawing of SpriteBlendMode from SpriteBlendMode.None to SpriteBlendMode.AlphaBlend . Hope this helps you understand the reason.

Yours faithfully,

-one
source share

All Articles