Реализация 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)
})
Lazy loading моделей: базовая модель грузится сразу, опциональные компоненты (акцессуары, насадки) — по требованию.
Фотореалистичное освещение
Для качественного рендеринга нужна 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 недель.







