Реалізація 3D-конфігуратора продукту на веб-сайті
3D-конфігуратор — це інтерактивна модель товару в браузері, яка оновлюється в реальному часі при зміні параметрів: покупець змінює колір дивану і одразу бачить результат, вибирає дерево для стільниці — текстура змінюється, додає ніжки іншої форми — модель перебудовується. Технічно це поєднання WebGL-рендерингу, управління 3D-сценою та бізнес-логіки конфігуратора.
Технологічний стек
Three.js — базова бібліотека WebGL для браузера. Працює скрізь, максимальна гнучкість, вимагає глибокого розуміння 3D.
React Three Fiber (R3F) — React-обгортка над Three.js. Декларативний підхід, добре інтегрується з існуючим React-додатком.
Babylon.js — альтернатива Three.js із більш багатою вбудованою функціональністю (фізика, PBR-матеріали, GUI). Документація краща, але спільнота менша.
model-viewer (Google) — веб-компонент для перегляду GLB/GLTF моделей з підтримкою AR. Підходить для простих випадків: переглянути модель, але не конфігурувати.
Для більшості конфігураторів вибір: React Three Fiber, якщо проект на React, Babylon.js, якщо потрібен візуальний редактор сцени.
Формати 3D-моделей
| Формат | Розмір | Браузер | Опис |
|---|---|---|---|
| GLTF/GLB | Компактний | Так | Веб-стандарт, підтримка PBR |
| OBJ | Великий | Так | Застарілий, немає анімації |
| FBX | Великий | Ні | Потрібна конвертація |
| USD/USDZ | Середній | Safari/AR | Apple AR Quick Look |
| Draco-стиснений GLTF | Мінімальний | Так | GLTF з Draco-стисненням геометрії |
Для веба — завжди GLTF/GLB з Draco-стисненням. Це зменшує розмір моделі в 5–10 разів без візуальних втрат.
Підготовка моделей: дизайнер експортує з Blender/3ds Max/Maya в GLTF, потім оптимізація через gltf-pipeline або gltfpack:
# Draco-стиснення + оптимізація
npx gltf-pipeline -i chair.gltf -o chair.glb --draco.compressionLevel 7
# Або через gltfpack (більш агресивне спрощення)
gltfpack -i chair.gltf -o chair.glb -cc
Архітектура конфігуратора на React Three Fiber
import { Canvas, useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import { OrbitControls, Environment } from '@react-three/drei'
import { Suspense } from 'react'
function ChairModel({ configuration }) {
const gltf = useLoader(GLTFLoader, '/models/chair-base.glb', (loader) => {
const draco = new DRACOLoader()
draco.setDecoderPath('/draco/')
loader.setDRACOLoader(draco)
})
// Застосовуємо матеріали за конфігурацією
useEffect(() => {
gltf.scene.traverse((node) => {
if (node.isMesh && node.name.startsWith('Seat')) {
node.material = getMaterialForChoice(configuration.material)
}
if (node.isMesh && node.name.startsWith('Frame')) {
node.material.color.setHex(configuration.frameColor)
}
})
}, [configuration])
return <primitive object={gltf.scene} />
}
export function ProductConfigurator({ productId }) {
const [config, setConfig] = useState({ material: 'leather', frameColor: 0x2c2c2c })
return (
<div className="grid grid-cols-2 gap-8">
<Canvas camera={{ position: [2, 1.5, 2], fov: 45 }}>
<Suspense fallback={<LoadingFallback />}>
<ChairModel configuration={config} />
<Environment preset="studio" />
<OrbitControls
enablePan={false}
minDistance={1}
maxDistance={4}
/>
</Suspense>
</Canvas>
<ConfiguratorPanel config={config} onChange={setConfig} />
</div>
)
}
Управління матеріалами та текстурами
PBR-матеріали (Physically Based Rendering) — стандарт для реалістичного рендерингу. Кожен матеріал описується набором текстур:
- baseColorTexture — колір/малюнок
- normalMap — рельєф поверхні
- roughnessMap — матовість/глянець
- metalnessMap — металічність
- aoMap — тіні в углибленнях (AO)
Для зміни матеріалу не міняємо всю модель — міняємо текстури:
async function applyMaterial(
mesh: THREE.Mesh,
materialConfig: MaterialConfig
): Promise<void> {
const loader = new THREE.TextureLoader()
const [baseColor, normal, roughness] = await Promise.all([
loader.loadAsync(`/textures/${materialConfig.id}/base.jpg`),
loader.loadAsync(`/textures/${materialConfig.id}/normal.jpg`),
loader.loadAsync(`/textures/${materialConfig.id}/roughness.jpg`),
])
;[baseColor, normal, roughness].forEach(t => {
t.wrapS = t.wrapT = THREE.RepeatWrapping
t.repeat.set(2, 2) // тайлінг текстури
})
const material = mesh.material as THREE.MeshStandardMaterial
material.map = baseColor
material.normalMap = normal
material.roughnessMap = roughness
material.needsUpdate = true
}
Текстури попередньо завантажуються при ініціалізації конфігуратора, а не при кожній зміні — це усуває затримку при перемиканні матеріалів.
Продуктивність
WebGL вимагає оптимізації, особливо на мобільних пристроях:
LOD (Level of Detail) — різні версії моделі за рівнем деталізації:
const lod = new THREE.LOD()
lod.addLevel(highDetailMesh, 0) // < 2 метрів від камери
lod.addLevel(midDetailMesh, 2) // 2–5 метрів
lod.addLevel(lowDetailMesh, 5) // > 5 метрів
Інстансинг — для повторюваних елементів (ніжки крісла × 4):
const geometry = new THREE.CylinderGeometry(0.02, 0.02, 0.45)
const material = new THREE.MeshStandardMaterial()
const instancedMesh = new THREE.InstancedMesh(geometry, material, 4)
// Розставляємо 4 ніжки через матриці трансформації
legPositions.forEach((pos, i) => {
const matrix = new THREE.Matrix4()
matrix.setPosition(pos.x, pos.y, pos.z)
instancedMesh.setMatrixAt(i, matrix)
})
Ледачне завантаження моделей: базова модель завантажується одразу, опціональні компоненти (аксесуари, насадки) — за потребою.
Фотореалістичне освітлення
Для якісного рендерингу потрібна HDR-карта оточення (HDRI):
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
const hdrLoader = new RGBELoader()
const hdrTexture = await hdrLoader.loadAsync('/env/studio.hdr')
hdrTexture.mapping = THREE.EquirectangularReflectionMapping
scene.environment = hdrTexture // освітлення від HDR
scene.background = hdrTexture // або null для прозорого фону
HDRI-карти беруться з Poly Haven (безплатно, CC0) або створюються користувацькі для бренду.
Експорт скріншота конфігурації
Покупець повинен мати можливість зберегти або поділитися конфігурацією. Скріншот із WebGL-полотна:
function captureConfiguration(): string {
const canvas = document.querySelector('canvas')
return canvas.toDataURL('image/png', 0.95)
}
async function saveToServer(dataUrl: string, config: object): Promise<string> {
const response = await fetch('/api/configurator/save', {
method: 'POST',
body: JSON.stringify({ image: dataUrl, configuration: config }),
})
const { shareUrl } = await response.json()
return shareUrl // унікальне посилання на конфігурацію
}
Збережену конфігурацію можна відновити за посиланням — це корисно для забутих кошиків і ділення в соцмережах.
Мобільні пристрої та AR
На мобільних пристроях додаткова можливість — перегляд в AR через model-viewer:
<model-viewer
src="/models/chair.glb"
ios-src="/models/chair.usdz"
ar
ar-modes="webxr scene-viewer quick-look"
camera-controls
alt="Крісло в 3D"
>
<button slot="ar-button">Переглянути в кімнаті</button>
</model-viewer>
AR працює на iOS через USDZ (Safari AR Quick Look) та на Android через Scene Viewer (ARCore).
Терміни реалізації
- Базовий 3D-перегляд моделі з OrbitControls: 2–3 дні
- Зміна матеріалів/текстур у реальному часі: 3–5 днів
- Повний конфігуратор з бізнес-логікою + розрахунком ціни: 5–8 днів
- Оптимізація продуктивності (LOD, інстансинг, текстурний атлас): 2–3 дні
- AR-перегляд на мобільних: 2–3 дні
- Збереження конфігурації + посилання на ділення: 1–2 дні
Підготовка 3D-моделей (не програмування) — окремої завдання для 3D-художника: 1–4 тижні залежно від складності товару.
Разом розробка: 3–5 тижнів.







