Help with blending modes

Discussion in 'Game Development (Technical)' started by punchey, May 16, 2005.

  1. punchey

    Original Member

    Joined:
    Aug 6, 2004
    Messages:
    64
    Likes Received:
    0
    I need a bit of advice regarding blending modes in D3D7. Basically, to avoid having to require 32-bit color support (for alpha channels), I'm using the color as the basis for blending. That is, the brighter the color, the more opaque. My source and dest blend factors are as follows:

    SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCCOLOR)
    SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCCOLOR)

    One little problem though: I also need to be able to fade this in and out. I can't figure out how to blend based on, for example, the current diffuse alpha AND color. Right now, the only way I can figure out how to fade this texture in and out is to actually alter the color of the texture.

    Now if there's no way to do what I'm describing (to blend based on color AND diffuse alpha), I'd definitely be interested to hear any methods of doing blending or using alpha channels with 16-bit surfaces.

    Thanks!
     
  2. mkovacic

    Original Member Indie Author

    Joined:
    Jul 28, 2004
    Messages:
    127
    Likes Received:
    0
    You can't do that with blending alone. Can you just darken the texture in the texture stages (multiply with diffuse, or tfactor or whatever)?
     
  3. punchey

    Original Member

    Joined:
    Aug 6, 2004
    Messages:
    64
    Likes Received:
    0
    I had tried TFACTOR but I couldn't get that to work either (perhaps I did something wrong?). Like you said, essentially what I want to be able to do is have transparent regions of the texture (the texture is a bit of text) and then multiply the opactiy of that texture by another value so that it will fade in and out.

    The closest I have come to getting it to work this way is to use the SRC and DEST values I described while setting ALPHAARG1 to D3DTA_DIFFUSE and then setting the ambient color to RGB values that correspond with the alpha level I want. Only problem with this is that even though the text does fade out this way, it also grows darker.

    And there's another problem with doing blending based on color: I can't use any text color other than pure white if I want it to be totally opaque. If I set it to red, for example (1,0,0), then it will be very translucent. So that's another reason it would be nice if there was a way to do alpha with 16-bit surfaces. I've thought about using color-keying, but I don't want any aliasing.
     
  4. mkovacic

    Original Member Indie Author

    Joined:
    Jul 28, 2004
    Messages:
    127
    Likes Received:
    0
    You can use D3DFMT_A4R4G4B4, although I have no idea how widely supported it is.

    If you can live with white-only text, additive blending (ONE:ONE) will probably give you reasonable results.

    You can also break the blending in two passes, first you darken what's in the backbuffer using white text (srcblend=zero; destblend=invscrcolor), then render your colored text on top of it (srcblend=one; destblend=one). To get the fading modulate the color in both passes with your fade amount using tfactor or diffuse or whatever.
     
  5. punchey

    Original Member

    Joined:
    Aug 6, 2004
    Messages:
    64
    Likes Received:
    0
    Thanks for the advice! That seems to work okay (doing the two passes or just doing additive). I have a tough time keeping all the blending modes and the combinations thereof straight in my head. :) It makes the text look less than what I'd wanted it to, but it may just have to do in 16-bit mode.

    Thanks again.
     
  6. mkovacic

    Original Member Indie Author

    Joined:
    Jul 28, 2004
    Messages:
    127
    Likes Received:
    0
    No problem. The two pass approach should be pixel-perfect though, I'm surprised it does not look good. This is what the setup should be (using tfactor):

    pass 1:
    colorarg1 = texture (white antialiased text);
    colorop = modulate;
    colorarg2 = tfactor (blend amount in RGB, ie. 0x808080);
    default alpha ( texture; selectarg1; current )
    srcblend = zero;
    destblend = invsrccolor;

    pass 2:
    colorarg1 = texture (same as above, white antialiased text);
    colorop = modulate;
    colorarg2 = tfactor (text color * blend amount);
    default alpha ( texture; selectarg1; current );
    srcblend = one;
    destblend = one;

    You can have textured fonts this way, too, you'll just need two separate textures, one for transparency (used in first pass) and one for color (premultiplied with transparency, used in second pass). This is just breaking the usual SRCALPHA:INVSRCALPHA blending in two passes so you don't need the alpha channel for the transparency map, but the math is the same.
     
  7. Mark Sheeky

    Indie Author

    Joined:
    Aug 7, 2004
    Messages:
    448
    Likes Received:
    0
    Don't all graphics cards have 32-bit colour and alpha channel support nowadays? I don't think you'd reduce your market by limiting to cards that require alpha in the textures.

    Mark
     
  8. soniCron

    Indie Author

    Joined:
    May 4, 2005
    Messages:
    3,664
    Likes Received:
    0
    Basically any graphics accellerator out there will support alpha channel support. I can't think of any that won't, in fact. However, the 32 Bit color mode is something different. Voodoo 1 & 2 (correct me if I'm wrong) only support a 16 Bit color depth. I'm sure there are more. I know some cards, such as early ATIs, absolutely cannot run smoothly greater than 16 Bit color (they fall back to software rasterizing).

    Please be aware that the display color depth has no bearing on the texture depth. A 32 Bit video mode is esentially a 24 Bit video mode with an extra byte for memory alignment (which makes it faster). A 32 Bit image, such as a truecolor PNG with alpha, is RGBA, but a 32 Bit video mode is RGB_, so don't confuse the two different 32 Bit types. There are exceptions, of course, but those will be found in professional grade video cards, which really wouldn't apply to you.

    I was planning to support only 32 Bit color in my engine, but when I did more research, a 32 Bit requirement is actually not safe. Search the web for "nVidia TNT" or "Intel i740" or something similarly old. Read the reviews. Also check out the early video accelerator articles Tom's Hardware. There are excellent reviews of the first graphics accelerators that were released, photos of what they rendered (there were sometimes dramatic rendering quality differences between brands), and benchmarks. This should help you out some.

    Did you know, for example, the ATI Rage didn't support alpha modulation? I didn't either, but if you don't keep that in mind, you can get an ugly, or worse, unplayable screen on some older cards. I am just assuming you'll want to support as many people you can within your limits.
     
  9. punchey

    Original Member

    Joined:
    Aug 6, 2004
    Messages:
    64
    Likes Received:
    0
    Thanks for the advice, guys!

    mkovacic: I think the reason it looks not-so-good is because the font I'm using comes out looking too thick, like it's bleeding into characters nearby. Also, there's no border at all, so when something white gets behind a character, it practically becomes invisible. I'm drawing a drop shadow sort of thing behind it to help with this, but it's not quite enough.

    When I was using src:SRCCOLOR and dest:INVSRCCOLOR, it would get a bit of the darker edge around the character to help sort of "frame" it and give it a border. It was much more readable.

    And I still can't get TFACTOR to work.... although I was passing TEXTUREFACTOR a full 32-bit value (0x80808080). I guess it's just supposed to be RGB? Maybe that's what I was doing wrong?

    Mark Sheeky and soniCron:
    Yes, I have a tester who has one of those Intel chips, and he reports that it will only support 16-bit surfaces. He suggested I use perhaps 4-4-4-4, but I figure only having 4 bits for color data will look really bad.

    So at this point, I'm thinking I'll just use 32-bit textures with alpha channels, and then if the hardware doesn't support that, I'll fall back on 16-bit using src:SRCCOLOR dest:INVSRCCOLOR and then "fade" it by changing the diffuse color. This leads to darkening of the text as it fades, but beggars can't be choosers. :) That is, unless I can get TFACTOR to work.

    Are there any other settings I need to set to get TFACTOR to work? I should just be able to set TEXTUREFACTOR to a value, and then set the alpha op to TFACTOR, right? Or is there another state I need to set?

    Thanks everyone!
     
  10. soniCron

    Indie Author

    Joined:
    May 4, 2005
    Messages:
    3,664
    Likes Received:
    0
    Not at all (especially to the owners of those old video cards). Just store the files as 32 bit, query the video card about it's capabilities, and if it can't support 32 bit textures, you can diffusion dither as you're loading and that'll look fine as a 16 bit texture. A lot of engines until recently only supported 16 bit textures. It won't be so bad!
     
  11. mkovacic

    Original Member Indie Author

    Joined:
    Jul 28, 2004
    Messages:
    127
    Likes Received:
    0
    Ah, that makes sense. What you're getting is the same as SRCALPHA:INVSRCALPHA where both color and the alpha have antialiased text in it, my version will give you the same as if the alpha has the text, and the color is pure white. You could tweak it to get the same results, but I don't see the point in complicating it any further, A4R4B4G4 is probably what you want anyway.

    WRT the TFACTOR, it's simply not supported (or is poorly supported) on some cards, I was just using it as an example because it's easier to setup than DIFFUSEMATERIALSOURCE. Yes, 0x80808080 would be fine as well.
     

Share This Page

  • About Indie Gamer

    When the original Dexterity Forums closed in 2004, Indie Gamer was born and a diverse community has grown out of a passion for creating great games. Here you will find over 10 years of in-depth discussion on game design, the business of game development, and marketing/sales. Indie Gamer also provides a friendly place to meet up with other Developers, Artists, Composers and Writers.
  • Buy us a beer!

    Indie Gamer is delicately held together by a single poor bastard who thankfully gets help from various community volunteers. If you frequent this site or have found value in something you've learned here, help keep the site running by donating a few dollars (for beer of course)!

    Sure, I'll Buy You a Beer