
Assembler adalah bahasa favorit saya ... tetapi hidup ini sangat singkat.
Saya melanjutkan siklus penelitian saya pada bayangan yang cocok untuk beberapa bagel. Setelah publikasi,
saya mendinginkan
sekali dan
dua kali untuk topik ini, tetapi efek dari tindakan tidak lengkap mendorong saya untuk kembali ke puing-puing piksel, dan menyelesaikan
gestalt .
Mengenali diri saya, saya yakin bahwa gim ini tidak akan mendapatkan perwujudannya, tetapi mungkin beberapa publik akan tertarik pada pencapaian saya di jalur yang sulit ini. Jadi mari kita mulai.
Pada akhir siklus terakhir, saya sampai pada pemahaman bahwa menghitung grafik pada CPU sudah merupakan abad terakhir, tetapi kegigihan alami bersikeras: tidak semua kemungkinan digunakan, masih ada pilihan untuk solusi menarik.
Pelacakan ray tetap tidak diterapkan. Lebih tepatnya, jenisnya, di mana untuk setiap piksel gambar (blok piksel) sebuah sinar tersebar dan tingkat iluminasi dari titik saat ini ditentukan. Algoritme itu sendiri dijelaskan dalam artikel sebelumnya dan tidak ada gunanya mengembalikannya. Untuk penelusuran sinar balik, kode ini bahkan lebih disederhanakan, semua trigonometri sepenuhnya dihapus, yang di masa depan bisa memberikan hasil yang dapat diterima.
Sayangnya, hasilnya jauh lebih buruk dari yang diharapkan, layak menyebarkan gambar ke layar penuh, FPS mencari unit.

Pengelompokan piksel ke blok makro untuk mengurangi perhitungan dan menerapkan penghalusan berikutnya tidak banyak meningkatkan kinerja. Efeknya terus terang tidak menyukai kata itu sama sekali.

Algoritma itu paralel sempurna, tetapi tidak masuk akal untuk menggunakan banyak aliran, efeknya tampak jauh lebih buruk daripada di artikel sebelumnya, bahkan dengan kualitas gambar yang lebih baik.
Ternyata jalan buntu. Harus saya akui, CPU dalam perhitungan grafik di mata saya telah habis sendiri. Tirai.
Digresi 1Selama dekade terakhir, hampir tidak ada kemajuan dalam pengembangan prosesor tujuan umum. Jika didekati oleh pengguna, maka peningkatan kinerja maksimum yang terlihat tidak lebih dari 30% per inti. Kemajuan, secara halus, tidak signifikan. Jika kita menghilangkan ekstensi panjang instruksi vektor, dan beberapa percepatan blok konveyor, ini merupakan peningkatan jumlah core yang bekerja. Pekerjaan aman dengan utas masih menyenangkan, dan tidak semua tugas dapat diparalelkan dengan sukses. Saya ingin memiliki inti yang berfungsi, meskipun satu, tetapi jika demikian, itu 5-10 lebih cepat, tetapi sayangnya dan oh, seperti kata mereka.
Di sini, di Habré ada serangkaian artikel yang sangat baik
"Kehidupan di era silikon" gelap ", yang menjelaskan beberapa prasyarat untuk keadaan saat ini, tetapi juga kembali dari surga ke bumi. Dalam dekade berikutnya, Anda tidak dapat mengharapkan peningkatan yang signifikan dalam komputasi per inti. Tetapi kita bisa mengharapkan pengembangan lebih lanjut dari jumlah core GPU dan akselerasi keseluruhannya. Bahkan di laptop lama saya, perkiraan total kinerja GPU adalah 20 kali lebih tinggi dari satu thread CPU. Bahkan jika Anda secara efektif memuat semua 4 inti prosesor, itu jauh lebih sedikit daripada yang kita inginkan.
Saya memberi penghormatan kepada para pengembang grafis masa lalu, yang membuat karya agung mereka tanpa akselerator perangkat keras, master sejati.
Jadi, kami berurusan dengan GPU. Ternyata agak tak terduga bagi saya bahwa dalam praktik nyata, hanya sedikit orang yang menyebarkan poligon. Semua hal menarik dibuat menggunakan
shader . Setelah membuang mesin 3D yang sudah jadi, saya mencoba mempelajari jeroan teknologi karena berada pada level yang dalam. Prosesor yang sama adalah assembler yang sama, hanya beberapa set instruksi terpotong dan spesifik pekerjaan mereka sendiri. Untuk tes, saya berhenti di
GLSL , sebuah sintaksis seperti C, kesederhanaan, banyak pelajaran dan contoh pelatihan, termasuk Habr.
Karena saya kebanyakan terbiasa menulis dalam
Pascal , tugasnya adalah bagaimana menghubungkan OpenGL
ke proyek. Saya berhasil menemukan dua cara untuk terhubung: perpustakaan
GLFW dan file header
dglOpenGL . Satu-satunya hal yang pertama kali saya tidak dapat menghubungkan shader, tetapi tampaknya ini adalah dari kelengkungan tangan saya.
Digresi 2Banyak teman bertanya kepada saya mengapa saya menulis dalam Pascal? Jelas, ini adalah bahasa yang terancam punah, komunitasnya terus berjatuhan, hampir tidak ada perkembangan. Insinyur sistem tingkat rendah lebih suka C, dan Java, Python, Ruby, atau apa pun yang ada di puncaknya sekarang.
Bagi saya, Pascal mirip dengan cinta pertama. Dua dekade yang lalu, pada zaman
Turbo Pascal 5.5 , ia tenggelam dalam jiwa saya dan telah berjalan bersama saya sejak saat itu, baik itu Delphi atau dalam beberapa tahun terakhir
Lazarus . Saya suka prediktabilitas bahasa, level relatif rendah (assembler menyisipkan dan melihat instruksi prosesor), kompatibilitas dengan C. Yang utama adalah bahwa kode dirakit dan dieksekusi tanpa masalah, tetapi tidak modis, ketinggalan jaman, dan ada beberapa fitur, ini omong kosong. Rumor mengatakan, ada orang yang masih menulis di
LISP , tetapi kepadanya secara umum selama setengah abad.
Jadi, mari selami perkembangannya. Untuk langkah uji, kami tidak akan mengambil model bayangan realistis yang akurat, tetapi mencoba menerapkan apa yang sudah kami coba sebelumnya, tetapi dengan kinerja GPU, jadi untuk perbandingan yang jelas.
Awalnya, saya berpikir untuk mendapatkan bayangan sekitar bentuk ini, menggunakan segitiga untuk objek.

Untuk membuat efek lingkaran halus, Anda membutuhkan banyak poligon. Tapi bagaimana jika Anda menggunakan segitiga seminimal mungkin, menggunakan pixel shader untuk membuat lubang pada bentuknya. Ide itu muncul di benak saya setelah membaca sebuah
artikel oleh seorang master yang disegani, di mana kesempatan dibuka untuk menciptakan sebuah bola dengan shader.

Jika Anda memperpanjang segitiga di luar batas layar, maka hasilnya adalah ini:

Perbatasan bayangan ternyata sangat kaku dan juga melangkah. Tetapi ada cara bagaimana mendapatkan hasil yang dapat diterima tanpa menggunakan
supersampling , ini menggunakan batas yang dihaluskan. Untuk melakukan ini, ubah skema sedikit. Sudut poligon di persimpangan garis singgung ke lingkaran akan menjadi transparan.

Hasilnya lebih baik, tetapi masih terlihat tidak alami.

Tambahkan sedikit penghalusan lingkaran untuk memberikan kelembutan, dan juga ubah bentuk gradien dari linier menjadi daya.

Ini adalah hasil yang dapat diterima.
Dan pada akhirnya kita akan menambahkan objek meniru rintangan ke formulir.

Kode shader//
#version 330 core
layout (location = 0) in vec2 aVertexPosition;
void main(void) {
gl_Position = vec4(aVertexPosition.xy, 0, 1.0);
}
//
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;
uniform mat4 uModelViewMatrix;
uniform float uRadius;
uniform vec2 uHeroPoint;
out float fTransparency;
out vec2 vCenter;
void main(){
vCenter = gl_in[0].gl_Position.xy;
vec2 d = uHeroPoint - vCenter;
float l = length(d);
float i = uRadius / l;
float ii = i*i;
float ij = i * sqrt(1 - ii);
vec2 p1 = vec2(vCenter.x + dx*ii - dy*ij , vCenter.y + dx*ij + dy*ii);
vec2 p2 = vec2(vCenter.x + dx*ii + dy*ij , vCenter.y - dx*ij + dy*ii);
d = uHeroPoint - p1;
vec2 p3 = vec2(p1 - d/length(d)*1000000);
d = uHeroPoint - p2;
vec2 p4 = vec2(p2 - d/length(d)*1000000);
fTransparency = 0;
gl_Position = uModelViewMatrix * vec4(p1, 0, 1);
EmitVertex();
fTransparency = 1;
gl_Position = uModelViewMatrix * vec4(p3, 0, 1);
EmitVertex();
gl_Position = uModelViewMatrix * vec4(vCenter, 0, 1);
EmitVertex();
gl_Position = uModelViewMatrix * vec4(p4, 0, 1);
EmitVertex();
fTransparency = 0;
gl_Position = uModelViewMatrix * vec4(p2, 0, 1);
EmitVertex();
EndPrimitive();
}
//
#version 330 core
precision mediump float;
varying float fTransparency;
varying vec2 vCenter;
uniform float uRadius;
uniform vec2 uScreenHalfSize;
uniform float uShadowTransparency;
uniform float uShadowSmoothness;
out vec4 FragColor;
void main(){
float l = distance(vec2((gl_FragCoord.xy - uScreenHalfSize.xy)/uScreenHalfSize.y), vCenter.xy);
if (l<uRadius) {discard;}
else {FragColor = vec4(0, 0, 0, min(pow(fTransparency, uShadowSmoothness), (l-uRadius)/uRadius*10)*uShadowTransparency);}
}
Saya harap ini informatif
Hamba rendah hati Anda, penyiksa piksel, Pembangun Ulang.
Saya melampirkan
demo kecil. (EXE Windows)
PS Judul artikel berisi
telur Paskah , referensi ke trilogi
Siala Chronicle . Sebuah karya luar biasa dalam gaya fantasi, tentang kemalangan tanduk, dari Alexei Pekhov.