React Three Fiber ile Animasyonlu 3D Model Kullanımı
ibrahim
- 18 Nis 2025

Modern web geliştirme projelerinde 3D görseller, kullanıcı deneyimini üst seviyeye taşır. Bu blogda, React Three Fiber ve React Drei kütüphanelerini kullanarak 3D animasyonlu modellerin nasıl entegre edildiğini inceleyeceğiz. GLTF formatının sunduğu performans avantajlarını kullanarak örnek kodlar ve görseller ile açıklamaya çalışacağım.
Başlarken kullanacağımız kütüphane, teknoloji ve formatları inceleyelim ve açıklayalım. Daha sonra ise örnek kodlar ile pekiştirelim.
React Three Fiber
Öncelikle neden Three.js değilde React Three Fiber kullanıyoruz? Çünkü Three.js React' ın yapısına tam olarak uymaz ve sahne yönetimleri ile de manuel uğraşmak istemeyiz. Three Fiber React ile tam uyumlu (hooks kullanmak işimizi çok kolaylaştırır), performanslı ve yardımcı kütüphaneleri ile çok kolay ve temiz kod yazmamıza olanak tanır. Tabii eğer react gibi bir çerçeve kullanmıyorsanız, çok ağır 3D sahne renderlama işlemleri yapacaksanız, veri görselleştirme veya küçük ölçekli web tabanlı oyunlar yapmayı planlıyorsanız (basit oyun motoru özelliklerini destekler) Three.js' e bir göz atmalısınız.
React Three Drei
Drei, React Three Fiber için yardımcı bir kütüphane. Bize yönetim kısmında hazır ayarlar ve kontrol araçları sağlayacak.
GLTF
GLTF (GL Transmission Format), modellerimizde bu formatı kullanacağız. Oluşturduğunuz veya herhangi bir platformdan indirdiğiniz 3D nesneleri bu formatta indirmeye özen gösterin. Tabii isterseniz GLB de kullanabilirsiniz fakat yüksek performans, hafiflik ve geniş destek istiyorsanız bu formatı kullanmamız gerek. Bu hafifliğinin üstüne birde %70 ila %90 sıkıştırmamıza olanak tanıyan komut satır aracımız var ona da değineceğiz. Bu sayede maksimum performans minimum tekrar ile çalışacağız.
GLTFJSX
Yukarıda bahsettiğim komut satırı aracımız. GLTF (GL Transmission Format) dosyalarını React Three Fiber için yeniden kullanılabilir JSX bileşenlerine dönüştüren bir komut satırı aracı. Bu araç ile hem boyutlandırmada çok büyük bir tasarruf elde edeceğiz hem modellerimizi düzenleyebilecek ve kullanışlı hale getireceğiz. Tabii modelde köklü değişiklikler yapmak isterseniz Three.js Editör de kullanabilirsiniz.
Ek olarak birkaç kütüphane ve yöntem daha kullanacağız. Kullandığımız ek kütüphane ve yöntemleri kodlarda açıklayacağım. Yukarıdaki başlıklar temel ve elzem olanlardı. Hadi şimdi örnek yapımızı kuralım ve kodları detaylıca inceleyerek açıklayalım.
1. Sahnemizi Hazırlayalım
RenderModel.jsx oluşturalım ve ortam kodlarımızı yazalım. Böylelikle 3D modelimizin yer alacağı sahneyi hazırlamış olacağız. Modelimizi children prop' u üzerinden alıp Environment ile sahnemizin aydınlatmasını gerçekleştireceğiz.
"use client";
import { Environment } from "@react-three/drei";
import { Canvas } from "@react-three/fiber";
import clsx from "clsx";
import React, { Suspense } from "react";
const RenderModel = ({ children, className }) => {
return (
<Canvas
className={clsx("w-screen h-screen -z-10 relative", className)}
shadows={false}
dpr={[1, 2]}
>
<Suspense fallback={null}>{children}</Suspense>
<Environment preset="dawn" />
</Canvas>
);
};
export default RenderModel;
use client : Server Componentler arasında istemci tarafındaki bileşenleri kullanacağımızı bildiriyoruz. Mesela @react-three-fiber kütüphanesi istemci tarafında çalıştığı için bu kütüphaneyi kullanmak istiyorsak use client gereklidir.
Canvas(@react-three-fiber) : 3D sahneyi ve grafikler için gerekli ortamı oluşturup sahnedeki içerikler için temelleri sağlar.
clsx kütüphanesi : CSS sınıflarını yönetmek için kullanıyoruz. className parametresi ile dinamik olarak sınıflar ve koşullu sınıflar ekleyebiliyoruz. Ben burada tailwind kullandım.
Environment (@react-three-drei) : Environment ile sahneye bir ortam aydınlatması ekliyoruz. Yukarıdaki örnekte preset="dawn" ayarı ile dawn yani şafak temasında bir aydınlatma ekledik. İsterseniz city veya forest gibi farklı ışıklandırmaları da deneyebilirsiniz bu size ve modelinize kalmış.
Suspense : Suspense React' ın asenkron işlemler sırasındaki bekleme durumunu belirttiğimiz bileşen. Yukarıda fallback={null}
ile model yüklenirken bir şey görünmemesini seçtik.
DPR (Device Pixel Ratio) : dpr=[1,2]
ile cihazın pixel oranına göre render kalitesini ayarlıyoruz. Değer ne kadar yüksekse o kadar iyi çözünürlük elde ederiz fakat bu değeri belirlerken performansı da göz önünde bulundurmamız lazım.
2. Modelimizi Hazırlayalım
Modelimiz için ortamımızı hazırladık, şimdi ise modelimizi hazırlayalım. Burada örnek olarak indirdiğim gltf formatında animasyonlu bir 3D modeli kullanacağım. Gltfjsx ile modelimizi react bileşenine dönüştürüp sıkıştıracağız.
Örnekte dönüştürme işlemini gerçekleştirdik ve scene-transformed modelimiz geldi, artık bu modelimizi kullanacağız. Şimdi GLTF React Three Fiber ile modelimizi görüntüleyelim ve react için oluşturduğu model kodlarımızı kopyalayalım.
Eğer sizde kendi modelinizi dönüştürdükten sonra kopyaladıysanız hadi şimdi react tarafına geçelim ve kodlarımızı inceleyelim. MeModel.jsx:
"use client";
import React, { useRef, useEffect } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";
const MeModel = React.memo(function MeModel(props) {
const group = useRef();
const { nodes, materials, animations } = useGLTF("/models/scene-transformed.glb");
const {actions} = useAnimations(animations, group);
useEffect(() =>{
actions.MOTION.play();
},[actions]);
return (
<group
ref={group}
{...props}
dispose={null}
scale={[1.5, 1.5, 1.5]}
rotation={[0, 0, 0]}
position={[0, -1.6, 0]}
>
<group name="Sketchfab_Scene">
<primitive object={nodes.GLTF_created_0_rootJoint} />
<skinnedMesh
name="Object_7"
geometry={nodes.Object_7.geometry}
material={materials.toon}
skeleton={nodes.Object_7.skeleton}
rotation={[Math.PI / 2, 0, 0]}
/>
</group>
</group>
);
});
export default MeModel;
useGLTF.preload("/models/scene-transformed.glb");
React.memo modelin gereksiz render edilmesini engeller ve performansımızı arttırır.
useRef()' i group olarak tanımladığımız modelimizin bileşenlerini kontrol etmek için kullandık.
useGLTF ile oluşturduğumuz models klasöründeki modelimizi yükledik. Burada modelimiz örnek olarak verdiğim ve gltfjsx ile dönüştürdüğüm model. Models klasörü oluşturup scene-transformed.glb modelimizi bu klasöre taşıdık. Farkettiyseniz modeli yüklerken içeriğini nodes
, materials
ve animations
olarak ayrıştırdık. Nodes modelin iskeletini, materials modelin kaplamalarını ve animations modelle birlikte gelen animasyonları içerir.
useAnimations ile modelin animasyonlarını kontrol ediyoruz.
actions.MOTION.play();
model ile gelen animasyonu başlatır. buradaki örnekte model ile birlikte gelen animasyonun ismi MOTION. Animasyonun ismini bilmiyorsanız useEffect içinde console.log(actions)
ile animasyon ismini konsolda yazdırabilirsiniz.
scale
, position
ve rotation
modelimizi konumlandırma ve ölçeklendirme araçları. Kendi modelinize göre bu ayarları yapmalısınız, deneme yanılma ile hızlı bir şekilde yapılır. dispose
ise model sahneden kaldırıldığında kaynakları temizler.
useGLTF.preload modelin önceden yüklenmesini sağlar ve performansı arttırır.
EKSTRA Eğer animasyonsuz bir modeliniz varsa ve basit animasyonlar (kendi etrafında döndürme gibi) eklemek istiyorsanız bu da çok basit bir işlem. Useframe ile bunu kolaylıkla yapabilirsiniz. Örnek olarak verdiğimiz modelde useFrame' i import edip : import { useFrame } from "@react-three/fiber";
şu şekilde kullanabilirsiniz: useFrame(() => { group.current.rotation.y += 0.002; });
. Bu modelinizin y ekseninde yani yatay eksende belirli bir hızda dönmesini sağlar. Hızını ayarlaması size kalmış :)
Artık hem sahnemiz hem modelimiz hazır durumda. Şimdi istediğimiz yerde bu modeli animasyonu ile kullanabilir, kullandığımız sayfaya göre özelleştirebiliriz.
3. Modelimizi Kullanalım
import RenderModel from "../RenderModel";
import dynamic from "next/dynamic";
const MeModel = dynamic(() => import("../models/MeModel"), {
ssr: false,
});
export default function Home() {
return (
<>
<RenderModel>
<MeModel />
</RenderModel>
</>
);
}
Oluşturduğumuz RenderModel.jsx' i ve next/dynamic' i import edelim. Next.js kullandığım için next/dynamic import ettim. dynamic
fonksiyonu ile bileşenleri dinamik olarak yükledik ve ssr:false
ile sadece istemci tarafında yüklenmesini sağladık. Eğer responsive olmasını isterseniz <RenderModel>
' i bir <div>
ile sarmalayıp tailwind kullanabilirsiniz.
En basit haliyle anlatmaya çalıştım umarım faydalı olmuştur. Daha detaylı bir anlatım veya destek için bana websitemden ulaşabilirsiniz.
Ve işte bu kadar canlı örnek için tıklayabilir aynı zamanda websitemi de ziyaret etmiş olursunuz :)