如何在SpriteBatch Draw XNA(2D)中相乘两个精灵

时间:2009-12-30 21:57:57

标签: xna 2d

我在XNA 3.1中为动作RPG编写简单的十六进制引擎。我想在暗黑破坏神II中照亮英雄和火炬附近的地面。我最好这样做的方法是计算视野,隐藏任何瓷砖及其播放器无法看到的内容,并在任何光源上绘制特殊的“光”纹理:黑色和白色的纹理,模糊的圆圈在它的中心。

我想将这个纹理与背景相乘(如混合模式:乘法),但是 - 不幸的是 - 我没有看到在SpriteBatch中这样做的选项。有人能指出我正确的方向吗?

或许还有其他 - 更好的方式来制作暗黑破坏神II中的照明模型?

3 个答案:

答案 0 :(得分:7)

如果你要将光线纹理与场景相乘,你将使该区域变暗,而不是使其变亮。

您可以尝试使用添加剂混合进行渲染;这看起来不太合适,但很容易接受。您将不得不使用相当低的alpha绘制光线,以获得轻盈的纹理,而不仅仅是过度饱和图像的那部分。

另一种更复杂的照明方式是将所有光纹理(对于场景中的所有光源)添加到第二个渲染目标上,然后将此纹理与场景相乘。这应该提供更真实的照明,但是具有更大的性能开销并且更复杂。

初​​始化:

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

绘制:

// 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();

答案 1 :(得分:2)

据我所知,如果不使用自己的自定义着色器,就无法做到这一点。

这样的自定义着色器可以这样工作:

  1. 将场景渲染为纹理
  2. 将灯光渲染为另一种纹理
  3. 作为空白四边形的后期处理,对两个纹理进行采样,结果为场景纹理*浅色纹理。
  4. 这将输出一个亮起的场景,但它不会做任何阴影。如果你想要阴影,我建议关注this excellent sample from Catalin Zima

答案 2 :(得分:1)

也许使用与the BloomEffect component中相同的技术可能是一个想法。

基本上,效果的作用是抓住渲染的场景,从场景中最亮的区域计算绽放图像,模糊并将两者结合起来。结果是根据颜色突出显示区域。

这里可以使用相同的方法。它会更简单,因为你不必根据背景计算绽放图像,只根据角色的位置。

你甚至可以进一步重复使用它来为其他光源提供高亮显示,例如火把,魔法效果等等。