Babylon.js ve React ile 3D Mobilya Özelleştirici Geliştirmek
Kapsül Mobilya üzerinde çalışmaya başladığımda zorluk netti: müşterilerin ürünleri gerçek zamanlı olarak özelleştirmesine olanak tanıyan, sürükleyici bir 3D mobilya alışveriş deneyimi yaratmak. Birkaç 3D kütüphanesini değerlendirdikten sonra, sağlam özellik seti, mükemmel TypeScript desteği ve aktif topluluğu nedeniyle Babylon.js'i tercih ettim.
Neden Three.js Yerine Babylon.js?
Her ikisi de mükemmel seçimler, ancak bu e-ticaret projesi için Babylon.js birkaç avantaj sundu:
- Sahne içi arayüz öğeleri oluşturmak için yerleşik GUI sistemi
- Gerçekçi ürün etkileşimleri için daha iyi fizik motoru entegrasyonu
- Temelden gelen yerel TypeScript desteği
- Geliştirmeyi önemli ölçüde hızlandıran denetleyici ve hata ayıklama araçları
- 3D mobilya modellerini içe aktarmak için mükemmel glTF desteği
Mimariye Genel Bakış
Uygulama, sorumlulukları etkili biçimde ayıran modüler bir mimari izliyor:
typescript// Scene setup with React integration
import { Engine, Scene } from '@babylonjs/core';
import { useEffect, useRef } from 'react';
export const useBabylonScene = (canvasRef: RefObject<HTMLCanvasElement>) => {
const engineRef = useRef<Engine | null>(null);
const sceneRef = useRef<Scene | null>(null);
useEffect(() => {
if (!canvasRef.current) return;
const engine = new Engine(canvasRef.current, true, {
preserveDrawingBuffer: true,
stencil: true,
});
const scene = new Scene(engine);
// Configure scene for furniture visualization
scene.clearColor = new Color4(0.95, 0.95, 0.95, 1);
engineRef.current = engine;
sceneRef.current = scene;
engine.runRenderLoop(() => {
scene.render();
});
return () => {
engine.dispose();
};
}, [canvasRef]);
return { engine: engineRef, scene: sceneRef };
};
Gerçek Zamanlı Malzeme Özelleştirme
En çok talep edilen özelliklerden biri, mobilya malzemelerini gerçek zamanlı olarak değiştirebilme yeteneğiydi. Malzeme değiştirme sistemini şu şekilde uyguladık:
typescriptinterface MaterialConfig {
name: string;
albedoTexture: string;
normalTexture?: string;
roughness: number;
metallic: number;
}
const applyMaterial = async (
mesh: Mesh,
config: MaterialConfig,
scene: Scene
) => {
const material = new PBRMaterial(config.name, scene);
// Load textures asynchronously
material.albedoTexture = new Texture(config.albedoTexture, scene);
if (config.normalTexture) {
material.bumpTexture = new Texture(config.normalTexture, scene);
}
material.roughness = config.roughness;
material.metallic = config.metallic;
// Smooth transition
await animateMaterialTransition(mesh, material);
mesh.material = material;
};
Performans Optimizasyonları
Web'de 3D ile çalışmak performansa dikkatli özen göstermeyi gerektirir. Uyguladığımız temel optimizasyonlar şunlar:
1. Ayrıntı Düzeyi (LOD)
typescriptconst setupLOD = (mesh: Mesh, scene: Scene) => {
const lod0 = mesh; // High detail
const lod1 = createSimplifiedMesh(mesh, 0.5); // 50% detail
const lod2 = createSimplifiedMesh(mesh, 0.25); // 25% detail
lod0.addLODLevel(15, lod1);
lod0.addLODLevel(30, lod2);
};
2. Doku Sıkıştırma
Görünür kalite kaybı olmadan önemli ölçüde dosya boyutu azaltımı için Basis Universal dokularını kullandık:
typescriptconst loadCompressedTexture = async (url: string, scene: Scene) => {
const texture = new Texture(url, scene, false, true,
Texture.TRILINEAR_SAMPLINGMODE,
null, null, null, true // Enable Basis transcoding
);
return texture;
};
3. Örnek (Instance) Render Etme
Birden fazla aynı nesnenin bulunduğu sahnelerde (sandalye ayakları gibi) örnekleme (instancing) kullanıyoruz:
typescriptconst createFurnitureInstances = (
baseMesh: Mesh,
positions: Vector3[]
) => {
positions.forEach((pos, index) => {
const instance = baseMesh.createInstance(`instance_${index}`);
instance.position = pos;
});
};
React State ile Entegrasyon
Babylon.js'i React'in durum yönetimiyle birleştirmek özel bir hook sistemi gerektirdi:
typescriptexport const useFurnitureCustomizer = (scene: Scene | null) => {
const [selectedPart, setSelectedPart] = useState<string | null>(null);
const [currentMaterial, setCurrentMaterial] = useState<MaterialConfig>(
defaultMaterial
);
const handleMaterialChange = useCallback(async (config: MaterialConfig) => {
if (!scene || !selectedPart) return;
const mesh = scene.getMeshByName(selectedPart);
if (mesh) {
await applyMaterial(mesh, config, scene);
setCurrentMaterial(config);
}
}, [scene, selectedPart]);
return {
selectedPart,
setSelectedPart,
currentMaterial,
handleMaterialChange,
};
};
Çıkarılan Dersler
Kapsül Mobilya'yı geliştirmek bana birkaç değerli ders öğretti:
- Performansı baştan düşünerek başlayın - Web'de 3D, dikkatli optimizasyon yapılmazsa hızlıca yavaşlayabilir
- İyi 3D modellere yatırım yapın - Kaynak modellerinizin kalitesi nihai deneyimi doğrudan etkiler
- Gerçek cihazlarda test edin - Mobil performans cihazdan cihaza ciddi ölçüde değişir
- Aşamalı iyileştirme - 3D'yi kaldıramayan cihazlar için yedek deneyimler bulundurun
Sırada Ne Var?
Şu anda müşterilerin mobilyaları AR kullanarak kendi mekânlarında görselleştirmesine olanak tanımak için WebXR entegrasyonunu araştırıyoruz. Babylon.js'in mükemmel XR desteği ile modern akıllı telefon yeteneklerinin birleşimi, bunu giderek daha uygulanabilir hale getiriyor.
Proje kapsulmobilya.com.tr adresinde yayında - göz atıp biraz mobilya özelleştirmekten çekinmeyin!