首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# XNA 2D轨迹效果优化

C# XNA 2D轨迹效果优化
EN

Stack Overflow用户
提问于 2012-03-29 06:27:58
回答 1查看 2.5K关注 0票数 3

目前,作为我的游戏中的一个拖尾效果,我每5帧就会有一个半透明的精灵纹理副本被添加到拖尾的List<>中。

这些轨迹的alpha值每一帧都会递减,绘制函数会迭代列表并绘制每个纹理。一旦它们达到0α,它们就会从List<>中删除。

结果是在移动实体后面产生了一个很好的小轨迹效果。问题是对于100+实体来说,帧速率开始急剧下降。

所有的轨迹纹理都来自相同的雪碧表,所以我不认为这是批处理的问题。我分析了代码,CPU强度在FPS下降尖峰期间较低,然后在正常FPS,所以我假设这意味着它的GPU限制?

有没有更有效地实现这种效果的方法?

下面是我使用的通用代码:

代码语言:javascript
运行
复制
// fade alpha
m_alpha -= (int)(gameTime.ElapsedGameTime.TotalMilliseconds / 10.0f);

// draw
if (m_alpha > 0) {
    // p is used to alter RGB of the trails color (m_tint) depending on alpha value
    float p = (float)m_alpha/255.0f;
    Color blend = new Color((int)(m_tint.R*p), (int)(m_tint.G*p), (int)(m_tint.B*p), m_alpha);               
    // draw texture to sprite batch
    Globals.spriteBatch.Draw(m_texture, getOrigin(), m_rectangle, blend, getAngle(), new Vector2(m_rectangle.Width/2, m_rectangle.Height/2), m_scale, SpriteEffects.None, 0.0f);                
} else {
        // flag to remove from List<>
        m_isDone = true;               
}

我想我应该注意到,给trail类的m_texture是对所有trail共享的全局纹理的引用。我注意到为每条轨迹创建一个硬拷贝。

编辑:如果我简单地注释掉SpriteBatch.Draw调用,即使我为成百上千的对象分配了每一帧的新轨迹,帧中也没有丢失……一定有更好的方法来做到这一点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-29 13:23:58

通常,对于轨迹,您只需在绘制当前帧之前绘制一个透明的屏幕大小的矩形,而不是清除每个帧上的屏幕。因此,前一帧是“暗淡的”或“颜色模糊的”,而较新的帧是完全“清晰”和“明亮”的。当重复此操作时,将从所有先前的帧生成轨迹,这些帧永远不会被清除,而是“变暗”。

这种技术非常有效,它被用在著名的Flurry屏幕保护程序中(www.youtube.com/watch?v=pKPEivA8x4g)。

为了使轨迹更长,只需增加用于清除屏幕的矩形的透明度即可。否则,将使其变得更不透明,从而使轨迹更短。但是,请注意,如果通过使矩形太透明而使轨迹太长,则可能会留下一些由于alpha混合而留下的轻微痕迹,即使在很长一段时间后也可能无法完全清除。遭受了这类伪像的影响,但有一些方法可以补偿它。

根据您的情况,您可能必须适应该技术。例如,您可能希望有多个绘制层,允许某些对象留下轨迹,而其他对象则不生成轨迹。

对于长途旅行,这种技术比尝试像当前方法一样重绘一个精灵数千次更有效。

另一方面,我认为代码中的瓶颈是下面这行:

代码语言:javascript
运行
复制
Globals.spriteBatch.Draw(m_texture, getOrigin(), m_rectangle, blend, getAngle(), new Vector2(m_rectangle.Width/2, m_rectangle.Height/2), m_scale, SpriteEffects.None, 0.0f);   

像Draw()这样的数以千计的GPU调用效率很低。如果在缓冲区中有一个多边形列表,其中每个多边形都位于正确的位置,并且其中存储了透明度信息,则效率会更高。然后,只需调用一次Draw(),就可以使用正确的纹理和透明度渲染所有多边形。很抱歉,我不能为您提供这方面的代码,但如果您想继续您的方法,这可能是您的方向。简而言之,你的GPU当然可以一次绘制数百万个多边形,但它不能调用Draw()那么多次……

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9916570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档