Blog'a Dön
Babylon.jsReact3DTypeScriptE-Commerce

Babylon.js ve React ile 3D Mobilya Özelleştirici Geliştirmek

Umut Korkmaz2025-04-0512 min read

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:

typescript
interface 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)

typescript
const 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:

typescript
const 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:

typescript
const 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:

typescript
export 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:

  1. Performansı baştan düşünerek başlayın - Web'de 3D, dikkatli optimizasyon yapılmazsa hızlıca yavaşlayabilir
  2. İyi 3D modellere yatırım yapın - Kaynak modellerinizin kalitesi nihai deneyimi doğrudan etkiler
  3. Gerçek cihazlarda test edin - Mobil performans cihazdan cihaza ciddi ölçüde değişir
  4. 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!