Yayasan: Mewakili Tiga Ruang

Sebelum pixel tunggal digambar, mesin 3D harus memiliki bahasa matematika untuk menggambarkan objek di ruang. Pada inti adalah vectors[ (tiga-komponen tuples mewakili posisi, arah, atau warna) dan matrices[ (4×4 array yang encode transformasi). Dalam C, ini biasanya didefinisikan sebagai struktur sederhana:

  • [[LRT:0]] untuk titik dan vektor.
  • untuk matriks transformasi disimpan dalam susunan kolom-major.

Setiap objek terdiri dari triangles. Sebuah segitiga didefinisikan oleh tiga vertik, masing-masing dengan posisi, dan secara opsional adalah normal dan warna. Mengatasi ini sebagai array coconlice (contohnya, untuk sebuah kubus) meningkatkan efisiensi cache ⁇ pertimbangan kritis ketika Anda kemudian memproses ribuan wajah per frame.

Jalur pipa Grafik: Dari Vertik hingga Piksel

Sebuah pipeline grafik adalah urutan tahap yang mengubah data adegan 3D menjadi gambar 2D. Dalam sebuah mesin dasar yang dirender perangkat lunak, Anda secara manual mengimplementasikan setiap tahap. Fasa utama adalah:

  1. [[ZOLT:0]]Vertex Processing ⁇ menerapkan model, tampilan, dan transform proyeksi.
  2. Rasterisasi ⁇ mengubah segitiga yang berubah menjadi fragmen (potensial pixel).
  3. [[GANDAFLT:0]]Shading ⁇ komputasi warna setiap fragmen berdasarkan pencahayaan dan material.
  4. [[GANDAFLT:0]]Output Menggabungkan[ ⁇ mencampur fragmen dengan buffer bingkai, termasuk pengujian kedalaman.

Mesin dipercepat perangkat keras-percepatan perangkat keras (menggunakan mesin OpenGL, Vulkan, atau DirectX) melakukan sebagian besar langkah-langkah ini pada GPU, tetapi memahami jalur perangkat lunak memberikan pemahaman mendalam tentang bagaimana GPU bekerja di bawah kap.

Pemrosesan dan Penjelmaan Verteks

Setiap verteks dari Pozéz mulai pada model ruang] (koordinat lokal relatif terhadap objek). Untuk memposisikannya di dunia, anda menerapkan sebuah model matrix yang mengenkode penerjemahan, rotasi, dan skala. Kemudian view matrix mengubah koordinat dunia menjadi koordinat kamera-relatif (lihat ruang). Akhirnya, matriks [[FLT:]] Proyeksi matrik] memetakan ruang pandang ke sistem koordinat normal ([TFLc:8]] space-relative space-space-space-space-space-fell[T:9] dimana perspektif dan pemetaan layar menghasilkan koordinat.

Dalam C, fungsi transformasi terlihat seperti:

  • ⁇ mengembalikan matriks identitas.
  • ⁇ membangun matriks terjemahan.
  • [[XALT:5]] ⁇ rotasi di sekitar paksi X.
  • [[OGAL:6]] ⁇ gandakan matriks 4×4 dengan vektor 4-elemen (koordinat kromosom).

Pelorek verteks anikel yang setara dalam software mengiterasi di atas semua vertices, mengalikan masing-masing oleh gabungan matriks, dan menyimpan hasil dalam buffer verteks tertransformasi.

Proyeksi: Perspektif versus Ortografi

Proyeksi zhoneion mengontrol bagaimana kedalaman diwakili pada layar. Perspektif proyeksi membuat objek jauh tampak lebih kecil, menciptakan realisme. Matriksnya dibangun dari bidang pandang, rasio aspek, dekat dan jauh kliping pesawat. Rumus klasik melibatkan membagi komponen x dan y oleh z (setelah perkalian matriks). Dalam C, Anda menghitung matriks proyeksi sekali dan menggunakannya kembali setiap frame:

  • ⁇ mengembalikan matriks perspektif standar.

[[GongzaFLT:0]]Projeksi Orthografi[ memelihara garis paralel dan lebih sederhana, digunakan untuk alat UI atau CAD. Ini tidak melibatkan pembagian perspektif.

Rasterisasi: Segitiga Isi

Setelah proyeksi, Anda memiliki koordinat layar 2D (seperti posisi piksel) dan nilai kedalaman (z). Rasterisasi memecah setiap segitiga menjadi fragmen yang meliputi koordinat piksel integer. Algoritme klasik adalah scanline conversion:

  1. Urutkan tiga ekor segitiga itu dengan koordinat-y.
  2. Jalan kaki di tepi kiri dan kanan, mengkomputasi batas x untuk setiap scanline.
  3. Untuk setiap piksel dalam rentang horizontal, kalkulasi kedalaman fragmen dengan melakukan interpolasi melintasi segitiga.
  4. Lakukan uji kedalaman : bandingkan z fragmen dengan nilai yang sudah ada di buffer kedalaman. Jika lebih dekat, perbarui buffer kedalaman dan hitung warna fragmen.

Implementasi algoritma berjalan-pinggir secara efisien dalam C membutuhkan loop ketat dan penggunaan aritmetika titik-tetap untuk menghindari overhead titik-apung Banyak mesin hobi dimulai dengan pendekatan gaya-basaran (memeriksa setiap piksel dalam kotak pembatasan) dan kemudian dioptimalkan dengan persamaan tepi.

Pencahayaan dan Pencahayaan

Mesin berjudi datar sederhana menggunakan warna tunggal per segitiga, dihitung dari wajah normal dan sumber cahaya tunggal.]Lambertian model memberikan intensitas difusi: . Dalam C, Anda menghitung normal sebagai hasil silang dua tepi segitiga (setelah mengubah vertik ke ruang dunia), kemudian memperbanyak intensitas cahaya oleh warna dasar segitiga.

Untuk menambah kedalaman, laksanakan Gouraud shading (vertex normals, interpolasi melintasi fragmen) atau Phong shading[ (per-piksel normals).Yang terakhir membutuhkan interpolasi posisi dunia dan normal, kemudian komputasi pencahayaan per fragmen ⁇ lebih mahal tetapi hasil yang lebih baik secara dramatis.

Bangunan Mesin dalam C: Langkah Praktis

Ayo kita berjalan melalui pembuatan mesin 3D perangkat lunak minimal dari awal. tujuannya adalah untuk membuat kiub berputar dengan cahaya ambien dan difusi ke jendela piksel 640×480.

1 ⁇ Tetapkan Penimbal Piksel

Takrifkan sebuah buffer memori untuk bingkai dan kedalaman: dan . Bersihkan buffer frame ke hitam dan buffer kedalaman ke 1.0 (pesawat jauh) setiap frame.

Langkah - 2 ⁇ Tentukan Data Adegan

Untuk sebuah kubus, enam wajah (12 segitiga) membutuhkan 12×3 = 36 vertices. Simpan mereka dalam susunan struktur dengan posisi (3 float) dan warna (3 float untuk RGB). Pre-definisikan 8 sudut kubus unik dan enam warna wajah. Gunakan sebuah buffer indeks untuk menghindari duplikasi vertik.

Langkah Ke - 3 ⁇ Transformasi Pipaline

Setiap frame, hitung matriks model dari sudut (mis., putarY(time)), matriks tampilan dari kamera tetap melihat asal, dan matriks proyeksi. Menggabungkan mereka ke dalam matriks MVP tunggal: . Jelmakan setiap verteks dengan mengalikan dengan . Kemudian lakukan pembagi perspektif (divide x,y,z by w) untuk mendapatkan koordinat perangkat normalisasi ( ⁇ 1 to +1) Peta ke koordinat layar: , (y) (diverted). Jaga zDC untuk pengujian kedalaman.

Langkah ke - 4 ⁇ Rasterize and Shade

Untuk setiap segitiga, gunakan metode scanline.Sementara berjalan pixel, interpolasi kedalaman dan juga interpolasi atribut per-vertex seperti posisi ruang dunia (untuk Phong) atau verteks normal (untuk Gouraud).Terap persamaan difusi Lambertian. Tulis warna akhir ke framebuffer jika uji kedalaman berlalu.

Step 5 ⁇ Tampilan

Nama dana untuk digunakan SDL (Sederhana DirectMedia Layer) atau pustaka serupa untuk membuat jendela dan blit buffer frame. Misalnya, dengan SDL2: , , dalam , maka dan setiap frame.

Jalur perangkat lunak ini berjalan pada CPU, sehingga kinerja dibatasi beberapa ribu segitiga per frame. Setelah nyaman, Anda dapat mengganti lapisan rasterisasi dengan OpenGL, offloading pekerjaan berat ke GPU sambil menjaga transformasi dan logika adegan Anda di C.

Mengoptimasi Mesin Anda

Beberapa optimisasi sangat penting untuk kinerja real-time:

  • [[EFAILT:0]] Kuku muka-balik: Skip segitiga yang normalnya menunjuk jauh dari kamera. Menghitung area yang ditandatangani dari segitiga yang diproyeksikan (dalam 2D) atau memeriksa produk titik wajah normal dengan arah pandang.
  • [[EANFAILT:0]]Frustum culling: Uji kotak batas suatu objek terhadap enam pesawat dari view frustum. Jika benar-benar di luar, lewati seluruh objek.
  • [ZOFLT:0]]Fixed-point aritmetika:] Gantikan operasi titik-apung dengan matematika integer dalam loop rasterisasi ketat. Banyak pembangun mesin menggunakan 16.16 titik-tetap untuk interpolasi scanline.
  • [FALT:0]]Pre-transform cache: Hindari transformasi verteks yang sama berkali-kali dengan mengubah semua vertikus dari sebuah mesh sekali, kemudian menggunakan indices.
  • [[EfleksifLT:0]]Blocked frame buffer write: Tulis piksel dalam memory-order (kiri-ke-kanan, atas-ke-bawah) untuk memaksimalkan cache hits.

Teknik-teknik ini dapat mendorong perender perangkat lunak dari 3 ⁇ fps hingga 60 fps untuk adegan kerumitan sedang (misalnya, beberapa ratus segitiga).

Mesin yang Dipakai Menerjang

Setelah fondasi padat ada, Anda dapat menambahkan fitur secara bertokokan:

  • [[GANDAFLT:0]]Petaan tekstur: Simpan 2D gambar dan interpolasi koordinat UV melintasi segitiga. Implementasi penyaringan bilinear untuk hasil lancar.
  • [[ZALAGAL:0]]Advanced shading: Tambahkan penonjolan spekular (Blinn-Phong), oklusi ambien, atau bahkan peta bayangan.
  • [[EfleksifT:0]]Pengelolaan scene: Gunakan pohon octree atau BSP untuk dengan cepat menentukan objek mana yang terlihat.
  • EUser interaksi User: Kendalikan masukan papan kekunci dan tetikus untuk mengorbit kamera atau memilih objek.
  • [[HILT:0]]Pipeline abstraksi: Design a lower system: defined vertex and fragment function pointers, enableing lentur rendering tanpa rekompilasi.

Sumber Daya dan Bacaan Lebih Lanjut

Untuk memperdalam pemahaman Anda, menjelajahi teks klasik dan tutorial online yang menginspirasi mesin ini:

  • [[CharthFLT:0]]Scratchapiksel[ ⁇ Penjelasan kedalaman-dalam tentang ray tracing, rasterisasi, dan matematika.
  • [[CANDAFLT:0]]LearnOpenGL ⁇ tutorial OpenGL modern; mulai dengan bab \"Halo Segitiga\".
  • [[ZOLT:0]]Wikipedia: Proyeksi 3D[]] ⁇ Matematika formal di balik perspektif dan matriks orthografis.

Mesin 3D di C adalah sebuah ritus dari bagian untuk programer grafis. Ini mengajarkan Anda tidak hanya bagaimana menulis kode efisien tetapi juga bagaimana berpikir dalam tiga dimensi dan menyusun sistem kritis kinerja. Mulai dengan satu putaran tunggal, kemudian menambahkan lebih banyak segitiga, tekstur, dan akhirnya menyerahkannya ke GPU. Perjalanan dari C mentah ke mesin yang berfungsi penuh mengungkapkan sihir di balik setiap piksel di layar.