color dodge in directx

Discussion in 'Game Development (Technical)' started by cliffski, Jul 10, 2009.

  1. cliffski

    Moderator Original Member

    Joined:
    Jul 27, 2004
    Messages:
    3,897
    Likes Received:
    0
    Anyone know what combination of render states and texture stage states reproduces the effect of a color dodge mode in photoshop / paintshop pro?
    It must be possible.
     
  2. andrew

    andrew New Member

    Joined:
    Jan 14, 2007
    Messages:
    487
    Likes Received:
    0
    http://www.nathanm.com/photoshop-blending-math/

    Looks like color dodge is basically src * 256 / (255 - dest) per channel? not sure if you can do that via old-style render states because of that divide. Would be easy in a pixel shader though...

    - andrew
     
  3. DavidR91

    DavidR91 New Member

    Joined:
    May 23, 2009
    Messages:
    47
    Likes Received:
    0
    If I recall correctly, there are some DX blending functions which can be manually set to equation-like states

    and Colour dodge should be Res = Original / (1-Blend)

    If you haven't already seen it, this article is fairly interesting, and should lead to an explanation on how to implement a custom/eqn. blend
     
  4. cliffski

    Moderator Original Member

    Joined:
    Jul 27, 2004
    Messages:
    3,897
    Likes Received:
    0
    Hmm. now I'm torn between both methods, and unsure how either works. The sort of shaders I write use .fx files (I understand little about shaders) and look like this:

    Code:
    sampler2D g_samSrcColor;
    float4 Redden( float2 Tex : TEXCOORD0 ) : COLOR0
    {
        float4 Color;   
        Color = tex2D( g_samSrcColor, Tex.xy);
        Color.r = (Color.r * 1.4);
        Color.g = (Color.g * 0.6);
        Color.b = (Color.b * 0.6);
        return Color;
    }
    
    technique PostProcess
    {
        pass p1
        {
            VertexShader = null;
            PixelShader = compile ps_2_0 Redden();
        }
    }
    
    which is fine when you are just applying an effect to the screen, but I'm unclear as to how I can reference the texture that is currently set, and the existing backbuffer (or current render target) data.
    In other words, how do I declare a sampler2D that is 'current render target'? The documentation on this stuff isnt very user friendly :(
     
  5. vjvj

    Indie Author

    Joined:
    Sep 25, 2004
    Messages:
    1,732
    Likes Received:
    0
    I might be a little foggy on this, but I'm pretty sure you can't bind the current render target as a texture for the current shader. Reading the render target would be mostly useless anyway, since the data you get at the time of the texture fetch is going to be missing lots of information due to the fact that hundreds of pixels are still sitting in the pipeline.

    So if you can do it in the blend unit via alpha blend equations like DavidR91 suggested, that would be ideal (I'm not sure what color dodge is, so I'll assume his equation is right). Blend happens in the ROP unit, which is at the end of the pipeline. If not, you'll have to introduce another fullscreen post-processing pass.
     
  6. cliffski

    Moderator Original Member

    Joined:
    Jul 27, 2004
    Messages:
    3,897
    Likes Received:
    0
    Ah interesting... thanks for that. I guess its back to the nightmare of the ten billion different combinations of render and texture state :D
     
  7. vjvj

    Indie Author

    Joined:
    Sep 25, 2004
    Messages:
    1,732
    Likes Received:
    0
    Yeah, they weren't able to completely eliminate fixed function in DX9, unfortunately (or even DX10, for that matter... Maybe DX11? LOL).
     
  8. gmcbay

    Indie Author

    Joined:
    Jul 28, 2004
    Messages:
    280
    Likes Received:
    0
    http://www.ziggyware.com/readarticle.php?article_id=228

    Article is for XNA, but the HLSL .Fx files between XNA and Direct3D 9 are basically the same, so you just need to port the very small bits of C# which set up the shader values into C/C++ (assuming that's what you're using).

    Also, the most common way to deal with what you guys are talking about as a situation where you'd be reading the contents of the backbuffer is to use multiple render passes, first render to a render target, and then do another render loop which feeds that render target's texture into a texture sampler in a shader in the next pass. For people used to fixed-pipeline coding the idea of doing multiple rendering passes seems strange and scary and inefficient at first, but I assure you it isn't. Commercial games these days do more render passes per one frame than you'd probably believe and a lot of them are to do the sort of compositing you're talking about here.

    Also, one thing to keep in mind when you DO end up juggling render states is that you can encode them into the .Fx file, so at least you don't have to dirty up your main rendering engine code with a bunch of state changes required for the hlsl effect to render correctly, eg:


    technique PostProcess
    {
    pass p1
    {
    AlphaBlendEnable = False;
    CullMode = CCW;

    VertexShader = null;
    PixelShader = compile ps_2_0 Redden();
    }
    }


    See the hlsl docs for a full list of the states and values you can set thusly in shaders, but it is pretty much all of the standard render states.
     

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