Setting Up 3D Product Viewing in 1C-Bitrix
360-photo is sequential images. 3D-viewing is a 3D model rotatable at any angle, zoomable, detailed. For furniture, jewelry, or tech online stores, the difference is significant.
Web-Compatible 3D Model Formats
Web-compatible 3D formats: glTF/glb — Khronos Group standard, most browser-supported; USDZ — Apple format for AR on iOS; OBJ — old text format, large size; FBX — for editor transfer, not web directly.
For websites use glb (binary glTF) — combines geometry, materials, textures in one file. Typical glb-model size for simple product — 500 KB – 5 MB.
Storing 3D Models in Catalog
Model stored as file linked to product via iblock property type F. Create property with code MODEL_3D:
\CIBlockProperty::Add([
'NAME' => '3D Model',
'CODE' => 'MODEL_3D',
'IBLOCK_ID' => $iblockId,
'PROPERTY_TYPE' => 'F',
'FILE_TYPE' => 'glb,gltf,usdz',
'SORT' => 500,
]);
Getting model file:
$props = $element->GetProperties();
$fileId = $props['MODEL_3D']['VALUE'];
$modelUrl = \CFile::GetPath($fileId);
Three.js Integration
For glTF rendering in browser use Three.js with GLTFLoader. Connect via CDN or bundle:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/controls/OrbitControls.js"></script>
Minimal viewer:
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xf5f5f5);
const camera = new THREE.PerspectiveCamera(45, container.offsetWidth / container.offsetHeight, 0.1, 100);
camera.position.set(0, 1, 3);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(container.offsetWidth, container.offsetHeight);
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild(renderer.domElement);
// Lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(5, 10, 5);
scene.add(dirLight);
// Orbit control
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
// Load model
const loader = new THREE.GLTFLoader();
loader.load('<?= $modelUrl ?>', function (gltf) {
scene.add(gltf.scene);
// Center model
const box = new THREE.Box3().setFromObject(gltf.scene);
const center = box.getCenter(new THREE.Vector3());
gltf.scene.position.sub(center);
});
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
animate();
Model-Viewer as Alternative
Google <model-viewer> — ready web-component supporting glTF and AR on mobile:
<script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/3.3.0/model-viewer.min.js"></script>
<model-viewer
src="<?= $modelUrl ?>"
alt="3D Product Model"
auto-rotate
camera-controls
ar
ar-modes="webxr scene-viewer quick-look"
style="width: 100%; height: 400px;">
</model-viewer>
ar attribute enables "View in AR" button — on iOS opens USDZ via Quick Look, on Android via Scene Viewer.
Model Optimization
Unprocessed glb from designers can be 50-200 MB. For web need optimization via gltf-transform (Node.js CLI):
npx @gltf-transform/cli optimize model.glb model-web.glb \
--compress draco \
--texture-compress webp \
--texture-size 1024
Draco geometry compression reduces size 5-10x. 1024×1024 WebP textures sufficient for 3D-viewer on site. After optimization typical model fits in 300-800 KB.
Integration in Product Card Template
In bitrix:catalog.element component template add container and conditional logic: if product has MODEL_3D property — show 3D-viewer instead of or alongside main photo:
if (!empty($arResult['PROPERTIES']['MODEL_3D']['VALUE'])) {
$modelUrl = \CFile::GetPath($arResult['PROPERTIES']['MODEL_3D']['VALUE']);
// Render viewer
}







