2015-03-17 8 views
11

Ich versuche quadratische Textur Texel in die Mitte der Textur folgenden Zeit zu bewegen. Der folgende Code macht seinen Job, wenn ich nicht möchte, dass das Pixel verschwindet, wenn es das Zentrum der Geometrie erreicht (eine Ebene) und für jetzt wird es nur immer kleiner, während die Zeit zunimmt und die Textur scheint wie kontrahiert zu sein.Verwenden von Shader, um Texel zu seiner Mitte zu bewegen

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)); 
} 

Edit:

Betrachten Sie das als ein schwarzes Loch in der Textur Mitte. enter image description here

+0

t liegt zwischen 0,0 und 1,0? – Robinson

+0

t wird immer in der Renderschleife erhöht: (d. H. T + = 0.01) – socrateisabot

+0

Dann wird die Disparität zwischen 'vUv.x' und' t * (center.x - vUv.x) 'weiter wachsen. Bei 't = 0.0 'hast du' (vUv.x, vUv.y) 'und' t = 1.0' hast du '(center.x, center.y)'. Was Sie hier wirklich haben, ist 't * center - (1.0 - t) * vUv '- nach' t> 1.0' für Pixel links von der Mitte ist dieser Wert positiv und rechts von der Mitte ist es negativ, also Anstatt Ihre Textur zu verschieben, skalieren Sie sie tatsächlich (und spiegeln sie auch). Haben Sie versucht, 'vec2 (vUv.x + t * center.x, vUv.y + t * center.y)' stattdessen zu verwenden? –

Antwort

1

Wie ich es verstehe, wollen Sie das Texel auf vUv wenn t=0 und bei center nach einer Weile sein.

Das Ergebnis ist ein Zoom in die Mitte der Textur.

Tatsächlich ist Ihr Code von t = 0 zu t = 1. Wenn t = 1 ist, ist die Texelposition center.

Sie haben das gleiche Verhalten mit der mix Funktion.

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

Auch wenn t = 1alle das Texel sind bei center und das Bild ein einfarbiges Bild. (Die Farbe der Mitte der Textur).

Ihr Problem ist, dass t weiter wächst. Und wenn t > 1 das Texel auf ihrem Weg weitergeht. Nachdem sie sich alle in der Mitte treffen, verlassen sie sich nun voneinander. Der Effekt ist, dass die Textur umgekehrt wird und Sie eine Verkleinerung sehen.

Je nachdem, wie Sie es wollen, dort enden, sind mehrere Lösungen:

  • Sie wollen den maximalen Zoom gehen und das Bild zu halten: clampt im Bereich [0, 1] wie diese t = clamp(t, 0, 1);.

  • Sie wollen zum maximalen Zoom gehen und das Bild verschwinden: Stop, um es zu zeichnen, wenn t > 1 (oder t >= 1, wenn Sie das einzelne Farbbild nicht wollen).

  • Sie möchten einen unendlichen Zoom, dh Texel gehen näher und näher an der Mitte, aber nie erreichen es.

Für diese dritte Verhalten, ein neues t verwenden können, sagen 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

Vor kurzem habe ich konfrontiert die gleicher Fehler. Aber ich habe eine alternative Lösung irgendwo im Internet gefunden, die einen Tunnel-Shader benutzt, anstatt Textur-Texel in die Mitte zu bewegen. Es hat ein ähnliches Verhalten wie du es willst.

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); 

Ich hoffe, es wird hilfreich sein.

+0

Ja, fand das auch, danke :) – socrateisabot

+0

@socratisabot, wenn Sie denken, dass es nützlich ist, sollten Sie es als Antwort überprüfen! – Nolesh