Bagaimana Anda menerapkan chromatic aberration?

22

Bagaimana Anda menerapkan efek chromatic aberration dengan shader?

Akankah rendering dunia dengan jarak fokus berbeda untuk setiap warna menyelesaikan masalah (mungkin dengan penggunaan hanya satu pass rendering mendalam)?

Quonux
sumber
Mengapa Anda ingin menerapkan abrasi kromatik?
ashes999
3
Anda dapat melanjutkan dengan cara yang sama saat mekar tercapai. Anda harus menggabungkan adegan normal Anda dengan 3 versi kabur; masing-masing dari tiga tekstur ini harus diwarnai terutama dalam 3 warna dasar .. Tentu saja, variasi dimungkinkan jika Anda menggunakan strategi blur yang berbeda untuk 3 tekstur (misalnya blur arah dengan offset sudut yang berbeda mungkin melakukan trik).
teodron
3
@ ashes999 - Mungkin lingkup sniper atau lensa panjang lainnya, untuk menambahkan sentuhan realisme? Aberasi kromatik adalah artefak dari banyak desain lensa majemuk.
KeithS
Anda mungkin juga ingin menerapkan chromatic aberration untuk melawan penyimpangan yang disebabkan oleh lensa yang digunakan untuk melihat permainan. Sebagai contoh, itu adalah ide yang baik untuk memiliki chromatic aberration di tepi tampilan dalam permainan yang dimainkan dengan Oculus Rift.
Joseph Mansfield

Jawaban:

22

Penyimpangan kromatik disebabkan ketika lensa tidak dapat memfokuskan setiap warna ke titik fokus yang sama. Cara sederhana untuk memalsukan efek ini, dan menjadikannya sebagai proses pasca-layar penuh cepat, adalah menerapkan offset untuk setiap saluran warna dalam shader fragmen.

Dengan menggunakan offset berbeda untuk setiap saluran, Anda dapat mencapai faksimili wajar dari efek yang diinginkan. Contoh teknik ini dapat ditemukan di sini ; shader fragmen akan terlihat seperti ini:

void main () {
    // Previously, you'd have rendered your complete scene into a texture
    // bound to "fullScreenTexture."
    vec4 rValue = texture2D(fullscreenTexture, gl_TexCoords[0] - rOffset);  
    vec4 gValue = texture2D(fullscreenTexture, gl_TexCoords[0] - gOffset);
    vec4 bValue = texture2D(fullscreenTexture, gl_TexCoords[0] - bOffset);  

    // Combine the offset colors.
    gl_FragColor = vec4(rValue.r, gValue.g, bValue.b, 1.0);
}

Peretasan sederhana ini tidak benar-benar memperhitungkan fakta bahwa penyimpangan kromatik adalah efek lensa, meskipun: untuk mendapatkan simulasi yang lebih baik, Anda sebenarnya ingin membuat sesuatu untuk bertindak sebagai lensa. Ini mirip dengan bagaimana Anda membuat objek yang reflektif atau bias. Konsekuensinya, shader refleksi / refraksi tipikal dapat menjadi dasar untuk menerapkan penyimpangan kromatik.

Biasanya, Anda akan menghitung vektor refraksi tunggal berdasarkan pandangan vektor dan beberapa didefinisikan indeks bias , menggunakan GLSL ini membiaskan fungsi dalam shader vertex:

void main () {
    // ...

    // RefractionVector is a varying vec3.
    // 'ratio' is the ratio of the two indices of refraction.
    RefractionVector = refract(incidentVector, normalVector, ratio);

    // ...
}

Kemudian Anda akan menggunakan vektor itu dalam shader fragmen untuk melakukan pencarian tekstur kubus (ke dalam peta lingkungan). Biasanya ini dilakukan di samping efek refleksi juga, dan dikombinasikan menggunakan istilah Fresnel yang dikomputasi .

Untuk mensimulasikan aberasi kromatik, maka, Anda dapat melakukan tiga perhitungan vektor refraksi yang berbeda , masing-masing sedikit diimbangi melalui indeks refraksi yang berbeda, di vertex shader:

void main () {
    // ...

    // RefractionVector is a varying vec3, as above.
    // 'ratioR,' et cetera, is the ratio of indices of refraction for
    // the red, green and blue components respectively.
    RedRefractionVector = refract(incidentVector, normalVector, ratioR);
    GreenRefractionVector = refract(incidentVector, normalVector, ratioG);
    BlueRefractionVector = refract(incidentVector, normalVector, ratioB);

    // ...
}

Ketiga vektor yang berbeda dapat digunakan untuk melakukan tiga pencarian peta kubus yang berbeda, yang dapat dicampur bersama mirip dengan bagaimana warna dicampur dalam contoh sederhana:

void main () {
    vec3 color;
    color.r = vec3(textureCube(EnvironmentMap, RedRefractionVector)).r;
    color.g = vec3(textureCube(EnvironmentMap, GreenRefractionVector)).g;
    color.b = vec3(textureCube(EnvironmentMap, BlueRefractionVector)).b;

    gl_FragColor = vec4(color, 1.0);
}

Untuk lebih jelasnya, OpenGL Orange Book tersedia dan berisi contoh efek refleksi dan refraksi dasar, serta contoh efek penyimpangan kromatik.


sumber
Apakah ada pendekatan yang hanya menggunakan satu sampel tekstur dan hanya mewarnai saja? Ini akan sangat bermanfaat untuk aplikasi seperti ray tracing, di mana tracing tiga vs satu ray sangat mahal.
Tara