--:--
Background Bottom
← Tüm Yazılara Dön
2026-08-177 dk okuma

Saf JavaScript ve Matematik ile 3D Render Motoru

Three.js veya WebGL gibi kütüphaneler kullanmadan, trigonometrik matris dönüşümleri ve perspektif projeksiyon formülleri ile HTML5 Canvas üzerinde 3 boyutlu döner küp motoru yapmanın adım adım rehberi.

#JavaScript#Math#3D#Canvas#Algorithms

İçindekiler

Saf JavaScript ve Matematik ile 3D Render Motoru

Günümüzde web projelerinde 3 boyutlu grafikler denildiğinde akla ilk olarak Three.js, Babylon.js veya doğrudan WebGL API gelir. Ancak bu kütüphanelerin arkasında çalışan temel mimari, aslında lise matematiğinden bildiğimiz trigonometri, vektör işlemleri ve perspektif projeksiyon formüllerine dayanır.

Bu yazıda, sıfırdan hiçbir 3D kütüphanesi veya hazır motor kullanmadan, saf JavaScript ve 2D HTML5 Canvas API ile 3 boyutlu bir nesneyi ekrana nasıl yansıttığımızı, döndürdüğümüzü ve animasyon döngüsüne bağladığımızı adım adım inceleyeceğiz.


1. 3D Uzay vs 2D Ekran Pikselleri

Bilgisayar ekranlarımız 2 boyutlu (XX ve YY pikselleri) düzlemlerdir. Bizim amacımız, 3 boyutlu sanal uzayda temsil ettiğimiz (x,y,z)(x, y, z) koordinatlarına sahip noktaları (ViV_i), ekranımızdaki piksel (xscreen,yscreen)(x_{screen}, y_{screen}) karşılıklarına dönüştürmektir.

3D uzaydaki bir noktanın bileşenleri:

  • XX Ekseni: Yatay eksen (Sağ / Sol)
  • YY Ekseni: Dikey eksen (Yukarı / Aşağı)
  • ZZ Ekseni: Derinlik ekseni (Ekrana yakınlaşma / Uzaklaşma)

2. Perspektif Projeksiyon Matematiği

Gözümüz veya fotoğraf makinesi lensleri nesnelerden uzaklaştıkça nesneleri daha küçük görür. Matematiksel olarak derinlik arttıkça (z>1z > 1) koordinat değerlerini bu zz değerine bölerek küçültürüz.

Buna Perspektif Projeksiyon (Perspective Projection) denir.

Formül:

x=xz,y=yzx' = \frac{x}{z}, \quad y' = \frac{y}{z}

JavaScript fonksiyon karşılığı:

javascript
/**
 * 3D noktayı 2D düzleme projeksiyonlar (Perspective projection).
 */
function project3DTo2D({ x, y, z }) {
    // Sıfıra bölünme hatasını (Division by zero) önlemek için z = 0 kontrolü
    const viewDistance = z === 0 ? 0.1 : z;
    return {
        x: x / viewDistance,
        y: y / viewDistance,
    };
}

3. Trigonometrik Matris Dönüşümleri (Rotation)

Nesnemizin kendi etrafında dönmesi için noktaların (x,z)(x, z) düzlemindeki açılarını trigonometrik Sinüs (sin\sin) ve Kosinüs (cos\cos) fonksiyonları ile güncelleriz.

Y ekseni etrafındaki dönme dönüşüm matrisi formülü:

[xyz]=[cos(θ)0sin(θ)010sin(θ)0cos(θ)][xyz]\begin{bmatrix} x' \\ y' \\ z' \end{bmatrix} = \begin{bmatrix} \cos(\theta) & 0 & -\sin(\theta) \\ 0 & 1 & 0 \\ \sin(\theta) & 0 & \cos(\theta) \end{bmatrix} \begin{bmatrix} x \\ y \\ z \end{bmatrix}

JavaScript kod karşılığı:

javascript
/**
 * Noktayı Y ekseni etrafında theta açısı kadar döndürür (XZ düzlemi).
 */
function rotateY({ x, y, z }, angle) {
    const cos = Math.cos(angle);
    const sin = Math.sin(angle);
    return {
        x: x * cos - z * sin,
        y: y,
        z: x * sin + z * cos,
    };
}

4. Normalize Koordinatları Piksel Düzlemine Çevirme

Projeksiyon sonucunda elde ettiğimiz (1,+1)(-1, +1) aralığındaki matematiksel koordinatları, Canvas ekranındaki piksel boyutlarına (800×800800 \times 800) ölçekleriz:

javascript
/**
 * Normalleştirilmiş koordinatları (-1 ile +1) ekran piksellerine çevirir.
 */
function convertToScreenCoords(p) {
    return {
        x: (p.x + 1) / 2 * canvas.width,
        y: (1 - (p.y + 1) / 2) * canvas.height,
    };
}

5. Tam Motor Algoritması ve Canvas Çizim Döngüsü

Şimdi tüm bu matematiksel adımları (Döndürme \rightarrow Derinlik Öteleme \rightarrow Projeksiyon \rightarrow Ekran Dönüşümü) birleştirerek 60 FPS akıcılıkta 3D döner küp oluşturan ana kod bloğuna bakalım:

javascript
const BACKGROUND_COLOR = "#101010";
const FOREGROUND_COLOR = "#7050ff";
const CANVAS_SIZE = 800;

// Canvas Kurulumu
const canvas = document.getElementById("cube");
canvas.width = CANVAS_SIZE;
canvas.height = CANVAS_SIZE;
const ctx = canvas.getContext("2d");

/**
 * Ekranı her karede temizler.
 */
function clearCanvas() {
    ctx.fillStyle = BACKGROUND_COLOR;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

/**
 * İki 2D nokta arasında çizgi çizer.
 */
function drawLine(p1, p2) {
    ctx.lineWidth = 3;
    ctx.strokeStyle = FOREGROUND_COLOR;
    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x, p2.y);
    ctx.stroke();
}

/**
 * Derinlik (Z) ötelemesi yapar.
 */
function translateZ({ x, y, z }, distance) {
    return { x, y, z: z + distance };
}

// Durum Değişkenleri
let cameraZOffset = 1;
let rotationAngle = 0;
let lastTime = 0;

/**
 * Ana Animasyon Döngüsü (RequestAnimationFrame)
 */
function animate(currentTime) {
    // Kare hızından bağımsız akıcı animasyon için Delta Time hesabı
    const deltaTime = (currentTime - lastTime) / 1000;
    lastTime = currentTime;

    if (!isNaN(deltaTime)) {
        rotationAngle += Math.PI * deltaTime; // Saniyede 180 derece dönme
    }

    clearCanvas();

    // Küpün Kenarlarını (Edges) ve Noktalarını (Vertices) İşle
    for (const edge of CUBE_EDGES) {
        for (let i = 0; i < edge.length; ++i) {
            const startVertex = CUBE_VERTICES[edge[i]];
            const endVertex = CUBE_VERTICES[edge[(i + 1) % edge.length]];

            // Matematiksel Boru Hattı (Pipeline)
            const processPoint = (v) => {
                const rotated = rotateY(v, rotationAngle);
                const translated = translateZ(rotated, cameraZOffset);
                const projected = project3DTo2D(translated);
                return convertToScreenCoords(projected);
            };

            drawLine(processPoint(startVertex), processPoint(endVertex));
        }
    }

    requestAnimationFrame(animate);
}

// Animasyonu Başlat
requestAnimationFrame(animate);

6. Projenin GitHub Reposu ve Canlı İnceleme

Bu projenin tam kaynak kodlarına, HTML5 test ortamına ve detaylı dosya yapısına GitHub üzerindeki github.com/lulushuz/MathTo3D-JS açık kaynak projemden erişebilirsiniz.

Grafik kütüphanelerinin arkasındaki matematiksel mantığı öğrenmek, performans odaklı render motorları geliştirmek ve WebGL dünyasına sağlam bir giriş yapmak için harika bir temel projedir.

Keyifli kodlamalar! 🚀

Lulushu

Made by Lulushu with❤️

© 2026 Lulushu. All Rights Reserved.