首页 文章

如何在GLSL中编写“纹理呼吸”着色器?

提问于
浏览
3

我正在研究一个小的2D视频游戏,在网上搜索与它无关的东西时,我发现了这个视频:http://vimeo.com/67886447我真的很喜欢它 . 我要它 .

作者概述了这个过程:

通过计算源照片的矢量导数然后沿结果轴应用迭代平流来产生效果 . 次级标量场控制平流的强度和幅度,并允许一系列有趣的效果,包括脉冲,挥动和呼吸 .

据我所知:计算梯度场,然后像素在相应矢量的方向和幅度上移动 . 我猜测时间是矢量幅度的乘数 .

所以,我想,我理解我脑海中的过程,但由于我是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

(着色器仅应用于背景图像)

1 回答

  • 5

    你需要更像是GLSL中的函数式程序员 . 你不会迭代任何东西;您提供的函数在给定适当的输入的情况下将提供输出的片段 . GPU处理在适当的地方应用该功能 . 根据特定于供应商的扩展,输入需要完全不同于输出 - 因此输入是不可变的 . GPU也会组织您输出的位置 .

    所以,不,你不会迭代任何东西 . 而且你不能写一个着色器来选择它要输出的位置,只能输出它要输出的内容 .

    你可能想要研究的是Stam's Advection,它几乎颠倒了这个问题 . 对于每个输出P,您将查找有助于它的颜色来自何处的记录 . 由于您可以自由地对输入进行采样(不考虑性能问题),因此您可以收集适当的输出 .

相关问题