Розроблення 3D-переглядача товарів для інтернет-магазину
3D-переглядач товарів — інтерактивна модель, яку користувач може обертати, масштабувати та розглядати під будь-яким кутом прямо у браузері. Це принципово інший досвід порівняно з набором фотографій: користувач досліджує об'єкт самостійно, а не бачить те, що вирішив сфотографувати маркетолог. Категорії з високим ефектом: меблі, ювелірні вироби, взуття, складні технічні вироби, сувенірна продукція.
Формати 3D-моделей
| Формат | Розширення | Розмір | Підтримка браузером | Застосування |
|---|---|---|---|---|
| glTF 2.0 | .gltf + .bin + текстури | Залежить від складності | Через Three.js/Babylon | Стандарт для веб |
| GLB | .glb | Компактніший (бінарний) | Через Three.js/Babylon, <model-viewer> |
Бажаний для веб |
| USDZ | .usdz | Середній | iOS Safari нативно | AR Quick Look на iOS |
| USD / USDC | .usdc | Великий | Обмежена | Apple/Pixar нативно |
| OBJ + MTL | .obj | Великий | Через Three.js | Legacy, не рекомендується |
| FBX | .fbx | Великий | Тільки конвертація | З DCC-інструментів |
GLB — де-факто стандарт для 3D на веб. Все упаковано в один файл: геометрія, матеріали, текстури, анімації. Підтримує PBR-матеріали (metalness/roughness workflow), що дає фізично коректний рендеринг.
Three.js — базовий стек
Мінімальний 3D-віджет на Three.js:
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, container.width / container.height, 0.1, 100);
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputColorSpace = THREE.SRGBColorSpace;
// OrbitControls — обертання, зум, зміщення мишею/дотиком
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.minDistance = 1;
controls.maxDistance = 10;
// DRACO-декомпресія для стиснених моделей
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('/draco/');
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('/models/product.glb', gltf => {
scene.add(gltf.scene);
fitCameraToObject(camera, controls, gltf.scene);
});
// HDR-окруження для PBR-освітлення
new RGBELoader().load('/env/studio.hdr', texture => {
texture.mapping = THREE.EquirectangularReflectionMapping;
scene.environment = texture;
});
Draco-компресія
DRACO — алгоритм стиснення 3D-геометрії від Google. Типове стиснення: геометрія зменшується в 5–10 разів без помітної втрати якості. Модель крісла 8MB → 800KB після Draco.
Конвертація в pipeline (offline, при завантаженні моделі адміністратором):
# gltf-pipeline від Khronos
npx gltf-pipeline -i input.glb -o output.glb --draco.compressionLevel 7
# або через blender CLI
blender --background --python export_with_draco.py
Draco-декодер у браузері — WASM-модуль (~200KB). Потрібно розмістити на сервері та вказати шлях у DRACOLoader.setDecoderPath().
<model-viewer> як готовий компонент
Якщо не потрібна глибока кастомізація, <model-viewer> від Google покриває 90% задач:
<model-viewer
src="/models/chair.glb"
ios-src="/models/chair.usdz"
alt="Офісне крісло Herman Miller"
camera-controls
auto-rotate
auto-rotate-delay="3000"
rotation-per-second="30deg"
shadow-intensity="1"
exposure="0.8"
environment-image="/env/neutral.hdr"
ar
ar-modes="webxr scene-viewer quick-look"
loading="lazy"
style="width: 100%; aspect-ratio: 1; background: #f5f5f5;"
>
<div slot="progress-bar">
<div class="progress-bar" style="..."></div>
</div>
<button slot="ar-button" class="ar-button">
Переглянути у вашому інтер'єрі
</button>
</model-viewer>
Вбудовано: OrbitControls, підтримка дотиків, AR (WebXR + Quick Look), тінь, ледаче завантаження, індикатор прогресу.
Освітлення та PBR-матеріали
Якість рендеринга у браузері визначається освітленням. Без правильного окруження навіть гарна модель виглядає плоскою.
HDR environment map — сферична HDR-панорама студійного або нейтрального освітлення. Створює коректні відображення на металевих та глянцевих поверхнях. Розмір: 2MB–8MB, завантажується один раз та кешується.
Для товарів: нейтральне студійне HDRI (сірий фон, рівномірне світло) — neutral.hdr з репозиторію model-viewer. Для ювелірних виробів — HDRI з вираженими бліками.
Анімовані матеріали: зміна варіанту (колір, матеріал) — змінюємо material.color, material.roughness, material.metalnessMap. Без перезавантаження моделі:
const materials = model.querySelector('model-viewer').model.materials;
const chairMaterial = materials.find(m => m.name === 'Fabric');
chairMaterial.pbrMetallicRoughness.setBaseColorFactor([0.8, 0.2, 0.2, 1]); // червоний
Оптимізація продуктивності
Розмір моделі: цільовий розмір GLB для карточки товару — до 2MB. Більше — користувач чекає, конверсія падає. Методи оптимізації:
- Draco-компресія геометрії (5–10x)
- KTX2 / Basis Universal компресія текстур (3–5x, з GPU-декодуванням)
- Retopology моделі: видалити приховані грані, спростити невидимі частини
- Запечення (bake) деталей з high-poly у normal map low-poly моделі
Ледаче завантаження: Three.js/WebGL ініціалізується тільки при потраплянні віджету у viewport:
const observer = new IntersectionObserver(entries => {
if (entries[0].isIntersecting) {
initViewer(container); // створюємо Scene, Renderer тільки зараз
observer.disconnect();
}
}, { threshold: 0.1 });
observer.observe(container);
Призупинена ренерація: коли віджет поза видимістю — renderer.setAnimationLoop(null), відновлюємо при поверненні.
Pixel ratio: на мобайлі обмежуємо devicePixelRatio до 1.5 максимум — економимо GPU на retina-дисплеях.
Анотації та hotspots
Анотації — точки на 3D-моделі з поясненнями. Користувач наводить / кликає — з'являється tooltip з інформацією про деталь.
У <model-viewer> анотації — через слоти:
<model-viewer src="headphones.glb" camera-controls>
<button
slot="hotspot-ear-cup"
data-position="-0.3 0.1 0.2"
data-normal="-1 0 0"
data-visibility-attribute="visible"
>
<div class="hotspot-label">
<strong>Амбушюри</strong>
Пам'ять-піна з ефектом пам'яті, 40мм
</div>
</button>
</model-viewer>
Координати data-position — світові координати в системі координат моделі. Визначаються в Blender або через вбудований picking у Three.js.
Конвейер підготовки контенту
Розроблення віджету та підготовка моделей — паралельні задачі. Типовий pipeline:
- 3D-моделювання (Blender, Cinema 4D) або фотограмметрія (RealityCapture, Meshroom)
- Оптимізація (Blender: retopology, LOD), Draco-компресія
- PBR-текстурування (Substance Painter) + конвертація текстур у KTX2
- QA у браузері: перевірка у model-viewer, тест на мобайлі
- Конвертація у USDZ для iOS AR (Reality Converter, online-конвертери)
-
Завантаження на CDN з правильними заголовками (
Content-Type: model/gltf-binary)
Терміни
-
<model-viewer>інтеграція (готовий компонент, GLB-файли від клієнта): 3–5 робочих днів - Кастомний Three.js-віджет (анотації, зміна матеріалів, кастомне освітлення): 2–4 тижні
- Повна платформа (завантаження моделей у CMS, pipeline оптимізації, AR, анотації): 4–7 тижнів
- Підготовка 3D-моделей (якщо нема): окремаа задача — від 4 годин до 2 днів на один артикул
При великому каталозі фотограмметрія (створення 3D з серії фото) зменшує вартість контент-продакшну в 5–10 разів порівняно з ручним моделюванням.







