gl-matrix实现可调配置webgl粒子特效动画代码

代码语言:html

所属分类:粒子

代码描述:gl-matrix实现可调配置webgl粒子特效动画代码

代码标签: gl-matrix 可调 配置 webgl 粒子 特效 动画 代码

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

<!DOCTYPE html>
<html lang="en" >


<head>
    <meta charset="utf-8">

    <style>
        body { 
            margin: 0; 
            overflow: hidden; 
            background: linear-gradient(to bottom, #000000, #0a0a2a);
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            font-family: 'Arial', sans-serif;
            color: #fff;
        }
        canvas { 
            display: block; 
            width: 800px;
            height: 800px;
            cursor: pointer;
            box-shadow: 0 0 50px rgba(0, 100, 255, 0.3);
        }
        .controls {
            position: absolute;
            top: 20px;
            right: 20px;
            width: 250px;
            background: rgba(0, 0, 20, 0.7);
            padding: 15px;
            border-radius: 8px;
            z-index: 100;
            max-height: 90vh;
            overflow-y: auto;
        }
        .controls h3 {
            margin-top: 15px;
            margin-bottom: 5px;
            border-bottom: 1px solid rgba(100, 150, 255, 0.5);
            padding-bottom: 5px;
        }
        .control-group {
            margin-bottom: 15px;
        }
        .control-item {
            margin-bottom: 8px;
        }
        label {
            display: block;
            margin-bottom: 3px;
            font-size: 12px;
        }
        input[type="range"] {
            width: 100%;
        }
        input[type="color"] {
            width: 50px;
            height: 25px;
            border: none;
            cursor: pointer;
        }
        .color-picker {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .color-value {
            font-size: 11px;
            color: #aaa;
        }
        button {
            background: rgba(30, 30, 100, 0.6);
            border: 1px solid rgba(100, 150, 255, 0.5);
            padding: 8px 15px;
            color: white;
            border-radius: 5px;
            cursor: pointer;
            transition: all 0.3s;
            text-transform: uppercase;
            font-size: 12px;
            letter-spacing: 1px;
            margin: 5px 3px;
        }
        button:hover {
            background: rgba(70, 70, 200, 0.7);
            transform: translateY(-2px);
        }
        .buttons-container {
            display: flex;
            flex-wrap: wrap;
            justify-content: space-between;
        }
    </style>
</head>
<body>
    <canvas id="glCanvas"></canvas>
    
    <div class="controls">
        <h3>Effets</h3>
        <div class="buttons-container">
            <button id="btnGravity">Gravité</button>
            <button id="btnExplosion">Explosion</button>
            <button id="btnImplosion">Implosion</button>
            <button id="btnVortex">Vortex</button>
            <button id="btnNeon">Néon</button>
            <button id="btnReset">Reset</button>
        </div>
        
        <h3>Particules</h3>
        <div class="control-group">
            <div class="control-item">
                <label for="particleSize">Taille des particules</label>
                <input type="range" id="particleSize" min="5" max="40" value="15" step="1">
            </div>
            <div class="control-item">
                <label for="particleDensity">Densité des particules</label>
                <input type="range" id="particleDensity" min="10" max="35" value="25" step="1">
            </div>
        </div>
        
        <h3>Couleurs</h3>
        <div class="control-group">
            <div class="control-item color-picker">
                <label>Couleur primaire</label>
                <input type="color" id="primaryColor" value="#3366ff">
                <span id="primaryColorValue" class="color-value">#3366ff</span>
            </div>
            <div class="control-item color-picker">
                <label>Couleur secondaire</label>
                <input type="color" id="secondaryColor" value="#ff3366">
                <span id="secondaryColorValue" class="color-value">#ff3366</span>
            </div>
            <div class="control-item color-picker">
                <label>Couleur d'accent</label>
                <input type="color" id="accentColor" value="#33ff66">
                <span id="accentColorValue" class="color-value">#33ff66</span>
            </div>
        </div>
        
        <h3>Animation</h3>
        <div class="control-group">
            <div class="control-item">
                <label for="rotationSpeed">Vitesse de rotation</label>
                <input type="range" id="rotationSpeed" min="0.1" max="3" value="1" step="0.1">
            </div>
            <div class="control-item">
                <label for="pulseSpeed">Vitesse de pulsation</label>
                <input type="range" id="pulseSpeed" min="0.5" max="5" value="1.5" step="0.1">
            </div>
            <div class="control-item">
                <label for="pulseIntensity">Intensité de pulsation</label>
                <input type="range" id="pulseIntensity" min="0.5" max="3" value="1.2" step="0.1">
            </div>
        </div>
        
        <h3>Effets visuels</h3>
        <div class="control-group">
            <div class="control-item">
                <label for="glowIntensity">Intensité de lueur</label>
                <input type="range" id="glowIntensity" min="0" max="3" value="1.2" step="0.1">
            </div>
            <div class="control-item">
                <label for="colorSaturation">Saturation des couleurs</label>
                <input type="range" id="colorSaturation" min="0.5" max="3" value="1.5" step="0.1">
            </div>
            <div class="control-item">
                <label for="colorIntensity">Intensité des couleurs</label>
                <input type="range" id="colorIntensity" min="0.5" max="3" value="1.5" step="0.1">
            </div>
        </div>
    </div>

    <script type="x-shader/x-vertex" id="vertexShader">
        attribute vec4 aVertexPosition;
        attribute vec3 aVertexColor;
        attribute float aPointOffset;
        attribute vec3 aOriginalPosition;
        attribute float aPointSize;
        
        uniform mat4 uModelViewMatrix;
        uniform mat4 uProjectionMatrix;
        uniform float uTime;
        uniform float uBasePointSize;
        uniform bool uGravityMode;
        uniform float uGravityTime;
        uniform bool uExplosionMode;
        uniform float uExplosionTime;
        uniform bool uImplosionMode;
        uniform float uImplosionTime;
        uniform bool uVortexMode;
        uniform float uVortexTime;
        uniform bool uNeonMode;
        uniform float uNeonTime;
        uniform float uRotationSpeed;
        uniform float uPulseSpeed;
        uniform float uPulseIntensity;
        uniform vec3 uPrimaryColor;
        uniform vec3 uSecondaryColor;
        uniform vec3 uAccentColor;
        uniform float uColorSaturation;
        uniform float uColorIntensity;
        
        varying highp vec3 vColor;
        varying highp float vTime;
        varying highp float vPulse;
        varying highp float vDistance;
        varying highp vec2 vUV;
        varying highp float vPointOffset;
        
        #define PI 3.14159265359
        
        vec3 generateCustomColor(vec3 pos, float t) {
            vec3 uv = pos * 0.5 + 0.5;
            vec3 col = vec3(0.0);
            
            float n = 8.0 * PI * (1.0 - cos(t * 0.3 * uPulseSpeed));
            
            for(int i = 0; i < 6; i++) {
                float fi = float(i) / 6.0;
                
                float x = sin(uv.x * 6.0 + t * 1.2 * uPulseSpeed + fi * PI * 2.0);
                float y = cos(uv.y * 6.0 + t * 0.9 * uPulseSpeed + fi * PI * 2.0);
                float z = sin(uv.z * 6.0 + t * 0.7 * uPulseSpeed + fi * PI * 2.0);
                
                float r = sin(x * cos(t/3.0) + y * 2.0) * 0.5 + 0.5;
                float g = sin(x + y * sin(t/4.0) + z * 2.0 + t) * 0.5 + 0.5;
                float b = sin(sqrt(x*x + y*y + z*z) * 2.0 + t * 1.2) * 0.5 + 0.5;
                
                vec3 baseColor = mix(
                    mix(uPrimaryColor, uSecondaryColor, r),
                    uAccentColor,
                    b * 0.5
                );
                
                col += baseColor * vec3(r, g, b) / (float(i) + 2.0);
            }
            
            if (uNeonMode) {
                col = pow(col, vec3(0.6)) * 2.0;
                
                float neonCycle = sin(uTime * 2.0 + uNeonTime * 5.0) * 0.5 + 0.5;
                vec3 neonTint = vec3(
                    sin(uNeonTime * 3.0) * 0.5 + 0.5,
                    sin(uNeonTime * 3.0 + PI * 2.0/3.0) * 0.5 + 0.5,
                    sin(uNeonTime * 3.0 + PI * 4.0/3.0) * 0.5 + 0.5
                );
                
                col = mix(col, col * neonTint, 0.6);
            } else {
                col = pow(col, vec3(1.0/uColorSaturation)) * uColorIntensity;
            }
            
            return col;
        }

        vec3 applyGravity(vec3 originalPos, float time, float offset) {
            if (!uGravityMode) return originalPos;
            
            float fallDelay = offset * 0.3;
            float effectiveTime = max(0.0, uGravityTime - fallDelay);
            
            float gravity = 12.0;
            float y = originalPos.y - 0.5 * gravity * effectiveTime * effectiveTime;
            
            float xNoise = sin(offset * 70.0) * 0.08 * effectiveTime;
            float zNoise = cos(offset * 70.0) * 0.08 * effectiveTime;
            
            if (y < -3.0) {
                float bounceFactor = 0.6;
                float bounceTime = effectiveTime - sqrt(6.0/gravity);
                if (bounceTime > 0.0) {
                    y = -3.0 + bounceFactor * (originalPos.y + 3.0 - 0.5 * gravity * bounceTime * bounceTime);
                } else {
                    y = -3.0;
                }
            }
            
            return vec3(originalPos.x + xNoise, y, originalPos.z + zNoise);
        }
        
        vec3 applyExplosion(vec3 originalPos, float time, float offset) {
            if (!uExplosionMode) return originalPos;
            
            float angle1 = offset * 10.0 * PI;
            float angle2 = offset * 20.0 * PI;
            vec3 dir = vec3(
                sin(angle1) * cos(angle2),
                sin(angle1) * sin(angle2),
                cos(angle1)
            );
            
            float explosionPower = 5.0 * (1.0 - min(1.0, uExplosionTime * 0.5));
            float delay = offset * 0.1;
            float effectiveTime = max(0.0, uExplosionTime - delay);
            
            vec3 turbulence = vec3(
                sin(effectiveTime * 5.0 + offset * 10.0),
                cos(effectiveTime * 6.0 + offset * 10.0),
                sin(effectiveTime * 7.0 + offset * 10.0)
            ) * 0.2 * effectiveTime;
            
            return originalPos + (dir * effectiveTime * explosionPower) + turbulence;
        }
        
        vec3 applyImplosion(vec3 originalPos, float time, float offset) {
            if (!uImplosionMode) return originalPos;
            
            vec3 dir = normalize(-originalPos);
            
            float implosionPower = 3.0 * min(1.0, uImplosionTime * 0.8);
            float delay = (1.0 - length(originalPos) * 0.5) * 0.2;
            float effectiveTime = max(0.0, uImplosionTime - delay);
            
            float rotationSpeed = 2.0 * effectiveTime;
            mat3 rotX = mat3(
                1.0, 0.0, 0.0,
                0.0, cos(rotationSpeed), -sin(rotationSpeed),
                0.0, sin(rotationSpeed), cos(rotationSpeed)
            );
            mat3 rotY = mat3(
                cos(rotationSpeed), 0.0, sin(rotationSpeed),
                0.0, 1.0, 0.0,
                -sin(rotationSpeed), 0.0, cos(rotationSpeed)
            );
            
            vec3 result = originalPos + (dir * effectiveTime * implosionPower);
            return rotX * rotY * result;
        }
        
        vec3 applyVortex(vec3 originalPos, float time, float offset) {
            if (!uVortexMode) return originalPos;
            
            vec3 axis = vec3(0.0, 1.0, 0.0);
            vec2 xzPos = vec2(originalPos.x, originalPos.z);
            float distToAxis = length(xzPos);
            vec2 perp = vec2(-xzPos.y, xzPos.x) / max(0.001, distToAxis);
            
            float rotSpeed = (3.0 / (0.5 + distToAxis)) * uVortexTime;
            float lift = sin(uVortexTime * 3.0 + offset * 5.0) * 0.5;
            
            float angle = rotSpeed * 2.0 * PI;
            float cos_a = cos(angle);
            float sin_a = sin(angle);
            vec2 rotated = vec2(
                xzPos.x * cos_a - xzPos.y * sin_a,
                xzPos.x * sin_a + xzPos.y * cos_a
            );
            
            return vec3(rotated.x, originalPos.y + lift * uVortexTime, rotated.y);
        }
        
        vec3 applyNeon(vec3 originalPos, float time, float offset) {
            if (!uNeonMode) return originalPos;
            
            float pulse = sin(uTime * 3.0 + offset * 10.0) * 0.05;
            
            float orbit = uNeonTime * 2.0;
            mat3 rotY = mat3(
                cos(orbit), 0.0, sin(orbit),
                0.0, 1.0, 0.0,
                -sin(orbit), 0.0, cos(orbit)
            );
            
            vec3 wave = vec3(
                sin(uTime * 2.0 + originalPos.x * 5.0) * 0.03,
                cos(uTime * 2.0 + originalPos.y * 5.0) * 0.03,
                sin(uTime * 2.0 + originalPos.z * 5.0) * 0.03
            );
            
            return rotY * (originalPos * (1.0 + pulse)) + wave;
        }
        
        void main(void) {
            vec3 position = aVertexPosition.xyz;
            
            if (uGravityMode) {
                position = applyGravity(aOriginalPosition, uTime, aPointOffset);
            } else if (uExplosionMode) {
                position = applyExplosion(aOriginalPosition, uTime, aPointOffset);
            } else if (uImplosionMode) {
                position = applyImplosion(aOriginalPosition, uTime, aPointOffset);
            } else if (uVortexMode) {
                position = applyVortex(aOriginalPosition, uTime, aPointOffset);
            } else if (uNeonMode) {
                position = applyNeon(aOriginalPosition, uTime, aPointOffset);
            }
            
            gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(p.........完整代码请登录后点击上方下载按钮下载查看

网友评论0