Реализация WebGL-анимаций и 3D-эффектов на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация WebGL-анимаций и 3D-эффектов на сайте
Сложная
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация WebGL-анимаций и 3D-эффектов на сайте

WebGL — это не «добавить красивость». Это программируемый графический конвейер прямо в браузере, с доступом к GPU. Когда нужно рендерить тысячи частиц, деформировать геометрию по аудиосигналу или строить интерактивные 3D-сцены без плагинов — это единственный инструмент, который справится без компромиссов.

Используется WebGL 2.0 (поддержка 95%+ браузеров на 2025 год), как правило через Three.js или напрямую через WebGL API для нестандартных задач.

Стек и подходы

Three.js — стандарт де-факто для большинства веб-проектов. Абстрагирует шейдеры и буферы, предоставляет сцену, камеру, освещение. Версия r169+ поддерживает WebGPU как альтернативный рендерер.

Raw WebGL применяется когда нужна полная управляемость: кастомные геометрические примитивы, нестандартные режимы бленда, минимальный bundle size без лишнего кода.

GLSL-шейдеры пишутся вручную под каждый эффект — universальных решений здесь не существует.

// Вертексный шейдер — деформация плоскости по шуму
uniform float uTime;
uniform float uAmplitude;

varying vec2 vUv;

// Simplex noise (встраивается как функция)
vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }

void main() {
  vUv = uv;

  vec3 pos = position;
  float noise = snoise(vec2(pos.x * 0.5 + uTime * 0.3, pos.y * 0.5));
  pos.z += noise * uAmplitude;

  gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
// Three.js — инициализация сцены с постпроцессингом
import * as THREE from 'three'
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'

const renderer = new THREE.WebGLRenderer({
  canvas: document.querySelector('#webgl'),
  antialias: true,
  alpha: true,
})
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.toneMapping = THREE.ACESFilmicToneMapping

const composer = new EffectComposer(renderer)
composer.addPass(new RenderPass(scene, camera))
composer.addPass(new UnrealBloomPass(
  new THREE.Vector2(window.innerWidth, window.innerHeight),
  0.8,  // strength
  0.4,  // radius
  0.85  // threshold
))

Типовые эффекты и их реализация

Шейдерный фон с шумом

Один из самых востребованных эффектов: анимированный градиентный фон, который реагирует на мышь. Реализуется через PlaneGeometry, покрывающую весь viewport, с фрагментным шейдером на базе FBM (fractional Brownian motion).

// Фрагментный шейдер — цветовой шум
uniform float uTime;
uniform vec2 uMouse;
uniform vec2 uResolution;

varying vec2 vUv;

void main() {
  vec2 uv = vUv;
  vec2 mouse = uMouse / uResolution;

  // Смещение UV по позиции мыши
  uv += (mouse - 0.5) * 0.05;

  float noise = fbm(uv * 3.0 + uTime * 0.15);

  vec3 colorA = vec3(0.1, 0.0, 0.4);
  vec3 colorB = vec3(0.0, 0.3, 0.8);
  vec3 colorC = vec3(0.8, 0.1, 0.3);

  vec3 color = mix(colorA, colorB, noise);
  color = mix(color, colorC, smoothstep(0.4, 0.7, noise));

  gl_FragColor = vec4(color, 1.0);
}

Система частиц

Для 100k+ частиц используется BufferGeometry с атрибутами в Float32Array. Анимация идёт целиком в вертексном шейдере — CPU не задействован в runtime.

const COUNT = 150000
const positions = new Float32Array(COUNT * 3)
const randoms = new Float32Array(COUNT)

for (let i = 0; i < COUNT; i++) {
  positions[i * 3 + 0] = (Math.random() - 0.5) * 10
  positions[i * 3 + 1] = (Math.random() - 0.5) * 10
  positions[i * 3 + 2] = (Math.random() - 0.5) * 10
  randoms[i] = Math.random()
}

const geometry = new THREE.BufferGeometry()
geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))
geometry.setAttribute('aRandom', new THREE.BufferAttribute(randoms, 1))

const material = new THREE.ShaderMaterial({
  uniforms: {
    uTime: { value: 0 },
    uSize: { value: 3.0 * renderer.getPixelRatio() },
  },
  vertexShader: particleVertexShader,
  fragmentShader: particleFragmentShader,
  transparent: true,
  depthWrite: false,
  blending: THREE.AdditiveBlending,
})

Image distortion при hover

Текстура изображения загружается как THREE.Texture, деформируется через displacement map по позиции курсора. Эффект «жидкого» наведения.

// Uniforms для передачи в шейдер
const uniforms = {
  uTexture: { value: texture },
  uDisplacement: { value: displacementTexture },
  uMouse: { value: new THREE.Vector2(0, 0) },
  uVelo: { value: 0 },
}

// Отслеживание скорости движения мыши
let lastMouse = new THREE.Vector2()
let currentVelo = 0

window.addEventListener('mousemove', (e) => {
  const current = new THREE.Vector2(
    e.clientX / window.innerWidth,
    1.0 - e.clientY / window.innerHeight
  )
  const delta = current.distanceTo(lastMouse)
  currentVelo = Math.min(delta * 10, 1.0)
  lastMouse.copy(current)
  uniforms.uMouse.value.copy(current)
})

Интеграция с React

Через @react-three/fiber (R3F) Three.js встраивается в React-компонент декларативно. @react-three/drei даёт готовые хелперы: useGLTF, MeshTransmissionMaterial, Float, Environment.

import { Canvas, useFrame } from '@react-three/fiber'
import { useRef } from 'react'
import * as THREE from 'three'

function AnimatedMesh() {
  const meshRef = useRef<THREE.Mesh>(null)

  useFrame(({ clock, pointer }) => {
    if (!meshRef.current) return
    meshRef.current.rotation.y = clock.getElapsedTime() * 0.3
    meshRef.current.position.x = THREE.MathUtils.lerp(
      meshRef.current.position.x,
      pointer.x * 2,
      0.05
    )
  })

  return (
    <mesh ref={meshRef}>
      <icosahedronGeometry args={[1.5, 4]} />
      <meshStandardMaterial
        color="#5500ff"
        wireframe={false}
        roughness={0.1}
        metalness={0.8}
      />
    </mesh>
  )
}

export function Scene() {
  return (
    <Canvas
      camera={{ position: [0, 0, 5], fov: 45 }}
      gl={{ antialias: true, alpha: true }}
      dpr={[1, 2]}
    >
      <ambientLight intensity={0.5} />
      <pointLight position={[10, 10, 10]} intensity={1} />
      <AnimatedMesh />
    </Canvas>
  )
}

Производительность

Framerate target — 60fps на десктопе, 30fps на мобильных с автоматическим снижением качества. Определяется через navigator.hardwareConcurrency и бенчмарк при первом рендере.

Ключевые правила:

  • Один drawcall вместо тысячи: InstancedMesh для повторяющейся геометрии
  • renderer.setPixelRatio(Math.min(devicePixelRatio, 2)) — не рендерить на 3x на Retina без нужды
  • Dispose при unmount: geometry.dispose(), material.dispose(), texture.dispose()
  • requestAnimationFrame через Three.js renderer, не свой loop
  • Постпроцессинг только при prefersReducedMotion === false
// Проверка перед инициализацией тяжёлых эффектов
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches
const isMobile = /Mobi|Android/i.test(navigator.userAgent)

const config = {
  bloomEnabled: !prefersReduced && !isMobile,
  particleCount: isMobile ? 10000 : 150000,
  pixelRatio: isMobile ? 1 : Math.min(devicePixelRatio, 2),
}

Загрузка ассетов

3D-модели — формат .glb (GLB = бинарный GLTF). Сжатие через Draco (geom) + KTX2 (текстуры). Загрузка через GLTFLoader + DRACOLoader.

import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'
import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'

const dracoLoader = new DRACOLoader()
dracoLoader.setDecoderPath('/draco/')  // wasm в public/

const ktx2Loader = new KTX2Loader()
ktx2Loader.setTranscoderPath('/basis/')
ktx2Loader.detectSupport(renderer)

const loader = new GLTFLoader()
loader.setDRACOLoader(dracoLoader)
loader.setKTX2Loader(ktx2Loader)

loader.load('/models/scene.glb', (gltf) => {
  scene.add(gltf.scene)
}, (progress) => {
  const pct = (progress.loaded / progress.total * 100).toFixed(0)
  onProgress(pct)
})

Сроки и этапы

Прототип с основным эффектом — 3–5 дней. Полная интеграция в сайт с адаптивностью, fallback для слабых устройств, оптимизацией bundle — 10–20 дней в зависимости от сложности сцены. Анимированный hero с шейдерным фоном и реакцией на мышь — ближе к нижней границе. Интерактивная 3D-модель продукта с конфигуратором материалов — к верхней.