2D lighting

Started by
3 comments, last by Spectrallic 9 years, 6 months ago

I am currently using this texture to draw lights around my items that emit light.

CDwKGdZ.png

Now this works great so far for lighting objects, but I want to create a dynamic lighting system and draw it from the center of my object that emits light. The problem is that I have no idea how to do this. I'm not so much concerned about realistic lighting like flickering and things like that. For now I want to be able to resize the light area on the fly when it's needed. How would I go about doing this?

Advertisement

Are you looking to cast any shadow or just control the size, intensity and color? In the case of size, intensity, etc - you can create a section after regular drawing that uses BlendState.Additive and use a customized color like:

Color col = new Color(200,0,0,50); //using alpha to control transparency

spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
spriteBatch.Draw(light_image, new Rectangle((int)pos.X, (int)pos.Y, (int)size.X, (int)size.Y), col);
Although you may need to offset the pos vector by half the size in the negative direction.
pos=lightpos-(size/2*scale);

Some people are use render targets to blend lights together and apply them to the image after.

ie:

Vector2 offset = new Vector2(lightImage.Width*0.5f, lightImage.Height*0.5f); //offset half width and half height to center light on object
Vector2 lightPos1 = ObjectPos+new Vector2(object.Width/2, object.Height/2)-offset; //put light in center of the object
Vector2 lightPos2 = OtherObjectPos+new Vector2(object.Width/2, object.Height/2)-offset;

GraphicsDevice.SetRenderTarget(myLightsTarget); //Draw lights on lights target
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
spriteBatch.Draw(lightImage, lightpos1, Color.Red);
spriteBatch.Draw(lightImage, lightPos2, Color.Blue);
spriteBatch.End();

GraphicsDevice.SetRenderTarget(null); //use normal backbuffer to render now
GraphicsDevice.Clear(Color.Black);

spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); //do all normal scene drawing stuff here
spriteBatch.Draw(sceneImage1, sceneRect, null, Color.White);
spriteBatch.End();

BlendState blendState = new BlendState();
blendState.AlphaDestinationBlend = Blend.SourceColor;
blendState.ColorDestinationBlend = Blend.SourceColor;
blendState.AlphaSourceBlend = Blend.Zero;
blendState.ColorSourceBlend = Blend.Zero;

//Now using the blendstate created, add the lights made on the lights target
spriteBatch.Begin(SpriteSortMode.Deferred, blendState, null, null, null);
spriteBatch.Draw(myLightsTarget, Vector2.Zero, Color.White);
spriteBatch.End();

//Oya for scaling them you can do this too...
Vector2 scale = new Vector2(0.5f, 0.5f); //half size
Vector2 origin = new Vector2(lightImage.Width/2*scale.X, lightImage.Height/2*scale.Y);
SpriteBatch.Draw(lightImage, lightPos, soureRect, Color.Orange, 0, origin, scale, SpriteEffects.None, 0);

Hopefully that helps?

I would take a look at the source code of Ethanon engine (MIT-based license) and study the 2.5D, normal-map-based effects that they're using:

eth075_2.jpg


- http://ethanonengine.com/faq/
- https://github.com/asantee/ethanon/tree/master/toolkit/Source/src

I'm actually adding different light stuff to mine right now. I across this (although I'm not using it because I don't want to render all the scene elements twice [once with normal maps and once with regular images]):

A tank game by SkyForce which uses normal maps with their 2D lighting and it's very straightforward:

https://github.com/SkyForce/tan4ik/tree/master/Tan4ik

Also here's an image of a test scene I made using the method I described in my previous post:

lights_screenshot.jpg

Maybe my tutorial could help you out here. It is about creating the same effect for lighting, only with a little shader (so you can just pass parameters as you like).

http://blog.spectralstudios.net/tutorials/from-zero-to-lighting-in-2d/

This topic is closed to new replies.

Advertisement