Jump to content

  • Log In with Google      Sign In   
  • Create Account


[C++] Blend state issue


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 Ripiz   Members   -  Reputation: 529

Like
0Likes
Like

Posted 29 August 2012 - 02:26 AM

Hello,
I'm trying to setup blending state to perform some blending, but for some reason I can't understand how it works, it's always giving me troubles.
My pixel shader returns (0, 0, 0, x), where x is some amount of alpha, basically I just want to make some areas darker. Here's my current blend state setup:
  D3D11_BLEND_DESC blendDesc;
  blendDesc.AlphaToCoverageEnable = FALSE;
  blendDesc.IndependentBlendEnable = FALSE;
  blendDesc.RenderTarget[0].BlendEnable = TRUE;

  blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_COLOR;
  blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_DEST_COLOR;
  blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
 
  blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA;
  blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
  blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

  blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
Why I setup it like this? Well I think SRC is new color, DEST is current render target color, so SrcBlend and DestBlend are set to use those colors, SrcBlendAlpha is set to use whatever alpha pixel shader returns, and DestBlendAlpha uses inverse of new alpha. Therefore I believe it'll end up like this:
rt_color = rt_color * (1 - new_color.a) + new_color * new_color.a;
But it doesn't seem to do that.

Could anyone explain me how blending states work and/or help setup it to get it to work like I need?

Thank you in advance.

Sponsor:

#2 Erik Rufelt   Crossbones+   -  Reputation: 3185

Like
1Likes
Like

Posted 29 August 2012 - 02:44 AM

SrcBlend = operation performed on source color, that is the color returned from your pixel shader
DestBlend = operation performed on destination color, that is the current value in the back-buffer
BlendOp = what do do with the results from Src and Dest before outputting the final result

SrcBlend = SrcColor means:
resultSrc = SrcColor * SrcColor = (0, 0, 0, x * x)

DestBlend = DestColor means:
resultDest = DestColor * DestColor = something from backbuffer * itself

BlendOpAdd:
result = resultSrc + resultDest

The SrcBlendAlpha etc is just if you want the Alpha part of your SrcColor and DestColor blended separately from the RGB part. You probably don't want to use that.

So your desired states should instead be SrcBlend = SrcAlpha, which would make the result color be SrcColor * SrcAlpha, and DestBlend = InvSrcAlpha to scale the current back-buffer color.

#3 Ripiz   Members   -  Reputation: 529

Like
0Likes
Like

Posted 29 August 2012 - 03:12 AM

Thank you for explanation and help. Seems I was completely wrong.
Here's my final setup that works the way I want:
  blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
  blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
  blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;

  blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
  blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
  blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

P.S. Also I found a bug, Debug and Release shaders behave differently. It seems in Debug clip(alpha_value - any_constant) clips everything, while in Release it works as expected, this happens only with blending enabled, before it was fine without it.

Thank you again!

Edit: a bit offtopic but, is it worth to use clip, or blending is very cheap? 95% pixels gonna get clipped if I use it.

Edited by Ripiz, 29 August 2012 - 03:25 AM.


#4 Erik Rufelt   Crossbones+   -  Reputation: 3185

Like
1Likes
Like

Posted 29 August 2012 - 03:35 AM

When I've tested it in the past it helps a bit.. In my font-wrapper I added if(alpha == 0) discard; which I tested to improve performance if there's a lot of pixels drawn, though not by very much. I've seen the same result with sprites. It probably depends on the graphics card etc..
There's a difference between blending and discarding, as the z-buffer will still get updated with blending, but not for discarded pixels.

#5 CryZe   Members   -  Reputation: 768

Like
0Likes
Like

Posted 29 August 2012 - 03:59 AM

It seems in Debug clip(alpha_value - any_constant) clips everything, while in Release it works as expected, this happens only with blending enabled, before it was fine without it.


The clip instrinsic discards random pixels in my engine on a NVidia graphics card I tested it on while it works on the AMD graphics card I'm using, probably because of faulty drivers. Try using the discard instrinsic instead.

Edited by CryZe, 29 August 2012 - 04:00 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS