-
|
|
Help with complex blending in DirectX
|
I've been trying all sorts of different combinations of renderstates and texturestagestates, and I just can't seem to make the effect I'm looking for work~
Hopefully somebody here can help me achieve what I'm looking for...
I have an interface composed of various shapes that are supposed to represent various shaped lights projected on a board. It should be noted that these shapes are represented by graphics files, so they have the required alpha channel to represent the shape. That in mind, the desired effect of these shapes is when they overlap, that the colors get brighter-- so, additive blending, no problem there. The other effect required tho, is that these shapes need to be able to fade in and out visibility- which, I would assume would mean we need to use blend factors.
In all of my trials and errors, I've managed to achieve -either- the additive blending effect, OR the fade in/out effect, but I can't seem to figure out how to get BOTH working at the same time, and it's driving me nuts~ >_<;☆
So what sort of calls to SetTextureStage and SetRenderState should I be making to achieve these effects at the same time?
|
|
-
|
|
Re: Help with complex blending in DirectX
|
You can do fading in and out with the alpha channel from fully visible to invisible, if the alpha value is zero the shape won't show it self.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
Nyxojaele:I've been trying all sorts of different combinations of renderstates and texturestagestates, and I just can't seem to make the effect I'm looking for work~
This sounds to me like you're just randomly trying things without understanding what it is you are doing. There are too many configuration inputs to the graphics pipeline for this approach to work. First you need to have an idea of what you want to happen, then you need an understanding of how the pipeline works so that you can configure it to get what you want.
Try reading Chapter 11. Basic Texturing which will explain the texture cascade and how to configure it. Then try reading Chapter 14. The Frame Buffer which will explain alpha blending. Consult my pipeline poster while you read these chapters so that you have an understanding of the data flow through the entire graphics pipeline. All of this is from my book "The Direct3D Graphics Pipeline", which you can read for free.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
legalize:This sounds to me like you're just randomly trying things without understanding what it is you are doing.
Well, that's only 20% true- I understand how color/alpha blending (ie via SetTextureStageState), and frame buffer alpha blending work, I just didn't understand where they were in the graphics pipeline. Your poster is something amazing to behold, thank you very much for posting the link to it- I now understand how they sit in there^^
But what my issue really is, is that I can't seem to figure out exactly what configuration I need to achieve the desired effect-- I mean, I can look at the values for the desired result color, and the values for the source colors, but I can't seem to find any formula that would give me the transition between them- you know, using the result = src * srcBlend + dest * destBlend formula. Which is what I'm asking for help on.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
Reading your original post again, it sounds like two things. First, you want the individual light texture to fade in and out -- this is configured in the texture cascade to modulate the texture with an overall scale factor that fades the texture in and out (you could scale color and alpha, or just scale alpha; it depends on the art files and the look you want).
Next, you want the two things to add up in the frame buffer when they overlap. This is alpha blending.
This gets back to my point of not understanding how the pipeline works. The two things you are trying to do are controlled by separate parts of the pipeline (did you read my chapters or just look at the poster?). Trying to do them all in one step is the source of your confusion.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
Hmm, allow me to elaborate a bit with some code then:
mID3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, (blendValue << 24) | 0x00000000);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); //Multiply our Diffuse with our Texture
mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); //Grab the alpha channel from the texture
mID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); //Keep the current color
mID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA); //Blend using the blendValue from earlier
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); //This is the same texture as is set for texture stage 0
mID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
mID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
mID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //Up until this point, the fade in/out effect is working fine, so long as the next 2 lines are commented out.
//mID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); //Uncommenting these 2 lines will cause the additive blending to occur, but the blend factor doesn't work anymore- it seems as if any non-zero blendValue will cause full opacity
//mID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
So what am I doing wrong here? I'm obviously overlooking something about the interaction of these things, but I can't seem to find -what-...
|
|
-
|
|
Re: Help with complex blending in DirectX
|
As I describe in my book, the texture cascade computes the alpha and color for the source pixel.
Source pixels and destination pixels are combined in the alpha blending operation of the frame buffer.
The blending formula you've written is simply a sum of the source and destination.
If you're not getting the results you want from that alpha blending configuration, then you need to take a step back and figure out the math of what you want to do first. Once you have the math figured out, you can look at the alpha blending portion of the pipeline and determine if it can give you what you want. If it can't do exactly what you want, then you'll have to do a multipass technique and use the texture cascade (or a pixel shader) to combine the first pass and the existing contents of the frame buffer (but in this case you'd be using a render target texture, because a pixel shader/texture cascade can only sample textures, not the back buffer).
|
|
-
|
|
Re: Help with complex blending in DirectX
|
Well, I don't know if you just misunderstood what I was asking, or what, but very little of what you've told me has been actually useful in any way to me, no offense. I wasn't in any way asking for help to understand how it works, but rather I wanted help implementing it to achieve the effect I desired. Your book did little/nothing for me, as I already understand what I need to, to achieve the effect- I just couldn't put that knowledge to proper use, as I have virtually no experience with it.
Regardless of that, tho- I managed to get the effect I wanted- I asked in another forum where the people were willing to give me ideas and thoughts to try, instead of just telling me to RTFM. I don't mean to be condescending towards you about your means of trying to help me, but all it really felt like to me was that you were just touting your book, and not actually trying to help me in any way. It was starting to get quite frustrating. (Although your last post was actually useful, but by that point I had already gotten my answer)
Anyways, for those who would like to see the solution, this is what I did to make it work:
mID3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, (blendValue << 24) | 0x00000000);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
mID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
mID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
mID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
mID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
mID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
mID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
|
-
|
|
Re: Help with complex blending in DirectX
|
You can't implement what you don't understand.
I don't implement other people's wants and needs for free. What I will do is try to help them understand how the pipeline works so that they can go implement things for themselves.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
I stayed out of this but when you set the D3DRS_SRCBLEND to ONE all alpha values will disappear as they are assumed to be 1.
The thing I actually don't understand in your code is why you are doing an or with zero on the blendfactor this has no effect at all and can be removed, I am not attacking here I just want to know why you are appending another operation to there.
Next to that if you could use shaders this code would become a lot easier to write for yourself, having said that it's still a good idea to know how to do it in the pipeline.
@legalize
Most of this forums users actually use it to get an answer to their implementation issues. Yes it is needed to understand the technology you are using for that but sometimes seeing the right solution shows you what you have been doing wrong all along.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
Yah, actually, when I set D3DRS_SRCBLEND to ONE, that was actually changed code from what I originally had- but it had the same visual effect, so I didn't notice until I had already posted the code. So that was my bad.
The blenfactor calculation I have there is actually a force of habit of mine- most of my coding usually revolves around binary manipulation, so I got into the habit of doing calculations like that, strung together into much longer lines, to create values I want.-- That, combined with my changing of 0's to F's and back constantly on the line as I was testing to make sure things were working, it just turned out that the value -happened- to be set to all 0's at the time I copy + pasted the code there.
I can use shaders, technically, but I'm trying to keep the technical requirements and code complexity to a minimum if possible.
@legalize
I'm not even going to argue with you about this anymore- I'm just going to say that I mostly agree with what NightCreature just said.
|
|
-
|
|
Re: Help with complex blending in DirectX
|
NightCreature:Most of this forums users actually use it to get an answer to their implementation issues. Yes it is needed to understand the technology you are using for that but sometimes seeing the right solution shows you what you have been doing wrong all along.
Well, most people would love it if they could just dump their code in here and have someone else debug/implement it for them. So? Just because this attitude is common does not mean I have to debug their code for them for free, without even knowing what it is that they want or trying to figure out what they want by attempting to read their minds.
I've been answering DirectX questions for about 8 years now and the 800+ pages I've written in my book are in direct response to the kinds of questions that come up very often in discussion forums. Some people want to be spoon fed specific answers to their specific programming problem by having someone else debug their code for them and just post the updated code. I don't work that way, unless someone is paying me as a consultant to fix their code for them.
| | |