[英]How to multiply two sprites in SpriteBatch Draw XNA (2D)
我正在为XNA 3.1中的动作RPG编写简单的十六进制引擎。 我想在暗黑破坏神II中照亮英雄和火炬附近的地面。 我最好这样做的方法是计算视野,隐藏任何瓷砖及其播放器无法看到的内容,并在任何光源上绘制特殊的“光”纹理:黑色和白色的纹理,模糊的圆圈在它的中心。
我想将这个纹理与背景相乘(如混合模式:乘法),但是 - 不幸的是 - 我没有看到在SpriteBatch中这样做的选项。 有人能指出我正确的方向吗?
或者也许还有其他 - 更好的方式来实现暗黑破坏神II中的照明模型?
如果要将光照纹理与场景相乘,则会使区域变暗 ,而不会使区域变亮。
您可以尝试使用添加剂混合渲染; 这看起来不太合适,但很容易接受。 您将不得不使用相当低的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();
据我所知,没有使用自己的自定义着色器就无法做到这一点。
一个自定义着色器可以这样工作:
这将输出一个亮起的场景,但它不会做任何阴影。 如果你想要阴影,我建议你遵循Catalin Zima的优秀样本
也许使用与BloomEffect组件中相同的技术可能是一个想法。
基本上,效果的作用是抓住渲染的场景,从场景中最亮的区域计算绽放图像,模糊并将两者结合起来。 结果是根据颜色突出显示区域。
这里可以使用相同的方法。 这将更简单,因为您不必基于背景计算绽放图像,仅基于角色的位置。
您甚至可以进一步重复使用它来为其他光源提供高亮显示,例如火把,魔法效果等等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.