OK Ho cercato di ricreare l'effetto quindi ho usato questo come struttura:
ho preso l'immagine e ridimensionarla a 512x512
quindi è potenza di 2 riempire il bordo con il nero. Siccome non condividi Vertex shader, ho creato il mio. Il GL esegue il rendering di un singolo quadrupolo <-1,+1>
senza coordinate di trama o matrici solo glVertex2f()
con singola 2D trama vincolata all'unità 0
. Riscrivo leggermente il tuo frammento per adattarlo all'output. Inoltre ho aggiunto tx,ty
uniformi per animare facilmente l'effetto con posizione del mouse <0,1>
Questi sono gli shaders primo vertice:
// Vertex
varying vec2 v_texCoord;
void main()
{
v_texCoord=gl_Vertex.xy;
gl_Position=gl_Vertex;
}
E poi frammento:
// Fragment
varying vec2 v_texCoord; // holds the Vertex position <-1,+1> !!!
uniform sampler2D s_baseMap; // used texture unit
uniform float tx,ty; // x,y waves phase
vec2 SineWave(vec2 p)
{
// convert Vertex position <-1,+1> to texture coordinate <0,1> and some shrinking so the effect dont overlap screen
p.x=(0.55*p.x)+0.5;
p.y=(-0.55*p.y)+0.5;
// wave distortion
float x = sin(25.0*p.y + 30.0*p.x + 6.28*tx) * 0.05;
float y = sin(25.0*p.y + 30.0*p.x + 6.28*ty) * 0.05;
return vec2(p.x+x, p.y+y);
}
void main()
{
gl_FragColor = texture2D(s_baseMap,SineWave(v_texCoord));
}
Questo è uscita per tx=0.3477,ty=0.7812
che visivamente più o meno corrispondenze il tuo esempio:
come si può vedi ho aggiunto alcuni termini nelle onde sin così da ottenere anche una distorsione distorta.
Se avete la v_texCoord
già nella gamma <0,1>
poi ignorare il
p.x=(0.55*p.x)+0.5;
p.y=(-0.55*p.y)+0.5;
o riscrivere per (in modo che lo strizzacervelli e coefficienti di rimanere come dovrebbe)
p.x=(1.1*p.x)-0.05;
p.y=(1.1*p.y)-0.05;
Se si utilizza diversa consistenza (non mio), quindi è necessario ridimensionare tutti i coefficienti.
[edit1] coefficienti significato
prima ho iniziato con la vostra:
float x = sin(10.0*p.y) * 0.15;
float y = sin(10.0*p.x) * 0.15;
Il 0.15
è ampiezza dell'onda che sembra essere troppo grande quindi abbassarlo 0.05
. Quindi 10.0
è la frequenza, maggiore è il numero più saranno le onde lungo l'asse. Per puro errore di prova & determino che dovrebbero essere 30.0
per asse ye 25.0
per asse x in modo che il numero di onde corrisponda all'output desiderato.
float x = sin(25.0*p.y) * 0.05;
float y = sin(30.0*p.x) * 0.05;
Dopo questo ho notato che le onde dovrebbero essere un po 'falsati quindi aggiungo dipendere sull'altro asse anche dopo qualche ritocco scoperto questa equazione:
float x = sin(25.0*p.y + 30.0*p.x) * 0.05;
float y = sin(25.0*p.y + 30.0*p.x) * 0.05;
dove entrambi i coefficienti sono uguali a tra gli assi (strano ma funzionante mi aspettavo che avrei bisogno di avere coefficienti diversi tra gli assi). Dopo questo è solo una questione di trovare la fase corretta per ogni asse in modo aggiungo sfasamento controllato dalla posizione del mouse (tx,ty) <0.0,1.0>
così ho preso la finale:
float x = sin(25.0*p.y + 30.0*p.x + 6.28*tx) * 0.05;
float y = sin(25.0*p.y + 30.0*p.x + 6.28*ty) * 0.05;
Poi io gioco con il mouse (stampa la sua posizione) finché non ho avuto abbastanza vicino per abbinare l'output desiderato, che è stato quando tx=0.3477,ty=0.7812
in modo da poter codificare
float x = sin(25.0*p.y + 30.0*p.x + 6.28*0.3477) * 0.05;
float y = sin(25.0*p.y + 30.0*p.x + 6.28*0.7812) * 0.05;
1. si dovrebbe aggiungere anche la texture di ingresso non distorta per il test. 2. devi distorcere anche l'asse 'x' che stai calcolando' y = sin (w * p.x + t) * A; 'quindi prova a distorcere anche' x' come 'x = sin (w * p.y + t) * A; 'e può essere giocato un po 'con le costanti (con costanti separate per' x' e per 'y'). – Spektre
grazie per la risposta, provo a distorcere x asix e applicare v_texCoord.y come fattore. ma il risultato non sembra giusto. – thrillerist