优化win2d实现的萤火虫粒子效果

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优化win2d实现的萤火虫粒子效果相关的知识,希望对你有一定的参考价值。

前几天我发了个技术博客,告诉大家怎样用Win2D 画萤火虫动画

那种绘制萤火虫的方式虽然画质高,但是性能不好,萤火虫数量超过50就可以感受到帧数下降。

我今天想到了一种牺牲画质提升性能的绘制方式,就算是画520只闪烁并且不远离画布的萤火虫都不会掉帧。

优化思路如下:

原本绘制萤火虫的代码是这样的:

    Public Overrides Sub OnDraw(sender As GamePanelView, DrawingSession As CanvasDrawingSession, Canvas As ICanvasResourceCreator)
        For Each fireFly In Target.Particles
            Using cl As New CanvasCommandList(DrawingSession), ds = cl.CreateDrawingSession
                Using glow As New GlowEffectGraph
                    Dim color = fireFly.CenterColor
                    color.A = CByte(fireFly.Opacity * 255)
                    ds.FillCircle(fireFly.Location + Target.Location, fireFly.Radius, color)
                    glow.Setup(cl, fireFly.Radius)
                    DrawingSession.DrawImage(glow.Output)
                End Using
            End Using
        Next
    End Sub

这种方式的思路是对每一个萤火虫: 画一个带有放大形态变换和高斯模糊的彩色的圆,再画一个半透明白色圆。

这样会使用1040次Effect,是一般的显卡不好接受的任务。

但是,现实情况是: 萤火虫有不同的透明度,接近的颜色和接近的尺寸。

那么我有了新思路,就是先画出520个彩色的圆,再对这个整体进行放大形态变换和高斯模糊,最后画520个半透明白色圆。

这样画质会略微下降,但是性能提升非常明显。

    Public Overrides Sub OnDraw(sender As GamePanelView, DrawingSession As CanvasDrawingSession, Canvas As ICanvasResourceCreator)
        Dim halfWhite = Colors.White
        Using cl As New CanvasCommandList(DrawingSession), ds = cl.CreateDrawingSession
            Using glow As New GlowEffectGraph
                Dim maxRadius = 0.0
                For Each fireFly In Target.Particles
                    If fireFly.Radius > maxRadius Then
                        maxRadius = fireFly.Radius
                    End If
                    Dim color = fireFly.CenterColor
                    color.A = CByte(fireFly.Opacity * 255)
                    halfWhite.A = color.A
                    ds.FillCircle(fireFly.Location + Target.Location, fireFly.Radius, color)
                Next
                glow.Setup(cl, maxRadius)
                DrawingSession.DrawImage(glow.Output)
                For Each fireFly In Target.Particles
                    Dim color = fireFly.CenterColor
                    color.A = CByte(fireFly.Opacity * 255)
                    halfWhite.A = color.A
                    DrawingSession.FillCircle(fireFly.Location + Target.Location, fireFly.Radius / 2, halfWhite)
                Next
            End Using
        End Using
    End Sub

 

原先的算法:画520个萤火虫,每秒平均8fps,CPU使用率平均18%。

现在的算法:画520个萤火虫,满帧(画布没有处于缓慢状态),CPU使用率平均9.2%。

效果图(我这学期作业的项目是这个,如果大家介意里面的文字,转载的时候可以把里面的字涂掉):

技术分享

视频:

http://v.youku.com/v_show/id_XMTU3Nzk4ODc3Ng==.html

以上是关于优化win2d实现的萤火虫粒子效果的主要内容,如果未能解决你的问题,请参考以下文章

win10 uwp 萤火虫效果

优化求解基于matlab粒子群算法和帝国殖民算法和萤火虫算法求解最小生成树优化问题含Matlab源码 2376期

[UWP]用Win2D实现镂空文字

[UWP]用Win2D实现镂空文字

使用 Win2D 实现融合效果

背包问题基于matlab带权重的贪心萤火虫算法求解0-1背包问题含Matlab源码 045期