Results 1 to 10 of 10

Thread: D3D alpha blending to a rendertarget surface

  1. #1

    D3D alpha blending to a rendertarget surface

    Hello everyone

    I'm havnig a tough time making my program do what I want it to do (naturally ). I'm using Direct3D 8 interface.

    But first, in short let me describe two different algorithms. I want them result in identical graphics output, but they don't.

    1st alg. drawing sprite to backbuffer (this one works fine)

    -setting rendertarget to backbuffer
    -clearing backbuffer with white color
    -drawing half transparent sprite to backbuffer.


    2nd alg. drawing sprite to a surface and then to backbuffer (this on doesn't do what I want)


    -seting rendertarget to rendertarget texture (ARGB format)
    -clearing rendertarget surface with A0R0G0B0
    -rendering half transparent sprite to a rendertarget surface
    -setting rendertarget to backbuffer
    -clearing backbuffer with white color
    -rendering newly rendered texture with sprite to backbuffer.


    The program doesn't crash. It actually produces some output, but alpha channel is all screwed up. I guessed it has all to do with srcblend and destblend flags. I tired all sorts of combinations, but I can't get the desired result.

    In the first algorithm I simply use d3blend_srcalpha for srcblend and d3dblend_invsrcalpha for destblend.

    In the second algorithm I use same flags when rendering to a surface, and I use d3dblend_one/d3dblend_invsrcalpha when rendering from a surface to a backbuffer. This combination gives me the closest result, but not the same. I tried many other combinations, non of them work

    All textures are in ARGB format.

    Can someone help me please?

  2. #2

    D3D alpha blending to a rendertarget surface

    Why in first case you are clearing surface with white color ($FFFFFFFF ?) and in second case with black (0-0-0-0) and expect the same results? You are setting both color and alpha to different values!
    There are only 10 types of people in this world; those who understand binary and those who don't.

  3. #3

    D3D alpha blending to a rendertarget surface

    No, Im crearing Backbuffer with white color. In the second part, I'm doing it too (the line before last one). I'm clearing the surface with (0-0-0-0) to make it completely transparent before drawing a sprite with alpha chanell on it. Then I draw the sprite on the surface. Then I clear the backbuffer and draw the content of that surface on the backbuffer.

  4. #4

    D3D alpha blending to a rendertarget surface

    Let me put my question this way:

    We have an ARGB color $7F00FF00
    and we want to blend this color with another ARGB color $FFFF0000

    We are using D3DBLEND_SRCALPHA for source blend
    And D3DBLEND_INVSRCALPHA for destination blend

    Thus resulting color will be:

    R = ($00*($7F/$FF))+($FF*(($FF-$7F)/$FF)) = $80
    G = ($FF*($7F/$FF))+($00*(($FF-$7F)/$FF)) = $7F
    B = ($00*($7F/$FF))+($00*(($FF-$7F)/$FF)) = $00

    Resulting RGB color is $807F00

    But what happens to alpha channel? Does it get blended too? If same formula applies to alpha channel then the resulting alpha chennel is:

    A = ($7F*($7F/$FF))+($FF*(($FF-$7F)/$FF)) = $BF

    Am I understanding this correctly, or am I not getting it at all? If I am wrong, could you please explain to me, what is the resulting alpha value in this particular case and how you arrived to it?

    Thanks.

  5. #5

    D3D alpha blending to a rendertarget surface

    Try clearing render-texture with $00FFFFFF - A=0, R,G,B=$FF. And, of course, use norma srcalpha/invsrcalpha combination.

    If it doesn't help, try examining alpha channel of rendered render-texture -> use D3DTA_ALPHAREPLICATE.

    Hope this helps... But not sure
    blog: http://alexionne.blogspot.com/

  6. #6

    D3D alpha blending to a rendertarget surface

    You are not giving enought details (for example: what is blend mode during rendering to rendertarget surface?)
    There are multiple ways to archive wanted behaviour and without knowing why at all you need additional renderterget surface (and what it should contain) - it's hard to provide to you most suitable algo.

    One of the ways:
    (1) set S=ONE D=ZERO / render to rendertarget surface. - now RT contains the copy of your texture.
    (2) render to backbuffer as in your first alg, but using newly genereated RT texture.
    There are only 10 types of people in this world; those who understand binary and those who don't.

  7. #7

    D3D alpha blending to a rendertarget surface

    Quote Originally Posted by alex_izm
    If same formula applies to alpha channel then the resulting alpha chennel is:

    A = ($7F*($7F/$FF))+($FF*(($FF-$7F)/$FF)) = $BF

    Am I understanding this correctly, or am I not getting it at all?
    You are 100% correct. In DX8 both color and alpha are scaled by the same blend factor.

    PS. In DX9 there is D3DRS_SEPARATEALPHABLENDENABLE that allows separate blend factors and blend ops for alpha channel.
    There are only 10 types of people in this world; those who understand binary and those who don't.

  8. #8

    D3D alpha blending to a rendertarget surface

    Thanks for your replies.
    Clootie - Spasibo

    But I'm still stuck.

    Try clearing render-texture with $00FFFFFF - A=0, R,G,B=$FF. And, of course, use norma srcalpha/invsrcalpha combination.
    Tried that. It had some effect in certain blend setings, but no desired result

    If it doesn't help, try examining alpha channel of rendered render-texture -> use D3DTA_ALPHAREPLICATE.
    If it is not too much trouble, could you provide a link to an example. I couldn't find anything that made sense to me.

    One of the ways:
    (1) set S=ONE D=ZERO / render to rendertarget surface. - now RT contains the copy of your texture.
    (2) render to backbuffer as in your first alg, but using newly genereated RT texture.
    This actually worked , but only if you render one sprite from texture to a rendertarget surface . If you render two overlaping sprites it doesn't work.

    I tired to figger out how to give you more info, on what I'm trying to do. May be this will help:

    If you ever worked with photoshop, you know it is all about layers. So if you follow the below steps, you should get a visual picture of my problem.

    1. Create a blank photoshop RGB image with white background
    2. Create first layer and draw a blue circle on it
    3. Change opacity of this layer to 75%
    4. Create another layer and draw a red circle on it, which overlaps partialy with the blue circle on the first layer
    5. Change opacity of the second layer (with the red circle) to 50%
    6. Merge second layer with the first one (Layer->merge down)

    now we end up with a white, non transparent background and one layer, with completely transparent area around circles, Part of blue circle (75% opacity), part of red circle (50% opacity) and purple area, where two circles intersect (?% opacity)

    This is what I want to achieve in d3d. White background is out backbuffer, Layer with two circles - our resulting rendertarget surface after sprites are rendered on it.

    I tried all sorts of combinations of blend flags. Non of them give me this result.

    Also, in this case, what would be the formula to calculate opacity for that purple intersection area. It is not completely opaque, but it is clearly more than 75%.

    I'm almost ready to give up. I've wasted two weekends on this. Apart from this crap, my sprite rendering engine is complete.

  9. #9

    D3D alpha blending to a rendertarget surface

    Hmm... problem here lies in algorithm area - not in Direct3D.

    Photoshop while blending layers (in normal mode) is using different function than SrcAlpha / InvSrcAlpha. I'm not sure is Photoshop function is commutative, but SrcAlpha / InvSrcAlpha definetly is NOT!

    So, while blending surfaces S1, S2 and S3: (S1 (S2 S3)) <> ((S1 S2) S3).
    You can figure it out by yourself if you take a piece of paper and try to do all calculations by pen

    So - you can't - you have to workaround
    There are only 10 types of people in this world; those who understand binary and those who don't.

  10. #10

    D3D alpha blending to a rendertarget surface

    [quote="alex_izm"]
    If it is not too much trouble, could you provide a ]

    I'm not sure about DX8, but in DX9 you use this as an modifier for input parameter for your texture-stage argument. As far as I remember it (I'm not at home now, do not have DX help here), Arg1 is set to D3DTA_TEXTURE, and Arg2 is set to D3DTA_CURRENT (both Color and Alpha). Now, try setting Color Arg1 to (D3DTA_TEXTURE + D3DTA_ALPHAREPLICATE) - that should do the thing In DX9, the "magic" function is IDirect3DDevice9.SetTextureStageState + D3DTSS_COLORARG1/2... Hope this helps...
    blog: http://alexionne.blogspot.com/

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •