kgl实现的玻璃体流体发散动画效果

代码语言:html

所属分类:粒子

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>Instancing Box &amp; Curl Noise</title>
    <style>
        html,
        body {
            height: 100%;
        }
        body {
            overflow: hidden;
            margin: 0;
        }
        canvas {
            width: 100%;
            height: 100%;
        }
    </style>

</head>
<body translate="no">
    <script type="x-shader/x-fragment" id="reset-velocity">
        precision highp float;

        void main () {
            gl_FragColor = vec4(vec3(0.), 1.);
        }
    </script>
    <script type="x-shader/x-fragment" id="reset-position">
        precision highp float;

        uniform vec2 size;

        // https://github.com/mattdesl/glsl-random
        highp float random(vec2 co) {
            highp float a = 12.9898;
            highp float b = 78.233;
            highp float c = 43758.5453;
            highp float dt = dot(co.xy, vec2(a, b));
            highp float sn = mod(dt, 3.14);
            return fract(sin(sn) * c);
        }

        void main () {
            vec2 nPosition = gl_FragCoord.st / size * 2. - 1.;
            vec4 position = vec4(
                nPosition * size,
                0.,
                random(nPosition)
            );
            gl_FragColor = position;
        }
    </script>
    <script type="x-shader/x-fragment" id="velocity">
        precision highp float;

        uniform vec2 size;
        uniform sampler2D prevVelocityTexture;
        uniform sampler2D prevPositionTexture;

        //
        // Description : Array and textureless GLSL 2D/3D/4D simplex
        //               noise functions.
        //      Author : Ian McEwan, Ashima Arts.
        //  Maintainer : ijm
        //     Lastmod : 20110822 (ijm)
        //     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
        //               Distributed under the MIT License. See LICENSE file.
        //               https://github.com/ashima/webgl-noise
        //

        vec3 mod289(vec3 x) {
            return x - floor(x * (1.0 / 289.0)) * 289.0;
        }

        vec4 mod289(vec4 x) {
            return x - floor(x * (1.0 / 289.0)) * 289.0;
        }

        vec4 permute(vec4 x) {
            return mod289(((x*34.0)+1.0)*x);
        }

        vec4 taylorInvSqrt(vec4 r) {
            return 1.79284291400159 - 0.85373472095314 * r;
        }

        float snoise(vec3 v) {
            const vec2  C = vec2(1.0/6.0, 1.0/3.0);
            const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);

            // First corner
            vec3 i = floor(v + dot(v, C.yyy));
            vec3 x0 = v - i + dot(i, C.xxx);

            // Other corners
            vec3 g = step(x0.yzx, x0.xyz);
            vec3 l = 1.0 - g;
            vec3 i1 = min(g.xyz, l.zxy);
            vec3 i2 = max(g.xyz, l.zxy);

            //   x0 = x0 - 0.0 + 0.0 * C.xxx;
            //   x1 = x0 - i1  + 1.0 * C.xxx;
            //   x2 = x0 - i2  + 2.0 * C.xxx;
            //   x3 = x0 - 1.0 + 3.0 * C.xxx;
            vec3 x1 = x0 - i1 + C.xxx;
            vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y
            vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y

            // Permutations
            i = mod289(i);
            vec4 p = permute(permute(permute(
                i.z + vec4(0.0, i1.z, i2.z, 1.0))
                + i.y + vec4(0.0, i1.y, i2.y, 1.0))
                + i.x + vec4(0.0, i1.x, i2.x, 1.0));

            // Gradients: 7x7 points over a square, mapped onto an octahedron.
            // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
            float n_ = 0.142857142857; // 1.0/7.0
            vec3  ns = n_ * D.wyz - D.xzx;

            vec4 j = p - 49.0 * floor(p * ns.z * ns.z); //  mod(p,7*7)

            vec4 x_ = floor(j * ns.z);
            vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)

            vec4 x = x_ *ns.x + ns.yyyy;
            vec4 y = y_ *ns.x + ns.yyyy;
            vec4 h = 1.0 - abs(x) - abs(y);

            vec4 b0 = vec4(x.xy, y.xy);
            vec4 b1 = vec4(x.zw, y.zw);

            //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
            //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
            vec4 s0 = floor(b0)*2.0 + 1.0;
            vec4 s1 = floor(b1)*2.0 + 1.0;
            vec4 sh = -step(h, vec4(0.0));

            vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy;
            vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww;

            vec3 p0 = vec3(a0.xy, h.x);
            vec3 p1 = vec3(a0.zw, h.y);
            vec3 p2 = vec3(a1.xy, h.z);
            vec3 p3 = vec3(a1.zw, h.w);

            //Normalise gradients
            vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
            p0 *= norm.x;
            p1 *= norm.y;
            p2 *= norm.z;
            p3 *= norm.w;

            // Mix final noise value
            vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
            m = m * m;
            return 42.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1),
                dot(p2, x2), dot(p3, x3)));
        }

        // https://www.npmjs.com/package/glsl-curl-noise
        vec3 snoiseVec3(vec3 x) {

            float s = snoise(vec3(x));
            float s1 = snoise(vec3(x.y - 19.1, x.z + 33.4, x.x + 47.2));
            float s2 = snoise(vec3(x.z + 74.2, x.x - 124.5, x.y + 99.4));
            vec3 c = vec3(s, s1, s2);
            return c;

        }


        vec3 curlNoise(vec3 p) {

            const float e = .1;
            vec3 dx = vec3(e, 0.0, 0.0);
            vec3 dy = vec3(0.0, e, 0.0);
            vec3 dz = vec3(0.0, 0.0, e);

            vec3 p_x0 = snoiseVec3(p - dx);
            vec3 p_x1 = snoiseVec3(p + dx);
            vec3 p_y0 = snoiseVec3(p - dy);
            vec3 p_y1 = snoiseVec3(p + dy);
            vec3 p_z0 = snoiseVec3(p - dz);
            vec3 p_z1 = snoiseVec3(p + dz);

            float x = p_y1.z - p_y0.z - p_z1.y + p_z0.y;
            float y = p_z1.x - p_z0.x - p_x1.z + p_x0.z;
            float z = p_x1.y - p_x0.y - p_y1.x + p_y0.x;

            const float divisor = 1.0 / (2.0 * e);
            return normalize(vec3(x, y, z) * divisor);

        }

        const float speed = 2.;
        const float density = 0.007;
        const float ease = 0.02;

        void main () {
            vec2 uv = gl_FragCoord.st / size;
            vec4 velocity = texture2D(prevVelocityTexture, uv);
            vec3 prevPosition = texture2D(prevPositionTexture, uv).xyz;
            velocity.xyz += curlNoise(prevPosition * density) * speed;
            velocity.xyz *= velocity.w;
            if (velocity.w > 0.01) {
                velocity.w -= velocity.w * ease;
            } else {
                velocity.w = 1.;
            }
            gl_FragColor = velocity;
        }
    </script>
    <script type="x-shader/x-fragment" id="position">
        precision highp float;

        uniform vec2 size;
        uniform sampler2D prevPositionTexture;
        uniform sampler2D velocityTexture;

        void main () {
            vec2 uv = gl_FragCoord.st / size;
            vec4 prevPosition = texture2D(prevPositionTexture, uv);
            vec4 velocity = texture2D(velocityTexture, uv);

            vec3 position;
            if (velocity.w == 1.) {
                vec2 nPosition = uv * 2. - 1.;
                position = vec3(nPosition * size, 0.);
            } else {
                position = prevPosition.xyz + velocity.xyz;
            }

            gl_FragColor = vec4(position, prevPosition.w);
        }
    </script>
    <script type="x-shader/x-vertex" id="main-vs">
        attribute vec3 position;
        attribute vec3 normal;
        attribute vec2 instancedUv;

        uniform sampler2D positionTexture;
        uniform sampler2D velocityTexture;
        uniform mat4 mvpMatrix;
        uniform mat4 invMatrix;
        uniform vec3 lightDirection;
        uniform vec3 ambientColor;
        uniform vec3 eyeDirection;
        uniform float time;

        varying vec4 vColor;

        // https://github.com/yuichiroharai/glsl-y-rotate#readme
        mat3 rotateQ(vec3 axis, float rad) {
            float hr = rad / 2.0;
            float s = sin(hr);
            vec4 q = vec4(axis * s, cos(hr));
            vec3 q2 = q.xyz + q.xyz;
            vec3 qq2 = q.xyz * q2;
            vec2 qx = q.xx * q2.yz;
            float qy = q.y * q2.z;
            vec3 qw = q.w * q2.xyz;

            return mat3(
                1.0 - (qq2.y + qq2.z), qx.x - qw.z, qx.y + qw.y,
                qx.x + qw.z, 1.0 - (qq2.x + qq2.z), qy - qw.x,
                qx.y - qw.y, qy + qw.x, 1.0 - (qq2.x + qq2.y)
            );
        }

        // https://github.com/mattdesl/glsl-random
        highp float random(vec2 co) {
            highp float a = 12.9898;
            highp float b = 78.233;
            highp float c = 43758.5453;
            highp float dt = dot(co.xy, vec2(a, b));
            highp float sn = mod(dt, 3.14);
            return fract(sin(sn) * c);
        }

        vec3 hsv(float h, float s, float v) {
            vec4 t = vec4(1., 2. /.........完整代码请登录后点击上方下载按钮下载查看

网友评论0