2014-07-18 14 views
9

alla ricerca di informazioni su come ricreare i parametri di ShaderToy iGlobalTime, iChannel ecc all'interno di threejs. So che iGlobalTime è il tempo trascorso da quando Shader è partito, e penso che la roba di iChannel sia per estrarre rgb dalle trame, ma apprezzerei le informazioni su come impostarle.Come implementare uno shader ShaderToy in three.js?

modifica: sono stati esaminati tutti gli shader forniti con gli esempi three.js e pensiamo che le risposte siano tutte da qualche parte - basta trovare l'equivalente ad es. iChannel1 = un input di trama ecc.

risposta

26

Non sono sicuro di aver risposto alla tua domanda, ma potrebbe essere utile per gli altri conoscere i passaggi di integrazione per shadertoys a TRE.

In primo luogo, è necessario sapere che shadertoys è un framment shader. Detto questo, devi impostare un vertex shader "general purpose" che dovrebbe funzionare con tutti gli shadertoys (framment shaders).

Fase 1 creare un "general purpose" vertex shader

varying vec2 vUv; 
void main() 
{ 
    vUv = uv; 

    vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 
    gl_Position = projectionMatrix * mvPosition; 
} 

Questa vertex shader è piuttosto semplice. Si noti che abbiamo definito una variabile variabile vUv per indicare allo shader di frammenti dove si trova la mappatura della trama. Questo è importante perché non useremo la risoluzione dello schermo (iResolution) per il nostro rendering di base. Utilizzeremo invece le coordinate della trama. Lo abbiamo fatto per integrare più shadertoys su oggetti diversi nella stessa scena di THREEJS.

Passaggio 2 Scegli gli shadertoys che vogliamo e crea lo shader di frammenti. (Ho scelto un semplice giocattolo che funziona bene: Simple tunnel 2D by niklashuss).

Ecco il codice dato per questo giocattolo:

void main(void) 
{ 
    vec2 p = gl_FragCoord.xy/iResolution.xy; 
    vec2 q = p - vec2(0.5, 0.5); 

    q.x += sin(iGlobalTime* 0.6) * 0.2; 
    q.y += cos(iGlobalTime* 0.4) * 0.3; 

    float len = length(q); 

    float a = atan(q.y, q.x) + iGlobalTime * 0.3; 
    float b = atan(q.y, q.x) + iGlobalTime * 0.3; 
    float r1 = 0.3/len + iGlobalTime * 0.5; 
    float r2 = 0.2/len + iGlobalTime * 0.5; 

    float m = (1.0 + sin(iGlobalTime * 0.5))/2.0; 
    vec4 tex1 = texture2D(iChannel0, vec2(a + 0.1/len, r1)); 
    vec4 tex2 = texture2D(iChannel1, vec2(b + 0.1/len, r2)); 
    vec3 col = vec3(mix(tex1, tex2, m)); 
    gl_FragColor = vec4(col * len * 1.5, 1.0); 
} 

Fase 3 Personalizzare il codice grezzo shadertoy di avere una completa dello shader frammento GLSL. La prima cosa che manca del codice è la dichiarazione di uniformi e variazioni. Aggiungere li nella parte superiore del file frag dello shader (basta copiare e incollare il seguente):

uniform float iGlobalTime; 
uniform sampler2D iChannel0; 
uniform sampler2D iChannel1; 

varying vec2 vUv; 

Nota, solo sono dichiarate le variabili shadertoys utilizzate per quel campione, più la variazione VUV precedentemente dichiarati nella nostra vertex shader.

L'ultima cosa che dobbiamo fare è la corretta mappatura UV, ora che abbiamo deciso di non usare la risoluzione dello schermo. Per farlo, basta sostituire la linea che utilizza le uniformi IResolution cioè .:

vec2 p = gl_FragCoord.xy/iResolution.xy; 

con:

vec2 p = -1.0 + 2.0 *vUv; 

Questo è tutto, i vostri shader sono ora pronti per l'uso nel vostro THREEJS scene.

Fase 4 Il codice THREEJS:

Impostare uniforme:

var tuniform = { 
     iGlobalTime: { type: 'f', value: 0.1 }, 
     iChannel0: { type: 't', value: THREE.ImageUtils.loadTexture('textures/tex07.jpg') }, 
     iChannel1: { type: 't', value: THREE.ImageUtils.loadTexture('textures/infi.jpg') }, 
    }; 

Assicurarsi che le texture sono avvolgendo:

tuniform.iChannel0.value.wrapS = tuniform.iChannel0.value.wrapT = THREE.RepeatWrapping; 
tuniform.iChannel1.value.wrapS = tuniform.iChannel1.value.wrapT = THREE.RepeatWrapping; 

Creare il materiale con le shader e aggiungere a una planegometria. Il planegeometry() simulerà la risoluzione dello schermo dello shadertoys 700x394, in altre parole sarà meglio trasferire il lavoro che l'artista ha intenzione di condividere.

var mat = new THREE.ShaderMaterial({ 
      uniforms: tuniform, 
      vertexShader: vshader, 
      fragmentShader: fshader,    
      side:THREE.DoubleSide 
     }); 

var tobject = new THREE.Mesh(new THREE.PlaneGeometry(700, 394,1,1), mat); 

Infine, aggiungere il delta del THREE.Clock() per iGlobalTime valore e non il tempo totale nella vostra funzione di aggiornamento.

tuniform.iGlobalTime.value += clock.getDelta(); 

Questo è vero, si è ora in grado di eseguire la maggior parte delle shadertoys con questa configurazione ...

+0

Grazie per la risposta. ma da dove viene questo? 'vec2 p = -1.0 + 2.0 * vUv;' – socrateisabot

+3

Permette di convertire le coordinate UV in coordinate assolute XY. Questo è il trucco/hack che lo fa funzionare ... – INF1

+0

ottime informazioni! Ho l'esempio che descrivi lavorando. Guardando https://www.shadertoy.com/view/XsBXWt# sono bloccato sull'ingresso channel0 che è un file audio. Devo passare attraverso la configurazione del materiale audio web HTML5 per questo? –

7

Questo è un vecchio thread, ma adesso c'è un metodo automatico per fare questo. Basta andare su http://shaderfrog.com/app/editor/new e in alto a destra fare clic su "Importa> ShaderToy" e incollare l'URL. Se non è pubblico, puoi incollare il codice sorgente grezzo. Quindi puoi salvare lo shader (richiede la registrazione, nessuna email di conferma) e fare clic su "Esporta> Three.js".

Potrebbe essere necessario modificare leggermente i parametri dopo l'importazione, ma spero di migliorarlo nel tempo. Ad esempio, ShaderFrog non supporta ancora gli ingressi audio e video, ma è possibile visualizzarli in anteprima con le immagini.

Proof of concept:

ShaderToy https://www.shadertoy.com/view/MslGWN

ShaderFrog http://shaderfrog.com/app/view/247

Full disclosure: Io sono l'autore di questo strumento che ho lanciato la settimana scorsa. Penso che questa sia una caratteristica utile.

+0

grazie - guardando ora. –

+0

Ho provato questo e restituisce sempre un errore e lo shader non verrà compilato. Sto cercando di importare questo shader: https://www.shadertoy.com/view/4sSGDc – Ajq

+0

Ci sono ancora alcuni casi limite di sintassi che causano l'arresto anomalo dell'importatore. Aggiungo questo alla lista degli errori –

1

Questo è basato su varie fonti, inclusa la risposta di @ INF1.

Fondamentalmente si inserisce manca variabili uniformi da Shadertoy (iGlobalTime ecc, consultare questo elenco: https://www.shadertoy.com/howto) nella shader frammento, la si rinomina mainImage(out vec4 z, in vec2 w)-main(), e quindi si modifica z nel codice sorgente per 'gl_FragColor'. Nella maggior parte degli Shadertoys 'z' è 'fragColor'.

Ho fatto questo per due fantastici shader di questo ragazzo (https://www.shadertoy.com/user/guil) ma sfortunatamente non ho ottenuto l'esempio di marmo per il lavoro (https://www.shadertoy.com/view/MtX3Ws).

Un jsFiddle funzionante è qui: https://jsfiddle.net/dirkk0/zt9dhvqx/ Cambiare lo shader da frag1 a frag2 nella riga 56 per vedere entrambi gli esempi.

E non 'Tidy' in jsFiddle - rompe gli shader.

EDIT: https://medium.com/@dirkk/converting-shaders-from-shadertoy-to-threejs-fe17480ed5c6

Problemi correlati