How to multiply two sprites in SpriteBatch Draw XNA (2D)

I am writing a simple hexadecimal engine for action-rpg in XNA 3.1. I want to illuminate the ground next to the hero and torches, as they were lit in Diablo II. I believe that the best way to do this is to calculate the field of view, hide any tiles and their contents that the player cannot see, and draw a special β€œLight” texture on top of any light source: The texture is black with white, a blurred circle in the center.

I would like to multiply this texture by the background (as in blend mode: multiply), but, unfortunately, I do not see the possibility for this in SpriteBatch. Can someone point me in the right direction?

Or maybe there is another - the best way to get a lighting model, like in Diablo II?

+3
source share
3 answers

If you were to multiply your light texture by a scene, you darken the area, rather than increase its brightness.

You can try rendering with the addition of blending; it will not be entirely correct, but easy and may be acceptable. You will need to draw your light with a rather low alpha for a light texture, so as not to just saturate this part of the image.

Another, more complicated way of lighting is to draw all of your light textures (for all the lights on the stage) additively to the second rendering target, and then multiply that texture by your scene. This should give much more realistic lighting, but has better performance and is more complicated.

Initialization:

RenderTarget2D lightBuffer = new RenderTarget2D(graphicsDevice, screenWidth, screenHeight, 1, SurfaceFormat.Color);
Color ambientLight = new Color(0.3f, 0.3f, 0.3f, 1.0f);

Draw:

// set the render target and clear it to the ambient lighting
graphicsDevice.SetRenderTarget(0, lightBuffer);
graphicsDevice.Clear(ambientLight)

// additively draw all of the lights onto this texture. The lights can be coloured etc.
spriteBatch.Begin(SpriteBlendMode.Additive);
foreach (light in lights)
    spriteBatch.Draw(lightFadeOffTexture, light.Area, light.Color);
spriteBatch.End();

// change render target back to the back buffer, so we are back to drawing onto the screen
graphicsDevice.SetRenderTarget(0, null);

// draw the old, non-lit, scene
DrawScene();

// multiply the light buffer texture with the scene
spriteBatch.Begin(SpriteBlendMode.Additive, SpriteSortMode.Immediate, SaveStateMode.None);
graphicsDevice.RenderState.SourceBlend = Blend.Zero;
graphicsDevice.RenderState.DestinationBlend = Blend.SourceColor;
spriteBatch.Draw(lightBuffer.GetTexture(), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
spriteBatch.End();
+7
source

, .

:

  • .
  • , , - * .

, . , Catalin Zima

+2

, , BloomEffect, .

, , , , . .

. , , .

You can even reuse this to provide illumination for other light sources such as torches, magic effects, and more.

+1
source

Source: https://habr.com/ru/post/1726937/


All Articles