【问题标题】:How to multiply two sprites in SpriteBatch Draw XNA (2D)如何在 SpriteBatch Draw XNA (2D) 中将两个精灵相乘
【发布时间】:2009-12-30 21:57:57
【问题描述】:

我正在为 XNA 3.1 中的 action-rpg 编写简单的十六进制引擎。我想在英雄和火把附近点亮地面,就像它们在暗黑破坏神 II 中被点亮一样。我认为最好的方法是计算视野,隐藏玩家看不到的任何瓷砖及其内容,并在任何光源上绘制特殊的“光”纹理:黑色和白色的纹理,在它的中心模糊的圆圈。

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

或者也许还有其他更好的方法来实现暗黑破坏神 II 中的光照模型?

【问题讨论】:

    标签: xna 2d


    【解决方案1】:

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

    您可以尝试使用加法混合进行渲染;这看起来不太正确,但很容易并且可能可以接受。您必须使用相当低的 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();
    

    【讨论】:

      【解决方案2】:

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

      为此的自定义着色器将像这样工作:

      1. 将场景渲染为纹理
      2. 将灯光渲染到另一个纹理
      3. 作为空白四边形的后期处理,对两个纹理进行采样,结果是场景纹理 * 光纹理。

      这将输出一个明亮的场景,但不会产生任何阴影。如果您想要阴影,我建议您关注this excellent sample from Catalin Zima

      【讨论】:

        【解决方案3】:

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

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

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

        您甚至可以进一步重复使用它来为其他光源提供高亮显示,例如手电筒、魔术效果等等。

        【讨论】:

        • 这与我的建议类似,但可能更好,因为您可以从bloom示例中获取示例代码
        猜你喜欢
        • 2011-06-09
        • 2012-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多