Интеграция 3D-просмотрщика на сайте: Three.js, Babylon.js, GLTF

Типичная ситуация: клиент предоставил GLB-модель дивана весом 50 МБ, а сайт на старом хостинге не тянет загрузку — посетители уходят через 5 секунд ожидания. Решение — встроить 3D-просмотрщик на Three.js или Babylon.js с оптимизацией: Draco-компрессия, LOD, правильное освещение. Мы реализовали такие

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

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

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

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Интеграция 3D-просмотрщика на сайте: Three.js, Babylon.js, GLTF
Сложный
~1-2 недели

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

Часто задаваемые вопросы

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

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

Типичная ситуация: клиент предоставил GLB-модель дивана весом 50 МБ, а сайт на старом хостинге не тянет загрузку — посетители уходят через 5 секунд ожидания. Решение — встроить 3D-просмотрщик на Three.js или Babylon.js с оптимизацией: Draco-компрессия, LOD, правильное освещение. Мы реализовали такие проекты для десятков клиентов: от интерьерных конфигураторов до витрин ювелирных украшений. Наш опыт — более 5 лет веб-разработки и свыше 30 успешных интеграций 3D-просмотрщиков, что позволило клиентам сократить время загрузки до 2 секунд и увеличить конверсию на 15-20%. При этом Three.js загружается в 3 раза быстрее Babylon.js для простых сцен, но уступает в физике и XR. Экономия на хостинге при Draco-сжатии может достигать $500 в месяц для крупных проектов.

Проблемы, которые решаем

Типичные технические сложности при внедрении 3D-просмотрщиков:

  • Большие файлы моделей: GLTF-модели мебели или автомобилей могут весить десятки мегабайт. Без Draco-компрессии и LOD пользователи ждут загрузку по 30 секунд, что критично для конверсии.
  • Кросс-браузерность: WebGL стабилен в Chrome, Firefox, Edge, но на старых версиях Safari возможны артефакты. Нужна корректная проверка WebGLRenderingContext и fallback-сообщение.
  • Производительность на мобильных: рендеринг сцены с высоким Pixel Ratio быстро сажает батарею. Ограничение devicePixelRatio до 2× и отключение теней на слабых GPU — обязательные меры.

Three.js vs Babylon.js: как выбрать?

Three.js — минималистичная библиотека рендеринга (~600 КБ), огромное сообщество, тысячи примеров. Требует больше ручной работы для сложных сцен (физика, collision detection).

Babylon.js — полноценный игровой движок в браузере (~2 МБ). Встроенная физика, PBR-материалы, Inspector, GUI, XR-поддержка. Хорош для сложных интерактивных сцен.

Для просмотра 3D-моделей — Three.js. Для интерактивных конфигураторов и сцен — Babylon.js. В 80% наших проектов используем Three.js из-за простоты интеграции и меньшего размера.

Критерий Three.js Babylon.js
Размер библиотеки ~600 КБ ~2 МБ
Физика Нет встроенной Встроенный Cannon.js
PBR-материалы Требует настройки Готовые решения
XR-поддержка Через WebXR Встроенный Inspector

Three.js: просмотрщик GLTF-модели

npm install three @types/three 
import * as THREE from 'three' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader' import { useEffect, useRef } from 'react' interface ModelViewerProps { modelUrl: string envMapUrl?: string } export function ModelViewer({ modelUrl, envMapUrl }: ModelViewerProps) { const mountRef = useRef<HTMLDivElement>(null) useEffect(() => { const container = mountRef.current! const width = container.clientWidth const height = container.clientHeight // Сцена const scene = new THREE.Scene() scene.background = new THREE.Color(0xf8fafc) // Камера const camera = new THREE.PerspectiveCamera(50, width / height, 0.01, 1000) camera.position.set(2, 1.5, 3) // Рендерер const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, }) renderer.setSize(width, height) renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)) renderer.toneMapping = THREE.ACESFilmicToneMapping renderer.toneMappingExposure = 1.2 renderer.outputColorSpace = THREE.SRGBColorSpace container.appendChild(renderer.domElement) // Освещение const ambientLight = new THREE.AmbientLight(0xffffff, 0.5) scene.add(ambientLight) const dirLight = new THREE.DirectionalLight(0xffffff, 2) dirLight.position.set(5, 10, 5) dirLight.castShadow = true dirLight.shadow.mapSize.set(2048, 2048) scene.add(dirLight) const fillLight = new THREE.DirectionalLight(0x8bb8e8, 0.5) fillLight.position.set(-5, 2, -5) scene.add(fillLight) // Orbit Controls const controls = new OrbitControls(camera, renderer.domElement) controls.enableDamping = true controls.dampingFactor = 0.08 controls.minDistance = 0.5 controls.maxDistance = 20 controls.autoRotate = true controls.autoRotateSpeed = 1.5 // GLTF загрузчик с Draco сжатием const dracoLoader = new DRACOLoader() dracoLoader.setDecoderPath('/draco/') // Копируем в public/draco/ const loader = new GLTFLoader() loader.setDRACOLoader(dracoLoader) let mixer: THREE.AnimationMixer | null = null loader.load( modelUrl, (gltf) => { const model = gltf.scene // Центрируем модель const box = new THREE.Box3().setFromObject(model) const center = box.getCenter(new THREE.Vector3()) const size = box.getSize(new THREE.Vector3()) const maxDim = Math.max(size.x, size.y, size.z) model.position.sub(center) camera.position.multiplyScalar(maxDim * 0.8) controls.update() scene.add(model) // Анимации if (gltf.animations.length > 0) { mixer = new THREE.AnimationMixer(model) gltf.animations.forEach((clip) => { mixer!.clipAction(clip).play() }) } }, (xhr) => { const progress = Math.round((xhr.loaded / xhr.total) * 100) console.log(`Loading: ${progress}%`) }, (error) => console.error('Error loading model:', error) ) // Анимационный цикл const clock = new THREE.Clock() let animFrameId: number function animate() { animFrameId = requestAnimationFrame(animate) const delta = clock.getDelta() mixer?.update(delta) controls.update() renderer.render(scene, camera) } animate() // Resize function handleResize() { const w = container.clientWidth const h = container.clientHeight camera.aspect = w / h camera.updateProjectionMatrix() renderer.setSize(w, h) } window.addEventListener('resize', handleResize) return () => { window.removeEventListener('resize', handleResize) cancelAnimationFrame(animFrameId) controls.dispose() renderer.dispose() container.removeChild(renderer.domElement) } }, [modelUrl]) return ( <div ref={mountRef} style={{ width: '100%', height: '500px' }} className="rounded-xl overflow-hidden cursor-grab active:cursor-grabbing" /> ) } 

Конфигуратор цвета материала

function changeModelColor(scene: THREE.Scene, meshName: string, color: string) { scene.traverse((object) => { if (object instanceof THREE.Mesh && object.name === meshName) { const material = object.material as THREE.MeshStandardMaterial material.color.set(color) } }) } // Использование в UI <div className="flex gap-2"> {['#ef4444', '#3b82f6', '#22c55e', '#f59e0b', '#8b5cf6'].map((color) => ( <button key={color} onClick={() => changeModelColor(sceneRef.current!, 'Body', color)} style={{ background: color }} className="w-8 h-8 rounded-full border-2 border-white shadow" /> ))} </div> 

Babylon.js: альтернатива для сложных сцен

npm install @babylonjs/core @babylonjs/loaders 
import { Engine, Scene, ArcRotateCamera, HemisphericLight, Vector3 } from '@babylonjs/core' import { SceneLoader } from '@babylonjs/core/Loading/sceneLoader' import '@babylonjs/loaders/glTF' function BabylonViewer({ modelUrl }: { modelUrl: string }) { const canvasRef = useRef<HTMLCanvasElement>(null) useEffect(() => { const engine = new Engine(canvasRef.current!, true, { preserveDrawingBuffer: true, stencil: true, }) const scene = new Scene(engine) const camera = new ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 4, 5, Vector3.Zero(), scene) camera.attachControl(canvasRef.current!, true) camera.lowerRadiusLimit = 1 camera.upperRadiusLimit = 20 new HemisphericLight('light', new Vector3(0, 1, 0), scene) SceneLoader.ImportMeshAsync('', '', modelUrl, scene).then(({ meshes }) => { // Автоцентрирование camera.setTarget(meshes[0]) }) engine.runRenderLoop(() => scene.render()) const handleResize = () => engine.resize() window.addEventListener('resize', handleResize) return () => { window.removeEventListener('resize', handleResize) engine.dispose() } }, [modelUrl]) return <canvas ref={canvasRef} style={{ width: '100%', height: '500px' }} /> } 

Почему важна оптимизация производительности?

Пользователи не готовы ждать загрузку дольше 3 секунд. Вот ключевые методы:

  • Draco-компрессия GLTF снижает размер геометрии на 60–90%. Это уменьшает время загрузки в 3-5 раз по сравнению с несжатым файлом.
  • renderer.setPixelRatio(Math.min(devicePixelRatio, 2)) — не рендерим выше 2x, что экономит энергопотребление.
  • LOD (Level of Detail) — более детальная модель вблизи, упрощённая вдали. На мобильных LOD даёт прирост FPS до 50%.
  • Instanced Mesh для множества одинаковых объектов (деревья, кресла).
  • Отключаем autoRotate во время взаимодействия пользователя.
Метод Эффект Сложность реализации
Draco-компрессия Снижение размера на 60–90% Средняя (нужен декодер)
LOD Ускорение рендеринга до 50% Высокая (создание уровней)
Ограничение Pixel Ratio Снижение нагрузки на GPU Низкая (одна строка)

Что такое Draco-компрессия?

Draco — библиотека от Google для сжатия 3D-геометрии. Она кодирует позиции вершин, нормали, текстурные координаты в компактный формат. На клиенте декодер восстанавливает оригинальные данные. Для GLTF достаточно подключить DRACOLoader и указать путь к декодеру. Сжатие без потерь, но для анимаций не применяется.

Что входит в работу?

  1. Анализ модели — проверка геометрии, текстур, анимаций. Конвертация в GLTF с Draco.
  2. Настройка сцены — освещение (окружение, направленный свет), тени, камера.
  3. Интеграция — React-компонент с загрузчиком, контролами, адаптивностью.
  4. Конфигуратор (опционально) — выбор цвета/материала, переключение моделей.
  5. Оптимизация — тесты на мобильных устройствах, настройка LOD.
  6. Документация — описание API компонента, инструкция по замене модели.

Сроки ориентировочно

  • Простой просмотрщик с загрузкой GLTF и orbit controls — 2–3 дня.
  • Конфигуратор с выбором цвета/материала и несколькими моделями — 5–7 дней.

Стоимость рассчитывается индивидуально в зависимости от сложности сцены и количества интерактивных элементов. Стоимость базового просмотрщика начинается от $1000, сложные конфигураторы — от $3000. Экономия на трафике может составлять до 30%. При больших объёмах возможна экономия бюджета — обсудим на консультации.

Как мы гарантируем качество?

Мы тестируем просмотрщик на трёх последних версиях Chrome, Firefox, Safari и Edge. Для мобильных устройств проверяем iPhone (Safari) и Android (Chrome). Предоставляем гарантию на работоспособность в течение 30 дней после сдачи. Наш опыт — более 5 лет в WebGL-разработке, более 30 успешных проектов.

Свяжитесь с нами для оценки вашего проекта. Закажите консультацию — обсудим требования и подготовим коммерческое предложение под ключ.