2
\$\begingroup\$

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 ?

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ not sure how to translate float4 sampledLightmapColor = tex2D(lightmap); to actual code, and how would that work when i'm drawing 3D models ? \$\endgroup\$ – dimitris93 Feb 9 '15 at 16:56
  • \$\begingroup\$ I updated my question to be more understandable \$\endgroup\$ – dimitris93 Feb 9 '15 at 17:07
  • \$\begingroup\$ i didn't have the time yet to check your code, but i also want to add that the light effect that i am trying to do with the sprite i have, is going to be used for 3D models as well, i added that in the question too. ( i am trying to light up 3D cubes in a breakout game, when the ball is close to them, and also the pillar in the left and right side of the screen ) \$\endgroup\$ – dimitris93 Feb 10 '15 at 3:58
  • \$\begingroup\$ The light will follow the ball around? If you render your 3D geometery to a texture, you can use the same method to light it, since it is 2D at that point. \$\endgroup\$ – Jon Feb 10 '15 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.