使用着色器将纹理像素移动到其中心

时间:2015-03-17 15:29:50

标签: opengl glsl webgl shader

我正试图将平方纹理纹理像素移动到纹理的中心。 下面的代码正在做它的工作,除非我希望像素在到达几何体的中心(一个平面)时消失,而现在它只是变得越来越小,而时间增加,纹理看起来像收缩。

enter image description here

uniform float time;
varying vec2 vUv;

void main() {

    vec2 center = vec2(0.5, 0.5);
    vec2 newPosition = vec2(vUv.x + t * (center.x - vUv.x), vUv.y + t * (center.y - vUv.y);

    gl_FragColor = texture2D( texture, vec2(newPosition.x, newPosition.y) );
}

编辑:

将此视为纹理中心的黑洞。 enter image description here

2 个答案:

答案 0 :(得分:1)

根据我的理解,您希望纹素在 vUv 时位于t=0,并在一段时间后位于center

结果是放大纹理的中心。

实际上,您的代码是从t = 0t = 1执行的。当 t = 1 时,纹素位置为center

您使用mix功能具有相同的行为。

vec2 newPosition = mix(vUv, center, t);

t = 1 全部时,纹素位于center且图像为单色图像。 (纹理中心的颜色)。

你的问题是t继续增长。当t > 1纹素继续沿着它们的路径行进时。他们都在中心见面后,现在彼此偏离了。效果是纹理反转,你看到缩小。

根据您希望的结果,有多种解决方案:

  • 您想要进行最大缩放并保留此图像:clamp t ,范围为[0, 1],如此t = clamp(t, 0, 1);

  • 您想要进行最大缩放并且图像消失:停止在t > 1时绘制它(如果您不想要单色图像,则为t >= 1。)

  • 你想要一个无限放大,纹理元素越来越靠近中心但从未到达它。

对于第三种行为,您可以使用新的t,比如t2

  • t2 = 1 - 1/(t*k+1); // Where k > 0
  • t2 = 1 - pow(k, -t); // Where k > 1
  • t2 = f(t); // Where f(0) = 0, f is increasing, continuous and limit in +∞ is 1

答案 1 :(得分:1)

最近,我遇到了同样的问题。但是我在互联网上的某个地方找到了替代解决方案,它使用隧道着色器而不是将纹理的纹理像素移动到中心。它有类似的行为。

float time = -u_time * 0.15;
vec2 p = 2.0 * gl_FragCoord.xy / u_res.xy -1.0;
vec2 uv;

float a = atan(p.y,p.x);
float r = sqrt(dot(p,p));
uv.x = time+.1/r;
uv.y = a/3.1416;

vec4 bg = texture2D(u_texture, uv);

我希望它会有所帮助。