Garis besar umum:
Buat peta kedalaman adegan Anda tanpa perisai. Anda bisa mendapatkan ini secara efektif secara gratis, karena objek transparan sering kali diberikan dalam pass kemudian. Jika tidak, Anda dapat membuat peta kedalaman dengan merender adegan tanpa pelindung ke RTT dengan shader kedalaman.
Jadikan adegan Anda secara normal, berikan peta kedalaman ke shader pelindung Anda.
Di shader, hitung perbedaan kedalaman adegan dari kedalaman fragmen perisai, dan gunakan perbedaan itu untuk memodifikasi warna fragmen.
Demo
Saya menulis demo WebGL sederhana tentang itu.
Baris demi baris
Mari kita membahas kode shader fragmen secara terperinci:
float solidsDepth = texture2D(depthMap, gl_FragCoord.xy / dims).r;
Sampel peta kedalaman di setiap fragmen. Ingatlah untuk membaginya dengan dimensi viewport Anda untuk mengonversi fragmen Anda dari ruang layar [0, lebar / tinggi] ke koordinat [0,0, 1.0] yang dinormalisasi. Pada titik ini, jika Anda cukup mengatur warna fragmen ke piksel peta kedalaman sampel, akan terlihat seperti ini:
Peta kedalaman berwarna abu-abu, sehingga Anda bisa mendapatkan nilai dari saluran apa pun (saya gunakan di r
sini).
float solidsDiff = 1.0 - smoothstep(
zNear,
zFar,
gl_FragCoord.z / gl_FragCoord.w
) - solidsDepth;
Anda kemudian dapat menggunakan sampel kedalaman untuk menemukan perbedaan antara kedalaman adegan dan kedalaman fragmen perisai. Ingatlah untuk menormalkan kedalaman Anda juga, untuk mengambilnya dari [zNear, zFar] (pesawat dekat dan jauh dari kamera Anda) ke [0,0, 1.0]. smoothstep
melakukan ini dengan baik. The 1.0 -
adalah untuk membalikkan nilai seperti yangsolidsDiff
adalah 1,0 ketika perbedaannya adalah maksimum (zFar - zNear) dan 0,0 minimal (0,0).
Perhatikan bahwa saya berasumsi solidsDepth
sudah dinormalisasi di shader kedalaman yang membuat peta kedalaman.
float alpha = 0.3 + max(0.0, 1.0 - log(100.0 * (solidsDiff - 0.005) + 1.0));
Anda kemudian dapat memodifikasi saluran alfa perisai Anda tergantung pada perbedaan kedalaman. Di sini kita mulai dari alfa minimum 0.3
, lalu buat peningkatan alfa yang tajam saat kita mendekati 0.0
perbedaan.
The - 0.005
diimbangi hanya menambahkan margin putih untuk membuat "persimpangan" lebih tebal. Coba modifikasi!
gl_FragColor = vec4(vec3(1.0), alpha);
Dan akhirnya, terapkan alpha itu ke warna fragmen Anda.
Perangkat tambahan
Anda bisa membuat perisai melengkung, menambahkan plasma untuk tampilan "perisai energi" (demo) atau menjelajahi efek hanya dengan menunjukkan persimpangan (demo) .
Langit Kartu grafis Anda adalah batasnya!