0
\$\begingroup\$

I'm trying to do alpha blending manually because I only want to apply alpha blending on certain pixels. Underlying is the texture I'm writing to. This is what I got so far, but it doesn't give the same result as when AlphaBlendEnable = TRUE

What formula does default alpha blend in HLSL use?

matrix WorldViewProjection; texture2D OverlyingShadingMap; sampler2D OverlyingShadingMapSampler = sampler_state { texture = <OverlyingShadingMap>; }; texture2D UnderlyingShadingMap; sampler2D UnderlyingShadingMapSampler = sampler_state { texture = <UnderlyingShadingMap>; }; struct VertexShaderOutput { float4 Position : SV_POSITION; float4 Color : COLOR0; float2 TextureCoordinates : TEXCOORD0; }; VertexShaderOutput SpriteVertexShader(float4 position : POSITION0, float4 color : COLOR0, float2 texCoord : TEXCOORD0) { VertexShaderOutput output; output.Position = mul(position, WorldViewProjection); output.Color = color; output.TextureCoordinates = texCoord; return output; } float4 SpritePixelShader(VertexShaderOutput input) : COLOR { float4 overlying = tex2D(OverlyingShadingMapSampler, input.TextureCoordinates); clip(overlying.a - 0.001); float4 underlying = tex2D(UnderlyingShadingMapSampler, input.TextureCoordinates); // Alphablending float3 rgb = overlying.rgb * overlying.a + (1 - overlying.a) * underlying.a * underlying.rgb; float alpha = underlying.a + (1 - underlying.a) * overlying.a; return float4(rgb, alpha); } technique SpriteDrawing { pass P0 { AlphaBlendEnable = FALSE; VertexShader = compile vs_2_0 SpriteVertexShader(); PixelShader = compile ps_2_0 SpritePixelShader(); } }; 
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Change this:

float3 rgb = overlying.rgb * overlying.a + (1 - overlying.a) * underlying.a * underlying.rgb; float alpha = underlying.a + (1 - underlying.a) * overlying.a; return float4(rgb, alpha); 

To this:

return underlying + (1 - underlying.a) * overlying; 

Formula for alpha blending is: $$pixelColour=src\_pixel+(1−src_α).dest\_pixel$$ Taken from here, which also lists formulas for other blendstates in XNA: http://glasnost.itcarlow.ie/~powerk/technology/xna/blending/blending.html

\$\endgroup\$
2
  • \$\begingroup\$ The formula you've shown is for pre-multiplied alpha. You'd multiply the source rgb by source alpha if you're using a non-premultiplied texture. \$\endgroup\$ Commented Nov 16, 2018 at 12:57
  • \$\begingroup\$ Correct. In MonoGame/XNA BlendState.AlphaBlend is pre-multiplied alpha and BlendState.NonPremultiplied is not. It seems that the default HLSL alpha blending uses the pre-multiplied alpha formula. \$\endgroup\$ Commented Nov 16, 2018 at 13:38

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.