3D Product Configurator Implementation for Website

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.
Development and maintenance of all types of websites:
Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1 servicesAll 2065 services
3D Product Configurator Implementation for Website
Complex
from 2 weeks to 3 months
FAQ
Our competencies:
Development stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    847
  • image_website-sbh_0.png
    Website development for SBH Partners
    999
  • image_website-_0.png
    Website development for Red Pear
    451

Implementing a 3D Product Configurator on a Website

A 3D configurator is an interactive product model in the browser that updates in real-time when parameters change: a customer changes the sofa color and immediately sees the result, selects wood for the tabletop — the texture changes, adds legs of a different shape — the model is rebuilt. Technically, it is a combination of WebGL rendering, 3D scene management, and configurator business logic.

Technology stack

Three.js — base WebGL library for the browser. Works everywhere, maximum flexibility, requires deep understanding of 3D.

React Three Fiber (R3F) — React wrapper over Three.js. Declarative approach, integrates well with existing React applications.

Babylon.js — alternative to Three.js with richer built-in features (physics, PBR materials, GUI). Better documentation, but smaller community.

model-viewer (Google) — web component for viewing GLB/GLTF models with AR support. Suitable for simple cases: view a model, but don't configure it.

For most configurators, the choice is: React Three Fiber if the project is React-based, Babylon.js if a visual scene editor is needed.

3D model formats

Format Size Browser Description
GLTF/GLB Compact Yes Web standard, PBR support
OBJ Large Yes Outdated, no animation
FBX Large No Requires conversion
USD/USDZ Medium Safari/AR Apple AR Quick Look
Draco-compressed GLTF Minimal Yes GLTF with Draco geometry compression

For web — always GLTF/GLB with Draco compression. This reduces model size by 5–10x without visual loss.

Model preparation: designer exports from Blender/3ds Max/Maya to GLTF, then optimization via gltf-pipeline or gltfpack:

# Draco compression + optimization
npx gltf-pipeline -i chair.gltf -o chair.glb --draco.compressionLevel 7

# Or via gltfpack (more aggressive simplification)
gltfpack -i chair.gltf -o chair.glb -cc

React Three Fiber configurator architecture

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)
    })

    // Apply materials based on configuration
    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>
    )
}

Material and texture management

PBR materials (Physically Based Rendering) — standard for realistic rendering. Each material is described by a set of textures:

  • baseColorTexture — color/pattern
  • normalMap — surface relief
  • roughnessMap — matte/gloss
  • metalnessMap — metallicity
  • aoMap — shadows in crevices (AO)

To change a material, don't replace the entire model — replace the textures:

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)  // texture tiling
    })

    const material = mesh.material as THREE.MeshStandardMaterial
    material.map = baseColor
    material.normalMap = normal
    material.roughnessMap = roughness
    material.needsUpdate = true
}

Textures are preloaded at configurator initialization, not on every change — this eliminates delay when switching materials.

Performance

WebGL requires optimization, especially on mobile devices:

LOD (Level of Detail) — different model versions by detail level:

const lod = new THREE.LOD()
lod.addLevel(highDetailMesh, 0)    // < 2 meters from camera
lod.addLevel(midDetailMesh, 2)     // 2–5 meters
lod.addLevel(lowDetailMesh, 5)     // > 5 meters

Instancing — for repeating elements (chair legs × 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)

// Position 4 legs via transformation matrices
legPositions.forEach((pos, i) => {
    const matrix = new THREE.Matrix4()
    matrix.setPosition(pos.x, pos.y, pos.z)
    instancedMesh.setMatrixAt(i, matrix)
})

Lazy loading models: base model loads immediately, optional components (accessories, attachments) — on demand.

Photorealistic lighting

For quality rendering, you need an HDR environment map (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  // lighting from HDR
scene.background = hdrTexture   // or null for transparent background

HDRI maps are taken from Poly Haven (free, CC0) or custom maps are created for the brand.

Exporting a configuration screenshot

The customer should be able to save or share the configuration. Screenshot from WebGL canvas:

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  // unique link to configuration
}

A saved configuration can be restored from a link — useful for abandoned carts and social media sharing.

Mobile devices and AR

On mobile devices, an additional option — viewing in AR via model-viewer:

<model-viewer
    src="/models/chair.glb"
    ios-src="/models/chair.usdz"
    ar
    ar-modes="webxr scene-viewer quick-look"
    camera-controls
    alt="Chair in 3D"
>
    <button slot="ar-button">View in room</button>
</model-viewer>

AR works on iOS via USDZ (Safari AR Quick Look) and on Android via Scene Viewer (ARCore).

Implementation timeline

  • Basic 3D model view with OrbitControls: 2–3 days
  • Real-time material/texture switching: 3–5 days
  • Complete configurator with business logic + price calculation: 5–8 days
  • Performance optimization (LOD, instancing, texture atlas): 2–3 days
  • AR viewing on mobile: 2–3 days
  • Configuration saving + share links: 1–2 days

3D model preparation (not programming) — separate task for 3D artist: 1–4 weeks depending on product complexity.

Total development: 3–5 weeks.