- Shader browser menggabungkan hamburan Rayleigh, hamburan Mie, dan penyerapan ozon untuk merender langit biru serta matahari terbenam dan terbit secara real-time
- Kedalaman optik dari sinar kamera dan transmitansi menurut Beer's Law diakumulasikan, lalu distribusi hamburan berdasarkan arah matahari dihitung dengan phase function
- Efek matahari terbenam dibuat dengan menjalankan light-march terpisah ke arah matahari pada setiap sampel, sehingga jumlah cahaya matahari yang hilang saat menembus atmosfer ikut diperhitungkan
- Shader langit planar menjadi efek pascapemrosesan melalui depth buffer dan rekonstruksi koordinat dunia, sehingga kabut atmosfer di antara objek dalam adegan juga bisa ditangani
- Pada skala planet, teknik ini diperluas dengan logarithmic depth buffer, ray-sphere intersection, serta LUT berbasis Transmittance, Sky-view, dan Aerial Perspective
Tujuan shader hamburan atmosfer dan referensi
Model dasar perenderan langit
-
Mengapa gradien sederhana tidak cukup
- Warna langit bukan sekadar latar biru sederhana, melainkan harus diperlakukan sebagai hasil interaksi cahaya dengan udara dan komponen penyusunnya
- Variabel seperti ketinggian pengamat, jumlah debu, dan waktu dalam sehari perlu diperhitungkan, dan perhitungannya dilakukan di dalam volume
-
Sampling kepadatan atmosfer
- Atmosfer di-sampling dengan raymarching seperti pada volumetric clouds atau volumetric light
- Sinar ditembakkan dari posisi kamera lalu bergerak maju mengikuti medium transparan, sambil menghitung transmitansi cahaya yang bertahan saat melewati atmosfer dan hamburan yang diarahkan kembali ke kamera di tiap sampel
- Untuk penyegaran tentang raymarching, bisa merujuk ke Painting with Math: A Gentle Study of Raymarching
-
Kepadatan Rayleigh dan kedalaman optik
- Untuk mendapatkan transmitansi, kepadatan atmosfer yang ditemui sepanjang jalur sinar harus diakumulasikan guna menghitung kedalaman optik
- Fungsi kepadatan Rayleigh menunjukkan seberapa banyak “udara” yang ada pada ketinggian
h, dan mencerminkan efek bahwa atmosfer makin tipis saat ketinggian bertambah
- Implementasi contoh memakai
RAYLEIGH_SCALE_HEIGHT = 8.0km, ATMOSPHERE_HEIGHT = 100.0km, VIEW_DISTANCE = 200.0km, dan PRIMARY_STEPS = 24
rayleighDensity(h) adalah exp(-max(h, 0.0) / RAYLEIGH_SCALE_HEIGHT), dan di dalam loop diakumulasikan dengan viewOpticalDepth += dR * stepSize
-
Beer's Law dan warna biru langit siang
- Dari kedalaman optik, transmitansi
T pada titik tertentu dihitung, dengan T=1.0 berarti tidak ada kehilangan cahaya dan T=0.0 berarti cahaya sepenuhnya hilang
- Transmitansi dihitung dengan Beer's Law, dan kode contoh memakai
vec3 transmittance = exp(-rayleighBeta * viewOpticalDepth)
rayleighBeta adalah koefisien hamburan Rayleigh, dan di shader disimpan sebagai vec3(0.0058, 0.0135, 0.0331)
- Sudut antara arah cahaya matahari dan sinar pandang dimodelkan dengan Rayleigh phase function berbentuk
3.0 / (16.0 * PI) * (1.0 + mu * mu)
- Karena koefisien hamburan Rayleigh, merah hampir tidak terhambur, hijau sedikit lebih banyak, dan biru paling banyak terhambur, sehingga langit siang tampak biru
- Jika diperluas menjadi satu sinar per piksel, arah cakrawala melewati lebih banyak atmosfer sehingga tampak seperti kabut putih terang, sedangkan makin tinggi ke atas warnanya berubah menjadi biru yang lebih dalam dan gelap
Hamburan Mie dan penyerapan ozon
-
Efek yang tidak cukup dijelaskan oleh Rayleigh saja
- Hamburan Rayleigh saja sudah bisa memberi hasil yang cukup baik, tetapi langit yang lebih realistis memerlukan efek atmosfer tambahan
- Hamburan Mie merepresentasikan interaksi cahaya dengan partikel yang lebih besar seperti debu atau aerosol, serta memiliki fungsi kepadatan dan phase function yang menggambarkan redistribusi menurut arah
- Penyerapan ozon menghilangkan sebagian panjang gelombang cahaya dari jalurnya saat melewati atmosfer atas tanpa menghamburkannya
- Penyerapan ozon terutama memperdalam warna langit dan menggeser warnanya di sekitar cakrawala, saat matahari terbenam, terbit, dan pada masa rembang
-
Akumulasi Mie dan ozon
- Implementasi yang memakai Rayleigh, Mie, dan ozon bersama-sama mengakumulasikan kedalaman optik masing-masing ke dalam
viewODR, viewODM, dan viewODO
- Pada setiap sampel dihitung
dR = rayleighDensity(h), dM = mieDensity(h), dO = ozoneDensity(h), lalu tau dibentuk dari penjumlahan BETA_R * viewODR, BETA_M_EXT * viewODM, dan BETA_OZONE_ABS * viewODO
- Transmitansi dihitung sebagai
exp(-tau), dan ke sumR, sumM, serta sumO diakumulasikan masing-masing kepadatan, transmitansi, dan stepSize
- Hamburan akhir dihitung dalam bentuk
SUN_INTENSITY * (phaseR * BETA_R * sumR + phaseM * BETA_M_SCATTER * sumM + BETA_OZONE_SCATTER * sumO)
-
Konstanta utama dan efeknya
MIE_SCALE_HEIGHT adalah padanan RAYLEIGH_SCALE_HEIGHT untuk aerosol, dan karena partikel biasanya terkonsentrasi dekat cakrawala, nilainya dibuat lebih kecil yaitu 1.2km
MIE_BETA_SCATTER mengontrol seberapa besar partikel menghamburkan cahaya ke arah kamera, dan karena umumnya hampir tidak bergantung pada panjang gelombang, nilainya diatur ke vec3(0.003)
MIE_BETA_EXT adalah koefisien ekstingsi Mie yang menunjukkan seberapa banyak cahaya dihilangkan dari jalur, sehingga atmosfer jauh tampak lebih berkabut
MIE_G mengontrol anisotropi, dengan 0.0 berarti hamburan seragam dan 1.0 berarti bias hamburan maju yang lebih kuat
OZONE_BETA_ABS memiliki nilai vec3(0.00065, 0.00188, 0.00008), menyerap lebih banyak hijau serta spektrum kuning-oranye, sehingga warna langit bergeser ke arah biru, merah, dan ungu
- Dengan mengintegrasikan Mie dan ozon, warna “sky blue” menjadi lebih alami dan muncul halo cahaya berkabut di sekitar matahari, sementara efek hamburan Mie menjadi lebih jelas saat matahari berada dekat cakrawala
Jalur cahaya dan matahari terbenam·terbit
-
Batasan implementasi yang ada
- Sky fragment shader dapat merender warna yang natural di berbagai ketinggian serta mencerminkan model transmitansi Mie, Rayleigh, dan ozon
- Namun, meski matahari dipindahkan mendekati cakrawala, yang muncul hanya gumpalan cahaya putih yang kabur tanpa pelemahan cahaya atau efek matahari terbenam·terbit
- Ini karena loop raymarching yang ada hanya menghitung pelemahan cahaya pada sinar pandang dari kamera ke tiap sampel
- Sebelum mencapai titik sampel, perlu juga dihitung seberapa besar cahaya matahari berkurang saat melewati atmosfer
-
Loop bertingkat light-march
- Pada setiap titik sampel, dijalankan loop bertingkat terpisah ke arah sumber cahaya untuk mengambil sampel transmitansi pada jalur tersebut
- Pendekatan terkait juga digunakan pada real-time cloudscapes dan volumetric lighting
lightMarch(float start, float sunY) mengulangi sebanyak LIGHTMARCH_STEPS sambil mengakumulasi odR, odM, odO
- Optical depth implementasi yang ada
viewODR, viewODM, viewODO ditambahkan dengan optical depth arah matahari sunOD
tau akhir dibentuk dengan menjumlahkan BETA_R * (viewODR + sunOD.x), BETA_M_EXT * (viewODM + sunOD.y), dan BETA_OZONE_ABS * (viewODO + sunOD.z)
- Dengan implementasi ini, langit untuk matahari terbenam, matahari terbit, matahari di zenit, dan kondisi pencahayaan di antaranya dapat dirender
- Uniform
sun angle menghasilkan perubahan warna biru langit sepanjang hari, dan hamburan Mie membaurkan cahaya secara alami dengan cakrawala saat matahari terbenam dan terbit
- Saat matahari rendah, ozon menambahkan nuansa ungu pada langit
Diperluas ke atmosfer planet
-
Dari latar belakang datar ke efek post-processing
- Shader yang dibuat sebelumnya memberi latar langit yang bagus, tetapi masih terasa seperti latar belakang datar pada scene React Three Fiber
- Langkah berikutnya adalah mengubahnya menjadi efek post-processing untuk merender volume yang mempertimbangkan kedalaman scene dan cangkang atmosfer yang mengelilingi mesh planet
- Untuk ini, koordinat ruang dunia direkonstruksi dari koordinat
screenUV, lalu depth buffer scene diterapkan ke raymarching
-
Rekonstruksi ruang dunia dan sinar 3D
- Untuk menerapkan hamburan atmosfer ke scene, bukan hanya menggambar langit, tetapi juga mengisi ruang antara kamera dan objek yang dirender di layar
- Data yang dibutuhkan adalah depth buffer scene,
projectionMatrixInverse, matrixWorld, dan position milik kamera, lalu nilai-nilai ini dikirim sebagai uniform ke efek post-processing
getWorldPosition(vec2 uv, float depth) membuat clipZ dengan depth * 2.0 - 1.0, membuat koordinat NDC dengan uv * 2.0 - 1.0, lalu menerapkan projectionMatrixInverse dan viewMatrixInverse
- Proses yang sama juga digunakan pada efek post-processing volumetric lighting di On Shaping Light
- Setelah mendapatkan
worldPosition untuk piksel saat ini, rayOrigin dihitung sebagai posisi kamera dan rayDir sebagai normalize(worldPosition - rayOrigin) untuk melangkah sepanjang sinar 3D per piksel di layar
-
Menyesuaikan rentang raymarch dengan depth buffer
- Untuk mempertimbangkan geometri scene, alih-alih
stepSize tetap, rentang raymarch untuk sinar saat ini harus ditentukan dengan depth buffer
sceneDepth = depthToRayDistance(uv, depth) digunakan untuk mendapatkan kedalaman scene pada sinar tersebut
- Piksel latar belakang diidentifikasi dengan
depth >= 1.0 - 1e-7, dan pada “sky pixels” diterapkan sceneDepth = atmosphereHeight * SKY_MARCH_DISTANCE_MULTIPLIER
- Jika sinar mengarah ke bawah, perpotongan tanah dihitung dengan
tGround = observerAltitude / max(-rayDir.y, 1e-4) dan dibatasi dengan rayEnd = min(rayEnd, tGround)
stepSize akhir dihitung sebagai (rayEnd - rayStart) / float(PRIMARY_STEPS)
- Sinar yang menyentuh objek dekat atau tanah akan mengambil sampel lebih akurat dengan
stepSize kecil, sementara sinar yang menjangkau jauh mendistribusikan jumlah sampel yang sama di atas jarak yang lebih panjang
-
Kabut atmosfer di dalam scene
- Shader yang diimplementasikan sebagai efek post-processing menerapkan hamburan atmosfer ke seluruh volume scene, dan shader langit dapat digunakan sebagai latar belakang sambil tetap mempertimbangkan geometri scene
- Objek yang dekat dengan kamera terlihat lebih tajam, sedangkan objek yang jauh menjadi lebih buram
- Contoh interaktif dengan benda langit yang bisa di-drag menggunakan
Raycaster dapat dilihat di tweet MaximeHeckel
Rendering planet
-
Dua langkah yang diperlukan
- Untuk merender atmosfer realistis di sekitar planet, diperlukan logarithmic depth buffer untuk menangani skala besar, serta selubung atmosfer berbentuk bola yang mendefinisikan di mana sinar mulai dan berakhir di atmosfer
-
logarithmic depth buffer
- Pada skala planet, saat dilihat dari jauh, shader dapat kesulitan membedakan perbedaan kedalaman antara atmosfer dan permukaan planet sehingga bisa terjadi depth fighting
- Karena tinggi atmosfer hanya beberapa km, definisi depth buffer pada scene dan cara membacanya dalam efek post-processing sama-sama perlu disesuaikan
- Di React Three Fiber, atur
logarithmicDepthBuffer: true pada prop gl yang membungkus Canvas
- Contoh konfigurasinya berbentuk
<Canvas shadows gl={{ alpha: true, logarithmicDepthBuffer: true }}>
- Di shader, perhitungan
sceneDepth didefinisikan ulang untuk mengembalikan logarithmic depth buffer menjadi jarak di sepanjang sinar
logDepthToViewZ(depth) menggunakan pow(2.0, depth * log2(cameraFar + 1.0)) - 1.0 dan mengembalikan -d
-
Menemukan segmen atmosfer dengan ray-sphere intersection
- Untuk mencari titik saat sinar pandang masuk dan keluar dari bola atmosfer (atmospheric sphere), digunakan ray-sphere intersection test
- Dengan mendapatkan dua titik perpotongan, raymarching loop bisa dibatasi hanya pada segmen itu tanpa membuang sampel di luar atmosfer
- Karena planet berbentuk mesh bola dan dikelilingi oleh bola atmosfer yang sedikit lebih besar, uji perpotongan yang sama juga diterapkan pada planet itu sendiri
- Jika sinar menyentuh permukaan sebelum keluar dari atmosfer, titik perpotongan dengan permukaan digunakan sebagai akhir segmen raymarching
- Implementasi
raySphereIntersect yang digunakan merujuk pada Inigo Quilez di Ray-Surface intersection functions
-
Objek scene dan kondisi penghentian atmosfer
- Atmosfer harus berhenti saat menyentuh permukaan planet, atau saat bertemu objek scene lain sebelum menyentuh permukaan
- Untuk kasus menyentuh planet, secara default digunakan
atmosphereFar = min(atmosphereFar, planetHit.x) agar berhenti di permukaan
- Jika mesh lain dirender di depan permukaan, hal itu dideteksi dengan kondisi
sceneDepth < planetHit.x - 2.0 lalu diterapkan atmosphereFar = min(atmosphereFar, sceneDepth)
- Tanpa logika ini, akan muncul masalah di mana permukaan planet terlihat berada di depan objek
-
Demo React Three Fiber dan glitch yang masih tersisa
- Setelah dua penyesuaian itu diterapkan ke kode, atmospheric scattering dapat diimplementasikan sebagai efek post-processing dan atmosfer di sekitar planet bisa dirender
- Scene demo merender “Sun - Earth system” sederhana di React Three Fiber dan menerapkan efek kustom
- Dengan mengatur posisi matahari dan melakukan zoom out, warna langit yang dihasilkan shader bisa dilihat dari berbagai sudut, dari permukaan hingga orbit
- Efek yang sama juga digunakan pada gambar poster untuk teaser artikel awal April, dan hasil render dibagikan lewat tweet
- Torus dalam scene masih bisa terlihat “lit-up” bahkan setelah matahari terbenam
- Penyebabnya adalah shadow-map atau skala shadow-camera dari directional light utama terlalu kecil sehingga tidak dapat mencakup torus yang terlalu jauh
- Sebagai solusi sementara, pendekatan shadow-mapping dari volumetric lighting article bisa digunakan kembali, tetapi belum benar-benar dicoba
Menangani gerhana
- Jika benda langit besar menutupi matahari, hal ini bisa ditambahkan dengan memanggil fungsi
sunVisibility setelah lightMarch lalu mengalikan nilai balik [0, 1] ke transmitansi
- Ide dasarnya adalah membandingkan hasil dot product antara arah bulan dan arah matahari dari titik sampel saat ini
- Jika kedua arah hampir sama sehingga dot product mendekati
1.0, berarti bulan sedang menutupi matahari; jika tegak lurus dan mendekati 0.0, berarti tidak ada penutupan
- Dot product sederhana saja tidak bisa merefleksikan ukuran dan skala objek di dalam scene, jadi implementasinya membandingkan jarak sudut antara matahari dan bulan serta masing-masing jari-jari sudutnya
sunVisibility menangani kasus saat bulan tidak menutupi matahari, saat bulan menutupi matahari ketika dari sudut pandang kamera ukurannya terlihat lebih besar atau mirip, dan saat bulan menutupi matahari ketika masuk ke dalam radius matahari dari sudut pandang kamera
- Demo menambahkan
sunVisibility dan mesh bulan ke contoh atmospheric scattering yang sudah ada, sehingga saat bulan disejajarkan dengan matahari, shader Atmospheric Scattering menangani kondisi kekurangan cahaya
- Simulasi gerhana dan korona yang lebih canggih dibahas dalam paper Physically Based Real-Time Rendering of Eclipses, tetapi implementasi paper tersebut tidak di-port ke WebGL
Atmosfer planet lain
- Model kepadatan atmosfer dan scattering yang digunakan sebagian besar ditentukan oleh radius planet dan atmosfer, serta beberapa konstanta seperti
RayleighScaleHeight, RayleighBeta, MieScaleHeight, MieBeta, mieBetaExt, mieG, OzoneHeight, OzoneWidth
- Dengan menyesuaikan nilai-nilai ini, hasil yang mendekati atmosfer Mars atau atmosfer planet lain bisa dibuat
- Nilai yang digunakan untuk Mars adalah nilai perkiraan
planetRadius: 3390
atmosphereRadius: 3500, ketebalan sekitar 110 km
rayleighScaleHeight: 11.1
rayleighBeta: new THREE.Vector3(0.019, 0.013, 0.0057)
mieScaleHeight: 1.5
mieBeta: 0.04
mieBetaExt: 0.044
mieG: 0.65
ozoneCenterHeight: 0.0
ozoneWidth: 1.0
ozoneBetaAbs: new THREE.Vector3(0.0, 0.0, 0.0)
sunIntensity: 15.0
planetSurfaceColor: '#8B4513'
- Jika konstanta yang ada diganti dengan nilai-nilai ini, atmosfer akan terlihat lebih berdebu dan jingga, dan rona biru saat matahari terbenam yang khas Mars juga bisa diperoleh
- Ada juga paper terkait, Physically Based Rendering of the Martian Atmosphere
Hamburan atmosfer berbasis LUT
-
Pendekatan dan bagian yang disederhanakan
- Shader sebelumnya dapat merender atmosfer skala kecil dan skala besar secara intuitif, tetapi biaya eksekusinya tinggi karena loop raymarching dengan
PRIMARY_STEPS yang banyak, loop bertingkat lightmarching, dan perhitungan pada resolusi full-screen
- A Scalable and Production Ready Sky and Atmosphere Rendering Technique karya Sebastian Hillaire mengusulkan pendekatan berbasis Look Up Tables (LUTs) yang menyimpan perhitungan hamburan yang mahal ke dalam tekstur, lalu melakukan sampling dan komposisi tekstur yang sudah dipra-hitung pada render akhir
- LUT yang dibahas adalah Transmittance LUT yang menyimpan jumlah cahaya yang bertahan saat melewati atmosfer, Sky-view LUT yang menyimpan warna langit dari posisi kamera tertentu, dan Aerial Perspective LUT yang menyimpan haze atmosfer dan cahaya hamburan antara kamera dan geometri adegan yang terlihat
- Implementasinya tidak memindahkan seluruh isi paper apa adanya; LUT memang cocok untuk compute shader WebGPU, tetapi karena keterbatasan waktu dan kesinambungan tulisan, tetap menggunakan WebGL
- Dalam paper, Aerial Perspective LUT adalah 3D texture, tetapi dalam implementasi digunakan render target 2D
- Pendekatan ini mengharuskan tekstur dibuat ulang setiap kali kamera bergerak agar nilai piksel tetap benar, sehingga sulit untuk dipra-hitung
- Multi-Scattering dihilangkan karena keterbatasan waktu
-
Transmittance LUT
- Pada shader sebelumnya, setiap titik sampel memanggil
lightmarch untuk menghitung seberapa banyak cahaya matahari yang sampai, dan proses ini mahal
- Transmittance LUT menyimpan data ini terlebih dahulu pada resolusi rendah agar LUT lain dapat membaca dan menggunakannya saat membutuhkan data cahaya
- Implementasinya mendefinisikan Frame Buffer Object khusus beresolusi
250 x 64, menerapkan material shader kustom pada full-screen quad di adegan khusus transmittanceLUTScene, lalu meneruskan tekstur hasil render sebagai uniform untuk LUT downstream
- Pada setiap piksel, raymarching dimulai dari
vec3(0.0, radius, 0.0), dengan radius meningkat dari planetRadius ke atmosphereRadius sepanjang koordinat vUv.y
- Sumbu x LUT merepresentasikan sudut cahaya, sedangkan sumbu y merepresentasikan ketinggian; putih murni berarti transmitansi
100%, sedangkan area hitam atau berwarna menunjukkan tanah atau bagian udara yang paling tebal
- Setelah itu, LUT lain dapat memperoleh “jumlah cahaya yang bertahan setelah melewati atmosfer pada sudut dan ketinggian tertentu” hanya dengan lookup tekstur
-
Sky-view LUT
- Sky-view LUT menghitung warna langit saat melihat ke atas dari permukaan ke arah tertentu
getSkyViewRayDir memetakan vUv.x ke azimuth [-PI, PI] dan vUv.y ke elevation [-PI/2, PI/2] untuk menentukan arah raymarching
- Untuk elevation digunakan quadratic mapping
(vUv.y * vUv.y - 0.5) * PI, sebagai jalan pintas untuk menghindari Sky View berkedip terlalu banyak pada jarak jauh
- Jika ray tidak masuk ke atmosfer, fungsi mengembalikan hitam; untuk ray yang menyentuh planet, raymarching hanya dilakukan pada bagian atmosfer yang terlihat dan berhenti lebih awal saat mencapai planet
- Loop hamburannya sama seperti sebelumnya, tetapi berjalan mengikuti arah Sky View dan menggunakan Transmittance LUT untuk cahaya matahari
-
Aerial Perspective LUT
- Berbeda dari paper Hillaire, hasil implementasinya berupa tekstur 2D, dan setiap piksel berkorespondensi dengan satu piksel layar yang terlihat
- Depth buffer adegan digunakan untuk menentukan seberapa jauh harus melangkah di sepanjang ray tersebut dan mengakumulasi hamburan
- Kode hamburan lama hampir seluruhnya dipakai ulang, tetapi setiap sampel mengambil visibilitas cahaya matahari dari Transmittance LUT
- Output menyimpan hamburan atmosfer terakumulasi pada RGB, dan nilai packed view transmittance pada alpha untuk dipakai saat komposisi
- Alur implementasinya adalah membaca kedalaman dari
depthBuffer, memulihkan posisi ruang dunia piksel layar dengan getWorldPosition(vUv, depth), lalu menghitung rayDir dari posisi kamera ke posisi dunia tersebut
- Setelah itu,
logDepthToRayDistance(vUv, depth) mengubah kedalaman adegan menjadi jarak ray, menghitung perpotongan atmosfer dan planet, lalu hanya melakukan march pada bagian atmosfer yang terlihat
-
Komposisi
- Setelah Sky-view LUT dan Aerial Perspective LUT dibuat, keduanya digabungkan pada pass post-processing terakhir
- Pekerjaan utamanya adalah mengubah
rayDir saat ini menjadi koordinat UV Sky View
- Untuk geometri adegan, Aerial Perspective LUT diterapkan; kanal alpha dipakai sebagai view transmittance, dan kanal RGB sebagai cahaya hamburan, sehingga dihitung
color = color * aerialPerspective.a + aerialPerspective.rgb
- Untuk piksel latar belakang, Sky View LUT di-sample, dan jika
depth >= 1.0 - 1e-7 maka dianggap sebagai latar belakang lalu diterapkan color = inputColor.rgb + sampleSkyViewLUT(rayDir, planetCenter)
- Terakhir, diterapkan
ACESFilm(color) dan pow(color, vec3(1.0 / 2.2))
- Seluruh kode implementasi atmosfer berbasis LUT dapat dilihat di Github link
Penutup
- Hasil hamburan atmosfer berbasis LUT mungkin terlihat hampir sama dengan versi raymarching penuh sebelumnya, tetapi proses internalnya berbeda
- Pekerjaan dipecah menjadi LUT-LUT yang lebih kecil lalu dikomposisikan pada efek akhir, dan tidak lagi melakukan raymarching berulang ke arah matahari untuk menghitung cahaya yang sampai pada setiap sampel
- Karena informasi pencahayaan diambil langsung dari Transmittance LUT, loop bertingkat yang mahal digantikan dengan lookup tekstur sederhana dan menghasilkan peningkatan performa yang berarti pada adegan akhir
- Implementasi ini masih kalah dibandingkan implementasi Sébastian Hillaire dan implementasi di bidang lain; khususnya masih ada banding dan flickering pada Sky View, dan optimalitasnya menurun karena beberapa penyederhanaan
- Mungkin seharusnya sejak awal menggunakan WebGPU
- Untuk implementasi production-grade yang nyata, penulis merekomendasikan three-geospatial karya Shoda Matsuda(@shotamatsuda)
- Selain itu, penulis juga mengerjakan penambahan volumetric clouds, tetapi hasilnya masih campur aduk dan belum cukup memuaskan untuk ditampilkan dalam tulisan, sehingga masih perlu dikerjakan lebih lanjut
1 komentar
Komentar Hacker News
Ada keseruan tersendiri dalam mengembangkan efek visual dan melihatnya makin mendekati realistis, dan suatu hari saya ingin mencoba bereksperimen di bidang ini sendiri
Dulu videonya mendapat jutaan penayangan, sekarang menembus 500 ribu pun nyaris susah. Mungkin juga karena saat masa COVID semua orang di rumah dan jadi tertarik pada hal-hal acak
Biasanya saya memutarnya saat mau tidur, dan karena saya berharap ada lebih banyak konten seperti ini—tenang tetapi mendalami topik teknis—saya bahkan pernah berpikir untuk membuatnya sendiri
Setelah matahari terbenam, atmosfer di atas kepala dan area di atas cakrawala masih menerima sinar matahari untuk sementara waktu, dan di atmosfer Bumi senja yang jelas masih bertahan sampai matahari turun 18 derajat di bawah cakrawala. Mungkin tidak praktis untuk mengimplementasikannya dengan ray tracing, tetapi ada algoritma umum untuk memodelkannya
https://www.threads.com/@mrsharpoblunto/post/DVS4wfYiG8f?xmt...
https://www.threads.com/@mrsharpoblunto/post/C6Vc-S1O9mX?xmt...
https://www.threads.com/@mrsharpoblunto/post/C6apksDRa8q?xmt...
Saya masih ingat pernah mengimplementasikan “Display of The Earth Taking into Account Atmospheric Scattering” karya Nishita dkk., makalah tahun 1993 yang nyaris merupakan karya perintis untuk topik ini dan sangat mudah dibaca: https://www.researchgate.net/publication/2933032_Display_of_...
Saat berhasil membuatnya bekerja, ada momen seperti, “fenomena dunia nyata yang rumit ini ternyata bisa dimodelkan dengan cukup baik hanya dengan beberapa perhitungan yang relatif sederhana.” Dari skybox biru statis, semuanya langsung berubah menjadi siklus siang-malam penuh
Dulu saya pernah berpikir bagaimana kalau langit di web dirender dengan menumpuk beberapa gradien. Mungkin saya bisa mendapat hasil yang lumayan dengan tingkat keberhasilan tertentu, tetapi itu tetap tidak sebanding dengan yang dibuat di sini. Hasilnya mengesankan dan memberi inspirasi
Hanya dengan itu saja saya kaget melihat betapa meyakinkannya siklus matahari terbenam/terbit yang dihasilkan, dan kalau ingatan saya benar, mataharinya sendiri juga entah bagaimana muncul secara alami dari situ. Saya menggunakan XNA, platform pengembangan game C# dari Microsoft, sambil mengikuti seri tutorial hebat dari Riemer, dan arsipnya ada di sini https://github.com/SimonDarksideJ/XNAGameStudio/wiki/Riemers...
Namun saya tidak melihat bagian tentang hamburan, jadi mungkin untuk bagian itu saya mengambilnya dari tempat lain. Saya masih ingat pernah membaca makalah yang berisi rumus
https://spaceengine.org/
Jawaban untuk “Berapa banyak objek yang ada di SpaceEngine?” kurang lebih menyebut 130 ribu objek dari seluruh katalog bintang Hipparcos, semua eksoplanet yang diketahui, lebih dari sepuluh ribu galaksi, dan sebagian besar objek di tata surya, lalu ditambah lebih banyak galaksi dan sistem bintang daripada yang benar-benar ada di seluruh alam semesta teramati. Untuk “Bagaimana planet air bisa panas?” jawabannya adalah bahwa air di atmosfer atas merupakan uap panas, tetapi semakin ke bawah ia bertransisi mulus menjadi cair di bawah tekanan tinggi, dan lebih dalam lagi menjadi keadaan padat bernama ice VII. Untuk “Bagaimana cara bergerak?” jawabannya adalah tombol WASD
Ini game yang luar biasa, dan meski sudah cukup tua, saya masih belum melihat banyak yang sebanding
Melihat tulisan ini juga langsung mengingatkan saya pada SpaceEngine
Salah satu makalah favorit saya: http://www.graphics.stanford.edu/papers/bssrdf/bssrdf.pdf
Saya rasa saat itulah pertama kali saya tahu bahwa merender susu adalah masalah yang rumit
Mungkin saya cuma paham sekitar 5%, tetapi saya benar-benar kagum
Dan kalau ini berlisensi MIT, berarti masalah skybox di game saya praktis sudah terpecahkan. Karena perspektifnya akan tetap, saya hanya perlu rendering matahari yang bergerak melintasi langit, lalu bisa memperluasnya dengan variasi sudut matahari tahunan menggunakan periode gelombang sinus