WebGL: Custom Shaders

var webglRenderer = i2d.webglLayer('#canvas', {}, {});
var a = -2;
var b = -2;
var c = -1.2;
var d = 2;
var n = Math.pow(2, 18);

var geome = webglRenderer.PointsGeometry();
    geome.setAttr('a_position', {
        value: new Float32Array(n * 2).map(() => Math.random() * 2 - 1),
        size: 2
    });
    geome.setDrawRange(0, n);

var shaderRef = webglRenderer.createShaderEl({
        fragmentShader: document.getElementById('fragmentShader').textContent,
        vertexShader: document.getElementById('vertexShader').textContent,
        uniforms: {
            u_a: {
                value: a.toFixed(2)
            },
            u_b: {
                value: b.toFixed(2)
            },
            u_c: {
                value: c.toFixed(2)
            },
            u_d: {
                value: d.toFixed(2)
            }
        },
        geometry: geome
    });

i2d.queue.onRequestFrame(function (t) {
    shaderRef.setUniformData('u_a', -2.0 + Math.sin(t / 8000));
});

Vertex shader:

<script id="vertexShader" type="x-shader/x-vertex">
        precision highp float;
        const float PI = 3.14159265359;

        uniform float u_a;
        uniform float u_b;
        uniform float u_c;
        uniform float u_d;

        attribute vec2 a_position;

        varying float v_t;

        void main() {
            float x1, x2 = a_position.x;
            float y1, y2 = a_position.y;
            for (int i = 0; i < 8; i++) {
                x1 = x2, y1 = y2;
                x2 = sin(u_a * y1) - cos(u_b * x1);
                y2 = sin(u_c * x1) - cos(u_d * y1);
            }
            v_t = atan(a_position.y, a_position.x) / PI;
            gl_Position = vec4(x2 / 2.0, y2 / 2.0, 0.0, 1.0);
            gl_PointSize = 1.5;
        }
    </script>

Fragment Shader:

<script  id="fragmentShader" type="x-shader/x-fragment">
        precision highp float;
        varying float v_t;
        const float PI = 3.14159265359;
        vec3 cubehelix(float x, float y, float z) {
        float a = y * z * (1.0 - z);
        float c = cos(x + PI / 2.0);
        float s = sin(x + PI / 2.0);
            return vec3(
                z + a * (1.78277 * s - 0.14861 * c),
                z - a * (0.29227 * c + 0.90649 * s),
                z + a * (1.97294 * c)
            );
        }

        vec3 rainbow(float t) {
            if (t < 0.0 || t > 1.0) t -= floor(t);
            float ts = abs(t - 0.5);
            return cubehelix(
                (360.0 * t - 100.0) / 180.0 * PI,
                1.5 - 1.5 * ts,
                0.8 - 0.9 * ts
            );
        }

        void main() {
            gl_FragColor = vec4(rainbow(v_t / 4.0 + 0.25), 1.0);
        }
    </script>

Last updated