VibeCoderzVibeCoderz
Telegram
All Prompts
Three.js Silk Shader Background Canvas preview
backgroundshaderthree.jscanvasanimationwebglresponsive

Three.js Silk Shader Background Canvas

Анимированный фон-шейдер в стиле шелка на Three.js. Адаптивный WebGL-холст для hero-секций, заголовков, UI-бэкграундов.

Prompt


<div id="shader-canvas" class="absolute inset-0 -z-10">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
  <script>
    class SilkShader {
        constructor(container) {
            this.container = container;
            this.scene = new THREE.Scene();
            this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
            this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
            this.clock = new THREE.Clock();
            
            this.init();
            this.createShaderMaterial();
            this.createMesh();
            this.animate();
            this.handleResize();
            
            window.addEventListener('resize', () => this.handleResize());
        }
        
        init() {
            this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);
            this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
            this.container.appendChild(this.renderer.domElement);
        }
        
        hexToNormalizedRGB(hex) {
            hex = hex.replace("#", "");
            return new THREE.Vector3(
                parseInt(hex.slice(0, 2), 16) / 255,
                parseInt(hex.slice(2, 4), 16) / 255,
                parseInt(hex.slice(4, 6), 16) / 255
            );
        }
        
        createShaderMaterial() {
            const vertexShader = `
                varying vec2 vUv;
                varying vec3 vPosition;
                
                void main() {
                    vPosition = position;
                    vUv = uv;
                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                }
            `;
            
            const fragmentShader = `
                varying vec2 vUv;
                varying vec3 vPosition;
                
                uniform float uTime;
                uniform vec3 uColor;
                uniform float uSpeed;
                uniform float uScale;
                uniform float uRotation;
                uniform float uNoiseIntensity;
                
                const float e = 2.71828182845904523536;
                
                float noise(vec2 texCoord) {
                    float G = e;
                    vec2 r = (G * sin(G * texCoord));
                    return fract(r.x * r.y * (1.0 + texCoord.x));
                }
                
                vec2 rotateUvs(vec2 uv, float angle) {
                    float c = cos(angle);
                    float s = sin(angle);
                    mat2 rot = mat2(c, -s, s, c);
                    return rot * uv;
                }
                
                void main() {
                    float rnd = noise(gl_FragCoord.xy);
                    vec2 uv = rotateUvs(vUv * uScale, uRotation);
                    vec2 tex = uv * uScale;
                    float tOffset = uSpeed * uTime;
                    
                    tex.y += 0.03 * sin(8.0 * tex.x - tOffset);
                    
                    float pattern = 0.6 +
                                  0.4 * sin(5.0 * (tex.x + tex.y +
                                                  cos(3.0 * tex.x + 5.0 * tex.y) +
                                                  0.02 * tOffset) +
                                          sin(20.0 * (tex.x + tex.y - 0.1 * tOffset)));
                    
                    vec4 col = vec4(uColor, 1.0) * vec4(pattern) - rnd / 15.0 * uNoiseIntensity;
                    col.a = 0.8;
                    gl_FragColor = col;
                }
            `;
            
            this.uniforms = {
                uTime: { value: 0 },
                uSpeed: { value: 2 },
                uScale: { value: 1.5 },
                uNoiseIntensity: { value: 1.2 },
                uColor: { value: this.hexToNormalizedRGB("#6366F1") },
                uRotation: { value: 0.5 }
            };
            
            this.material = new THREE.ShaderMaterial({
                uniforms: this.uniforms,
                vertexShader,
                fragmentShader,
                transparent: true
            });
        }
        
        createMesh() {
            const geometry = new THREE.PlaneGeometry(2, 2);
            this.mesh = new THREE.Mesh(geometry, this.material);
            this.scene.add(this.mesh);
        }
        
        handleResize() {
            this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight);
        }
        
        animate() {
            requestAnimationFrame(() => this.animate());
            
            const delta = this.clock.getDelta();
            this.uniforms.uTime.value += 0.1 * delta;
            
            this.renderer.render(this.scene, this.camera);
        }
    }
    
    // Initialize the shader when the page loads
    document.addEventListener('DOMContentLoaded', () => {
        const container = document.getElementById('shader-canvas');
        new SilkShader(container);
    });
</script>
</div>
All Prompts