WEBGL com THREE.JS

Salvei o código criado na aula em /palestra/ (zip). Fiz duas modificações importantes, habilitei o orbit controller, e defini a cor de fundo do render para a mesma cor do fog, assim o efeito fica melhor. Dúvidas para pedro arroba rckt ponto com ponto br. A sombra funciona se você chamar duas vezes o render, ou se você usar animação/orbit. Para importar objetos e texturas, o projeto precisa de um server, o canvas só aceita arquivos do mesmo domínio, e não usando file://.

O que são WEBGL e THREE.JS?

O WEBGL é uma API Javascript para trabalhar com gráficos 3D no navegador, usando canvas. Para tornar o desenvolvimento mais rápido, utilizaremos uma biblioteca, chamada THREE.JS. O Three.js é uma camada de abstração em cima do WEBGL, criado por Ricardo Cabello (mr doob). A compatibilidade do WEBGL é IE11, Edge, Firefox 4, Chrome 18, Safari. Chrome for Android e iOS Safari com limitações. Mais sobre o WEBGL em khronos.org.

Objetos e texturas

Shaders

Os shaders são códigos que definem como uma geometria ou uma material deve se comportar utilizando programação. Esses códigos são passados em string para o driver da GPU (não são javascript). Mais sobre Shaders no Wikipedia. Busque seu shader favorito em Shadertoy.com.

Vertex Shader

      <script id="vertex-shader" type="x-shader/x-vertex">
          
        uniform float time;
        varying vec2 vUv;

        void main()
        {
            vec3 posChanged = position;
            posChanged.x = posChanged.x*(abs(sin(time*1.0)));
            posChanged.y = posChanged.y*(abs(cos(time*1.0)));
            posChanged.z = posChanged.z*(abs(sin(time*1.0)));
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position*(abs(sin(time)/2.0)+0.5),1.0);
            //gl_Position = projectionMatrix * modelViewMatrix * vec4(posChanged,1.0);
        }
        
      </script>
          

Fragment Shader

      <script id="fragment-shader" type="x-shader/x-fragment">
        precision highp float;
        uniform float time;
        uniform float alpha;
        uniform vec2 resolution;
        varying vec2 vUv;

        void main2(void)
        {
        vec2 position = vUv;
        float red = 1.0;
        float green = 0.25 + sin(time) * 0.25;
        float blue = 0.0;
        vec3 rgb = vec3(red, green, blue);
        vec4 color = vec4(rgb, alpha);
        gl_FragColor = color;
        }

        #define PI 3.14159
        #define TWO_PI (PI*2.0)
        #define N 68.5

        void main(void)
        {
        vec2 center = (gl_FragCoord.xy);
        center.x=-10.12*sin(time/200.0);
        center.y=-10.12*cos(time/200.0);

        vec2 v = (gl_FragCoord.xy - resolution/20.0) / min(resolution.y,resolution.x) * 15.0;
        v.x=v.x-10.0;
        v.y=v.y-200.0;
        float col = 0.0;

        for(float i = 0.0; i < N; i++)
        {
        float a = i * (TWO_PI/N) * 61.95;
        col += cos(TWO_PI*(v.y * cos(a) + v.x * sin(a) + sin(time*0.004)*100.0 ));
        }

        col /= 5.0;

        gl_FragColor = vec4(col*1.0, -col*1.0,-col*4.0, 1.0);
        }
      </script>
           

Fragment Shader

      <script id="fragment-shader-frac" type="x-shader/x-fragment">
        // http://glslsandbox.com/e#31923.0
        // precision mediump float;
        uniform vec2 resolution;
        uniform float time;
        uniform vec2 mouse; //Robert Schütze (trirop) 07.12.2015

        float rand(vec2 n) { 
            return fract(sin(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
        }


        float noise(vec2 p){
            vec2 ip = floor(p);
            vec2 u = fract(p);
            u = u*u*(3.0-2.0*u);

            float res = mix(
                mix(rand(ip),rand(ip+vec2(1.0,0.0)),u.x),
                mix(rand(ip+vec2(0.0,1.0)),rand(ip+vec2(1.0,1.0)),u.x),u.y);
            return res*res;
        }

        float walker(float minX, float maxX, float freq)
        {
            return noise( vec2(time*freq, 0.0) )*(maxX-minX)+minX;	
        }

        void main(){

            float a = walker(1.1,1.2,0.05);
            float p0x = walker(0.99,1.01,0.2);
            float p0y = walker(0.95,1.05,0.2);
            float p0z = walker(-0.01,0.01,0.2);

            float c = walker(0.05,1.04,0.05);
            float noi = walker(0.85,1.0,10.);

            vec3 p0 = vec3(p0x,p0y,p0z);

            vec3 p = vec3((gl_FragCoord.xy)/(resolution.y),c);

            for (int i = 1; i < 100; i++){
                p.xzy = vec3(a,0.999,noi)*(abs((abs(p)/dot(p,p)-p0)));
            }


            gl_FragColor.rgb = p;		
            gl_FragColor.a = 0.8;

        }
      </script>
          

Fragment Shader de Água

      <script id="frag-shader-water">
        uniform float time;
        uniform vec2 resolution;

        #define MAX_ITER 4

        float rand( float n )
        {
            return fract(n);
        }
        void main( void ) {
            vec2 sp = gl_FragCoord.xy/resolution.xy;

            vec2 p = sp*6.0 - vec2(125.0);
            vec2 i = p;
            float c = 1.0;
            float cc = rand(1.);
            int ccc = int(cc);

            float inten = 0.01;

            if(ccc==0){
                for (int n = 0; n < MAX_ITER; n++) 
                {
                    float t = time* (0.05 - (3.0 / float(n+1)));
                    i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
                    c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)));
                }
                    c /= float(MAX_ITER);
                    c = 1.5-sqrt(c);
                gl_FragColor = vec4(vec3(c*c*c), 0.4) + vec4(0.0, 0.3, 0.4, 0.4);
            }else{
                for (int n = 0; n < MAX_ITER; n++) 
                {
                    float t = time* (1.0 - (3.0 / float(n+1)));
                    i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(t + i.x));
                    c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),p.y / (cos(i.y+t)/inten)));
                }
                    c /= float(MAX_ITER);
                    c = 1.5-sqrt(c);
                gl_FragColor = vec4(vec3(sin(c)), 0.4) + vec4(0.8, 0.1, 0., 0.4);

            }
        } 
      </script>