online - Come implementare il codice shadertoy in three.js-chiarire i dettagli



shadertoy code (1)

Quindi ecco una domanda precedente: Come implementare uno shader ShaderToy in three.js

Ho cercato di implementare i passaggi dal link sopra in questo codice senza successo: three.js / blob / master / examples / webgl_shader.html

Così ho sostituito il vertex shader originale e lo shader del frammento origianl così ho ottenuto questo codice:

<script id="vertexShader" type="x-shader/x-vertex">
    varying vec2 vUv; 
    void main()
    {

     vUv = uv;

        vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
        gl_Position = projectionMatrix * mvPosition;    
    }
</script>

<script id="fragmentShader" type="x-shader/x-fragment">


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

    varying vec2 vUv; 

    void main(void)
    {
        vec2 p = -1.0 + 2.0 *vUv;
        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);
    }
</script>

Questo è chiaro ma come e dove implementare il tuniform:

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' ) },


    };

e le parti iGlobalTime?

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

Quindi la mia domanda è: come modificare questo codice (o qualsiasi codice thrre.js): three.js / blob / master / examples / webgl_shader.html

per visualizzare un esempio shadertoy funzionante che include anche iGlobalTime?

==================== LA PARTE EITED INIZIA QUI =========================

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - shader [Monjori]</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                color: #ffffff;
                font-family:Monospace;
                font-size:13px;
                text-align:center;
                font-weight: bold;

                background-color: #000000;
                margin: 0px;
                overflow: hidden;
            }

            #info {
                position: absolute;
                top: 0px; width: 100%;
                padding: 5px;
            }

            a {

                color: #ffffff;
            }

            #oldie a { color:#da0 }
        </style>
    </head>
    <body>

        <div id="container"></div>
        <div id="info"><a href="http://threejs.org" target="_blank">three.js</a> - shader demo. featuring <a href="http://www.pouet.net/prod.php?which=52761" target="_blank">Monjori by Mic</a></div>

        <script src="../build/three.min.js"></script>

        <script src="js/Detector.js"></script>
        <script src="js/libs/stats.min.js"></script>

        <script id="vertexShader" type="x-shader/x-vertex">
            varying vec2 vUv; 
            void main()
            {
            vUv = uv;
                vec4 mvPosition = modelViewMatrix * vec4(position, 1.0 );
                gl_Position = projectionMatrix * mvPosition;    
            }
        </script>

        <script id="fragmentShader" type="x-shader/x-fragment">


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

            varying vec2 vUv; 

            void main(void)
            {
                vec2 p = -1.0 + 2.0 *vUv;
                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);
            }
        </script>

        <script>

            if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container, stats;

            var camera, scene, renderer;

            var uniforms;

            init();
            animate();

            function init() {

                container = document.getElementById( 'container' );

                camera = new THREE.Camera();
                camera.position.z = 1;

                scene = new THREE.Scene();

                var geometry = new THREE.PlaneBufferGeometry( 2, 2 );

                uniforms = {
                    time: { type: "f", value: 1.0 },
                    resolution: { type: "v2", value: new THREE.Vector2() }
                };

                var material = new THREE.ShaderMaterial( {

                    uniforms: uniforms,
                    vertexShader: document.getElementById( 'vertexShader' ).textContent,
                    fragmentShader: document.getElementById( 'fragmentShader' ).textContent

                } );

                var mesh = new THREE.Mesh( geometry, material );
                scene.add( mesh );

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                container.appendChild( renderer.domElement );

                stats = new Stats();
                stats.domElement.style.position = 'absolute';
                stats.domElement.style.top = '0px';
                container.appendChild( stats.domElement );

                onWindowResize();

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize( event ) {
                renderer.setSize( window.innerWidth, window.innerHeight );

                uniforms.resolution.value.x = renderer.domElement.width;
                uniforms.resolution.value.y = renderer.domElement.height;
            }
            //

            function animate() {

                requestAnimationFrame( animate );

                render();
                stats.update();

            }

            function render() {

                var tuniform = {

                        iGlobalTime:    { type: 'f', value: 0.1 },
                        iChannel0:  { type: 't', value: THREE.ImageUtils.loadTexture( 'textures/brick_bump.jpg') },
                        iChannel1:  { type: 't', value: THREE.ImageUtils.loadTexture( 'textures/brick_bump.jpg' ) },

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


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

                    uniforms.time.value += 0.05;

                    renderer.render( scene, camera );

            }

        </script>

    </body>
</html>

Per convertire qualsiasi shader da shadertoy a uno shader three.js, devi solo avere le variabili / uniformi corrette. Shadertoy ha uniformi disponibili che gli shader three.js non sono predefinite. Ad esempio, Shadertoy ha l'uniforme iResolution, che non si avrà in uno shader three.js come Shadertoy è per il rendering su una tela piatta piuttosto che su un oggetto 3d. iGlobalTime è anche una di queste uniformi che non si trova in uno shader three.js per impostazione predefinita.

Nel codice che hai postato, hai definito correttamente uniforme iGlobalTime, devi solo creare un THREE.Clock una volta quando codifichi le prime esecuzioni, quindi devi aggiornare l'uniforme nella tua funzione di rendering.

uniforms.iGlobalTime.value = clock.getElapsedTime();

Ho implementato questo shader matrix style che utilizza iGlobalTime in three.js qui