Jump to content
  • Advertisement
Sign in to follow this  
Syranide

Common tile lightning

This topic is 5130 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got a simple question regarding the lightning often found in 2D tile RPG-games, you, know with lights on the walls etc which light up a number of squares. My question, what kind of blending do they use, I assume it isn't common alpha bledning as that really doesn't that well with high light values (or am I wrong?). I'm guessing they are using additivt blendning, and if such is the case, how do you do that fast/the best way in D3DXSprite? I mean locking the buffer and working pixel-per-pixel works, but really isn't that fast right? And as far as I saw, there were no options for additive blending (isn't there something like that in D3D?). Thanks in advance Syranide

Share this post


Link to post
Share on other sites
Advertisement
I think I actually figured it out...

g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, 0 );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

that works for me... I guess it is additive blending too, at least seems that way.

Share this post


Link to post
Share on other sites
Fiddled some more with additive blending, and just by accident I came across this... really advanced patterns start showing after a while, all with one singel continous formula, modulate next position by rotation and distance, using a constant increase.

http://home.syranide.com/download/pattern.rar

And for those who don't dare run it here are some screens

http://home.syranide.com/~showcase/?url=Pattern/

I'm really amazed I must say on what the smallest things can do.
(And no, this is no pathetic try to spread a virus)

[Edited by - Syranide on November 27, 2004 11:13:07 AM]

Share this post


Link to post
Share on other sites
Those patterns are weird.

However, additive blending means having D3DBLEND_ONE for both the source blend factor and the destination blend factor.

i.e.

g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

This is because the blending equation is as follows:

Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor

-Mezz

Share this post


Link to post
Share on other sites
Mmm, yes, I believe so too, but however, just as everyone else has problems with it, so do I...

Having D3DBLEND_ONE on both, creates a "2 colored image", transparent and white, no alpha what so ever... perhaps you know what's wrong? As fast as I apply D3DBLEND_ONE to source it gets that way.

Btw, something strange happens when I set source blend to ONE... it gets as I said, and it stays that way, even if I set it to 0 and run... if I run another application it works, but not instantly, might be something with MSVC...

http://home.syranide.com/download/pattern3.rar (that's with both ONE, the previous is with only destination blending ONE.)

And btw, are you sure what I showed isn't additive, I mean, this looks very additive to me...

http://home.syranide.com/download/patternadditive.jpg <-- only RED, GREEN and BLUE.

[Edited by - Syranide on November 27, 2004 12:15:58 PM]

Share this post


Link to post
Share on other sites
I don't understand what the problem you are having is.
What do you mean by a 2 colour image, could you show a screenshot of that problem?

The screenshot (http://home.syranide.com/download/patternadditive.jpg) shows additive blending, yes. Is this what you get when you use the following?

g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, 0 );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

If so, I'll theorise that D3D is possibly setting the source blend factor to something else, because 0 isn't a legal value for the parameter, it has to be a D3DBLEND_xxxx constant.

-Mezz

Share this post


Link to post
Share on other sites
g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );

Those are the correct ones, never thought about the 0.
Anyway, yes, that picure was with the zero (or the one I just wrote here)

However if I set source blending to ONE I get this.
http://home.syranide.com/download/patternsolid.jpg

Btw, great thanks for taking your time.

Share this post


Link to post
Share on other sites
Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor

But no, wait a minute... is that really true?
I mean, if we put an additive picture on another, we don't want them to be additive on a black background... we want the applied picture to be added to the final color right?

As the destination texture is not supposed to be additive, it's supposed to be kept as it is, and one layer (det source) to be additive. I mean, if we want to add two images using additive blending that would mean.

Final Color = DestinationTexture + SourceTexture * SourceBlendFactor
and NOT ...
Final Color = (0 + ) DestinationTexture * DestinationBlendFactor + SourceTexture * SourceBlendFactor

Right? (If I'm not to sleepy the last one is the one you (and everyone) else suggests?)

I mean, if I would add 3, 4 or any amount of layers, that would mean constantly using the background for additive blending on black, we don't want that. (Even though it should produce the same result...)

(This however doesn't explain why destination should ONE and not source in that case... but anyway, or perhaps I've screwed up the "renderstate" meanings at this time of night ;))

(D3DBLEND_SRCALPHA is default for D3DXSprite, however D3DBLEND_ONE is default for D3DDevice...)

Share this post


Link to post
Share on other sites
I'm getting lost, Sometimes I have a really hard time following what you are saying. I'll try to answer the bits I understood.

Quote:
Original post by Syranide
Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor

But no, wait a minute... is that really true?


Yes, it is the actual equation used. It's the formula that is stated in the Direct3D documentation.

Quote:
Original post by Syranide
I mean, if we put an additive picture on another, we don't want them to be additive on a black background... we want the applied picture to be added to the final color right?


I don't understand this.

Quote:
Original post by Syranide
As the destination texture is not supposed to be additive, it's supposed to be kept as it is, and one layer (det source) to be additive. I mean, if we want to add two images using additive blending that would mean.

Final Color = DestinationTexture + SourceTexture * SourceBlendFactor
and NOT ...
Final Color = (0 + ) DestinationTexture * DestinationBlendFactor + SourceTexture * SourceBlendFactor


I don't understand where you get your (0 + ) from. On a black backround, your 0 is the destination because the only thing in your destination is black!

Also, if you consider that:

Final Color = DestinationTexture + SourceTexture * SourceBlendFactor

is actually

DestinationTexture * DestinationBlendFactor + SourceTexture * SourceBlendFactor

where DestinationBlendFactor is 1, then they are the same thing.

Also, use

Final Color = ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor

instead of SourceTexture and DestinationTexture because you might get confused with the texture blend cascade using those terms.

Quote:
Original post by Syranide
I mean, if I would add 3, 4 or any amount of layers, that would mean constantly using the background for additive blending on black, we don't want that. (Even though it should produce the same result...)


I don't understand this either - what do you mean by layers? and constantly using the background?

Quote:
Original post by Syranide
(This however doesn't explain why destination should ONE and not source in that case... but anyway, or perhaps I've screwed up the "renderstate" meanings at this time of night ;))


OK, additive blending means that you take what comes out of the pixel pipeline, and you add it to what is already in the framebuffer. As a verbose equation, that's as follows:

whats_new + whats_already_there

Now, whats_new corresponds to "ObjectColor" in the blending equation and whats_already_there corresponds to "PixelColor".

ObjectColor * SourceBlendFactor + PixelColor * DestinationBlendFactor

Now, if you set SourceBlendFactor and DestinationBlendFactor to 1, i.e.

g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

Then you get:

ObjectColor * 1 + PixelColor * 1

Which resolves to:

ObjectColor + PixelColor

Which is adding the two things together. I'm not sure what you're trying to do - in your original post you said it is lighting for 2D tile games.

I would expect the lighting to be this kind of additive blending, although I see now that you are probably having trouble because you are using ID3DXSprite, which only understands the concept of alpha blending in the sense that you want transparency (hence it using SRCALPHA, INVSRCALPHA). I'm not sure, but you can probably override this by setting parameters on the device as well (after the Begin() call).

e.g.


mySprite->Begin(...);

g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

// draw some stuff

mySprite->End();


Although it probably isn't the most recommended way of doing things because you mess with the state inside the sprite drawing.

-Mezz

Share this post


Link to post
Share on other sites
Yeah sorry for that, I was really tired and... well shit the same...

By tile lightning I mean a simple faded circle with an alphachannel, which you apply to a room which creates the "illusion" of a light source...

However, as I previously said, setting both to ONE creates the picture you saw, which seems to be the case for many many more on the internet... But then again it seems to be because of something in ID3DXSprite, as if you set the default renderstates for D3D to the Sprite, they draw the same way, only white and black... but as I expect it looks good in "D3D".

Either way, I've found what I was looking for, setting only destination to ONE creates additive blending. As people say, as long as it works, don't touch it... but then again it's always good to know why :/

Btw, what other way is there than setting them between Begin/End?
I don't want it to count for all textures so I can't just tell it to keep the states when "begin"... ? (I am aware of that it creates some problems as I have to flush each time I change states so I need to be smart in which order I draw)
Is there a better way?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!