Friday, September 1, 2017

xna - Rendering lighting only on specific objects


I have done something similar to this in monogame:


2


3


My question is, what would I have to do to draw that lighting effect only on the pillar and not the background ? Is there something like ignoring certain sprites when using BlendState.Additive ? How would that work ? Here is how i'm drawing it now.


//draw background
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
spriteBatch.Draw(Background, Vector2.Zero, Color.White);
spriteBatch.End();


//draw pillar
spriteBatch.Begin(SpriteSortMode.Deferred);
spriteBatch.Draw(Texture, new Rectangle(PillarX, PillarY, Width, Height), Color.White);
spriteBatch.End();

//draw lighting sprite in additive mode
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
spriteBatch.Draw(LightTexture, pos, null, Color.OrangeRed, 0f, Vector2.Zero,
scale, SpriteEffects.None, 0f);
spriteBatch.End();


Edit: Also, apart from the pillar I have as an example, I need to do that for 3D models as well, so would the Stencil Buffer work here ?



Answer



Re-psuedo-coded:


//draw pillar
LightMapTexture.Clear(0,0,0,0); //Transparent everywhere
spriteBatch.Begin(Immediate, Alpha);
spriteBatch.Draw(Texture, new Rectangle(PillarX, PillarY, Width, Height), Color.White);
//Still transparent everywhere except texture; texture may be partially transparent also


customBlendState = new BlendState();
customBlendState.ColorSourceBlend = Blend.DestinationAlpha; //0 everywhere but Texture
customBlendState.AlphaSourceBlend = Blend.DestinationAlpha; //0 everywhere but Texture
customBlendState.ColorDestinationBlend = Blend.One; //Plus what's already there
customBlendState.AlphaDestinationBlend = Blend.One; //Plus what's already there
spriteBatch.Begin(Immediate, customBlendState);
spriteBatch.Draw(LightTexture, pos, null, Color.OrangeRed, 0f, Vector2.Zero, scale, SpriteEffects.None, 0f);
//Still transparent everywhere except texture
spriteBatch.End();


//draw background
spriteBatch.Begin(Immediate, Opaque);
spriteBatch.Draw(Background, Vector2.Zero, Color.White,,,,,,,,1); //Draw at Z=1
spriteBatch.End();

The preceeding may not be 100%, but should get you well on your way.
The purpose is to only use LightTexture where DestinationAlpha > 0 (Texture has colored the pixel already).
Be back soon.


Edit: Just for learning, please look at the members of BlendState. Use each of them and explain the result of each to yourself. i.e. why you are having the problem you have


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...