I’m diving deep into DirectX 9, and I’ve hit a pretty frustrating wall regarding alpha blending. I’ve been trying to achieve true alpha blending on surfaces, but I’m running into the issue where I can’t seem to clear a surface effectively without completely destroying it. I’ve tried using the `Clear()` method, but it behaves more like `FillRect()`—filling the surface with an actual color rather than just clearing it. Even when I set the alpha value to 0, it’s not giving me the transparent effect I’m hoping for.
What I really want is a way to control the alpha while erasing. So, for example, if I set it to alpha=0.5, I’d like to reduce the opacity of what’s been previously drawn on the surface. That way, I can layer the graphics without losing too much of the underlying content. I tried applying some shaders in the mix, but even that hasn’t yielded the results I expected. It seems like the background just doesn’t behave the way I want it to.
I’ve got some code snippets that I’ve been experimenting with. In the rendering setup, I’m using multiple texture stages and modulation for both color and alpha. Here’s a short look at what I’ve got going on in the shader:
“`cpp
float mix=0.0f;
float4 PS(float2 uv: TEXCOORD): COLOR {
float4 ret=tex2D(sampler_main, uv);
return float4(ret.rgb, mix*ret.a);
}
“`
I’m trying different `mix` values, but I’m not achieving the blending effect I’m after. Is there some trick or alternative method in DirectX 9 that I’m missing? Maybe a different rendering configuration or a specific technique? I’ve searched around, but it feels like there has to be a better way to achieve this without clearing the whole surface or getting stuck in a color fill trap. Any suggestions or insights would be much appreciated!
It sounds like you’re really diving into some tricky parts of DirectX 9 with alpha blending! From what you described, it seems like you want to use alpha blending to layer your graphics without fully erasing what’s already on the surface, which can definitely be challenging.
First off, the `Clear()` method usually clears the entire surface to a solid color, which isn’t what you want. To achieve a more dynamic blending where you can control the opacity, you might want to try rendering into an off-screen surface or texture, and then use that for your final composite.
Instead of clearing the surface, consider using
Texture
blending modes. You can draw your new content on top of the existing content while still maintaining the underlying image. Set up your blending state like this:As for shaders, your pixel shader snippet looks good for modifying alpha, but you might want to adjust how the mix value is applied. The mix value should take the previous texture’s alpha into account:
Make sure that `previousAlpha` represents the alpha of the underlying pixel. This way, you’re blending the old and new pixel’s alpha values. If you don’t have access to previous pixel colors, save your off-screen texture and use that for blending.
Finally, if you absolutely need to “clear” parts of your surface while controlling the blending, consider rendering a semi-transparent rectangle instead of clearing it. A rectangle with alpha
0.5
will achieve the desired effect of making old graphics more transparent without completely erasing them.It can definitely feel a bit confusing at first, but once you get the hang of blending modes and working with textures, you’ll find a lot more flexibility in how you render your scenes. Keep experimenting with different values and configurations!
The issue you’re encountering stems from how DirectX 9 handles alpha blending and the limitations of the
Clear()
method. In DirectX, callingClear()
effectively resets the surface buffer with a specific color value rather than erasing it with transparency or semi-transparency in mind. Your shader approach is headed in the right direction, but it’s essential to use render-to-texture targets coupled with careful blending operations to achieve partial transparency. Rather than relying onClear()
, you can render onto intermediate textures using blend states (IDirect3DDevice9::SetRenderState()
) with appropriate blending modes—typically something likeD3DRS_SRCBLEND = D3DBLEND_SRCALPHA
,D3DRS_DESTBLEND = D3DBLEND_INVSRCALPHA
. Then, instead of clearing, you’d draw full-screen quads with semi-transparent colors to modulate the existing content.Additionally, to control opacity levels effectively, consider setting up render targets with alpha channels and ensure you’re working with textures in formats like
D3DFMT_A8R8G8B8
to support per-pixel alpha properly. Your pixel shader snippet is close, but to decrease the opacity of previously drawn content, you’d ideally blend the render target with another semi-transparent quad rather than just manipulating alpha in the shader itself directly on sampled pixels. By rendering a full-screen quad with the desired semi-transparent color (e.g., RGBA(0,0,0,0.5)) atop your existing render target, you achieve cumulative alpha fading without manipulating individual shader pixel computations. This blend-and-overlay method will likely align better with DirectX 9’s rendering pipeline constraints and deliver more predictable, controlled alpha results.