点对点显示器(物理b/w像素)的这个YouTube视频显示了一种可能被称为溶解或分散的效果的反面,即由像素移动形成字母而产生的文本。这里有一个剪短的剪辑,只显示“结晶”(这不是一个合适的名称吗?)

(资料来源:纽约早餐)
想要了解更多关于这个或类似效果的信息,我发现后效:像沙子一样吹走的文字有一个粉碎效应,很明显是一个三维物理模拟的粒子系统。
对于一个粒子系统,我可以想象随机地“溶解”每个像素(字符)不会太难。逆转效果,如视频所示,可以使用预先计算的序列,甚至只是动画精灵对每个字母。或者,噪声中的每一个像素都被选择为一个字母(看起来更复杂,可能需要聚类)。
然后我找到了一个实现和现场演示:
我认为效果非常相似,所以我认为他们使用了一个粒子系统。
作为比较,这里尝试创建一个“正常”的动画噪音溶解(随机抖动),如评论中所建议,但我认为很明显,原来的像素确实在移动,这不仅仅是二进制混合效应:

它要求每个像素至少有一个随机值:在动画的哪个帧上活动。
这就是毛霉溶液的样子(伪交换100个帧中的每一个10,000个相邻像素,然后使用相同的伪随机数序列,刚刚反转):

发布于 2017-05-18 00:24:27
如果您真的想使用尽可能少的内存,可以使用比存储单个映像(第一帧)所需的内存更多的内存,前提是可以预先进行一些预处理。
如果您复制以下乱七八糟的图像,这弹琴将将其作为输入:

然后,它会将像素一步一步地移动,这样它们就会漂移到适当的位置,再次给出原始图像:

这不需要任何内存来跟踪粒子。算法非常简单:
不需要额外的内存,因为没有粒子被使用。我们只是随意地交换像素,没有目的地。关键在于选择一个明显混乱的初始图像,使像素位于正确的位置,这样,应用一百万个随机交换就会使所有像素都位于正确的位置,从而给出所需的文本。
为此,准备好的小提琴接受一个图像作为输入,并输出一个混乱的图像,该图像被精确地安排为主要的jsfiddle的输入。
这个需要更多的内存,但仍然是一个非常简单的算法:
这正相反,主要的小提琴将做什么,所以混乱将完全颠倒,恢复原来的形象。你可以粘贴在一个彩色图像,或者,如果你想只使用黑白像素的文本,也将工作。上面显示的示例图像介于这两个极端之间,因为它有用于反混叠的灰度像素,与黑白像素一起徘徊。
百万像素互换可以用于相当小的图像。对于更大的尺寸,这不会使它们混乱到完全模糊原始图像,所以您需要调整掉期的数量。
没有重新播种
语言
请注意,这只是因为伪随机数生成器在这两种算法开始时被重新插入,以确保它们都处理完全相同的“随机”数字列表。大多数语言都允许您重新分配随机数生成器,这是一种简单的方法。JavaScript没有,因此jsfiddles包括一个xorshift的实现,以允许重新播种。
即使使用允许重新播种的语言,如果硬件是特别有限的,那么您可能需要考虑xorshift,因为它非常快,并且只使用4个字节的内存作为其状态。它也只有几行代码。
*请注意,顺序与刚才颠倒的顺序不完全相同。在此示例代码中,对要交换的每一对像素使用三个随机数。因此,为了避免选择不同的像素对,每个三重的顺序必须保持不变。例如:
1,2,3,4、5、6,7、8、9
必须倒转到
7、8、9,4、5、6,1,2,3
为了在反向运行时为每个像素对选择相同的x值、y值和方向。
发布于 2017-05-15 19:07:39
您完全可以在OpenGL/WebGL片段着色器中完成此操作:
附加您希望显示为纹理/样本2D的图像。附上当前时间的制服,以及您希望效果完成的时间。
uniform sampler2D myTexture;
uniform float currentTime;
uniform float finishTime;
#define TWO_PI 6.283185307179586476925286766559其次,应用确定性伪随机噪声算法代替给定距离和指南针方向的像素.类似于:
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
float R = rand(thisPixel.xy);
var float timeLeft = clamp((finishTime - currentTime) * R, 0.0, 10000.0);
float direction = classic1dPerlinNoise( R + currentTime ) * TWO_PI;
float offsetX = thisPixel.x + sin(direction) * timeLeft / 500.0;
float offsetY = thisPixel.Y + cos(direction) * timeLeft / 500.0;
vec2 texCoord = vec2( offsetX, offsetY );注意,上面的夹子在适当的时间停止效果,并设置最大的效果持续时间(在本例中为10秒)。
最后,查找您的纹理示例:
gl_FragColor = gl_Color * texture2D(myTexture, texCoord);瞧!虽然像素可能不会在彼此周围导航,但它们至少会移动到适当的位置,每个像素在分配给它们的时间范围内都会达到自己的不同时间,并且使用非常少的内存和CPU时间。
https://computergraphics.stackexchange.com/questions/5104
复制相似问题