我正在制作一个小型 2d 视频游戏,在互联网上搜索与其无关的内容时,我发现了这个视频:http://vimeo.com/67886447 我很喜欢。我想要它。
作者概述了这个过程:
The effect is produced by computing the vector derivative of a source photo then applying iterative advection along the resulting axes. A secondary scalar field controls and strength and magnitude of advection and allows a range of interesting effects including pulsing, waving and breathing.
据我了解:计算梯度场,然后在相应向量的方向和大小上移动像素。我猜时间是矢量幅度的乘数。
所以,我想,我理解我头脑中的过程,但由于我是 GLSL 和一般着色器的新手,我不确定如何编写代码。
到目前为止,我是这样看代码大纲的:
遍历图像,用某种边缘检测算法产生的向量填充矩阵。 再次遍历图像并按矢量幅度*时间置换所有像素。
几个具体问题:
这在性能方面是否可行(当然,在普通 PC 上)?
是否可以使用简单的边缘检测算法(检查附近的8个像素,比较它们之间的差异,并将其作为大小,向量的方向将由2个像素之间最大的角度决定区别)。
我将如何置换像素?我想象移动一个像素会在它原来的地方留下一个空白区域,或者,如果我克隆像素,会有很多奇怪的叠加,图像会变得很糟糕。
编辑:
我刚刚意识到一次完成会更好:计算向量,然后立即移动像素。你怎么看?
我猜,我用错了,把它当成迭代。
这是我目前得到的代码。它很简单,并且仅沿 +x 轴进行。
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
varying vec2 vTexCoord;
uniform sampler2D u_texture; //diffuse map
void main( void ) {
vec2 pos = vec2(1,0);
vec4 px1 = texture2D(u_texture, vTexCoord+(pos/resolution));
vec4 dif = px1 - texture2D(u_texture, vTexCoord);
vec4 color = texture2D(u_texture, vTexCoord+(vec2((dif.r+dif.g+dif.b)*time,0)/resolution));
gl_FragColor = vec4(color.xyz,1.0);
//gl_FlagColor = color;
}
现在我只需要对其余的轴执行此操作。效果实际上看起来就像它应该做的那样。
我为 Y 轴做了这件事,这就是我得到的结果,我该如何修复伪像,所以看起来颜色实际上在扩展,而不是简单地移动。
breathing thing http://rghost.ru/57475312/image.png
(着色器仅应用于背景图像)
最佳答案
您需要像使用 GLSL 的函数式程序员一样思考。你不会遍历任何东西;您提供的函数在给定适当输入的情况下将提供输出的一部分。 GPU 负责在适当的地方应用该函数。根据特定于供应商的扩展,输入需要与输出完全不同——因此输入是不可变的。 GPU 还会组织您输出到的位置。
所以,不,您不会遍历任何内容。你不能编写一个着色器来选择它要输出到的位置,而只能选择它要输出的内容。
您可能想要查看的是 Stam's Advection这几乎颠倒了问题。对于每个输出 P,您将查找对其有贡献的颜色来自何处的记录。由于您可以自由地对输入进行采样(撇开性能问题不谈),您可以收集适当的输出。
关于opengl - 如何在 GLSL 中编写 "Texture Breathing"着色器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25318155/