我有一个游戏,该游戏的简单粒子(基本上是点)在屏幕上移动,留下了痕迹。

我的最终目标是要能够改变每个绘图调用中纯黑色渐变纹理的不透明度。这样,即使粒子运动可能会随时间而移动,我也可以使用拖尾保持粒子的长度(使用累积缓冲区)相同。渲染粒子的方式是根据粒子位置渲染当前帧,让我们将此纹理称为A。然后,我将前一帧并设置为不透明度,在其上绘制一个纯黑色纹理,以使其褪色,我们称之为纹理B。然后在纹理B上绘制纹理A。这样,粒子将根据其所在位置离开轨迹。我目前正在按时间步调粒子的运动,以使它们无论以多大的延迟始终以相同的速度运动(考虑实际时间)。

本质上,我希望能够可以说粒子试验将始终为100像素(考虑到粒子每秒移动60像素),即使帧速率下降,也是如此。当前,当帧率下降时,累积缓冲区的运行时间会减少,因此路径越长,延迟就越长。

我需要知道的信息是衰落的工作原理。因为我需要以某种方式更改黑色纹理的不透明度,以使其在每秒调用较少次数的累积缓冲区时褪色更多,而在每秒调用多次的情况下则褪色较少。现在,我真的不明白当具有特定不透明度的黑色纹理出现在像素上时会发生什么。

这里是我收集的一些数据。

数据1:
这是粒子轨迹的图表。 x轴表示运行时的FPS,y轴表示路径的长度为多少像素。左侧显示了累积缓冲区中使用的黑色纹理的不透明度。

您可以在此处(在desmos上)找到所有数据以及一些最佳拟合线公式。

请注意,在V小于20之后我停止了计数,因为颜色之间的差异开始变得很小。

我注意到的一些事情是,它们似乎是数字之间的指数关系或除法关系。我还注意到,它们是每一帧在褪色之前的片段,并且当考虑相同的黑色纹理不透明度时,可见的帧数量几乎与fps相同。

数据2:
我用paint.net重新创建了褪色的纹理。我做了一张100x100的图片,并将其涂成红色。然后,我添加了一个具有黑色像素的图层,其不透明度为25/255,然后我重复了此操作并添加了另一个像素,基本上创建了一个渐变。然后,我考虑了每个像素的圆形暗度(在hsv颜色空间中),并对其进行了标记。然后标记暗度值之间的差异。



不幸的是,我没有学到很多东西。只是重申这是非线性关系。而且我还注意到,如果我再进行一次淡入淡出操作,所有的暗度值都将移到它们旁边的正方形处。因此,如果我知道应用了多少次淡入淡出,我就可以预测暗度值。



那么当半透明的黑色纹理混合到另一个纹理上时会发生什么呢? br />如果您愿意多加思考,那么公式
将使我不透明,因此黑色纹理必须处于
顺序,以使粒子轨迹约为“ N”给定
自上一帧以来的dt长?


#1 楼

alpha混合的基本公式如下:

$$ c_ \ text {final} = c_ \ text {source} \ cdot \ alpha + c_ \ text {dest} \ cdot(1-\ alpha)$$

这里,$ c_ \ text {source} $是要混合的事物的颜色,$ c_ \ text {dest} $是要进行混合的背景,和$ \ alpha $在0到1之间。 to

$$ c_ \ text {final} = c_ \ text {dest} \ cdot(1-\ alpha)^ n $$

这确实是指数下降如你所料您可以插入此公式,并获得与您发布的公式非常相似的数字(尽管当我这样做时,我的结果相差一到两个,可能是由于四舍五入;我不确定)。

关于无论路径速率如何都使轨迹显示相同的问题,一种简单的方法是在必要时每帧多次运行累积缓冲区传递,因此无论路径速率如何,路径实际上都有固定的时间步长。这可能比尝试根据帧速率摆弄Alpha的效果更好。不过,它可能太慢了。

一种可能更有效的方法是让粒子每隔一段时间频繁地产生一个新的“尾迹粒子”,其中每个尾迹粒子保持固定的位置,并具有其alpha值。在一段时间内从100%变为0(然后回收)。您必须每帧重新渲染所有粒子,但是如果全屏混合遍历的累积缓冲区的开销变得太高,最终可能会整体上变得更快。

我应该指出,尽管所有这些方法实际上都是基于时间的衰落,而不是您要求的基于距离的衰落(100像素轨迹)。如果所有粒子以相同的速度移动,您可以调整淡入淡出的时间以使轨迹达到所需的长度,但是如果不同的粒子以不同的速度移动,那么在设置其轨迹的淡入时间时就需要考虑到这一点。 。使用累积缓冲区方法也没有简单的方法,因为它对屏幕上的所有内容隐式使用相同的淡入时间。

评论


$ \ begingroup $
非常感谢!现在,我知道了Alpha混合的工作原理并解决了粒子问题!我发现最有效的解决方案是确保该函数每秒被调用60次,无论帧速率如何。非常感谢!
$ \ endgroup $
–J.Doe
2015年12月29日23:51