Setelah menulis 'standar' phong & blinn shaders untuk sementara waktu, saya baru-baru ini mulai mencoba-coba shading berbasis fisik. Sebuah sumber yang banyak membantu saya adalah catatan kursus ini , terutama tulisan ini - ini menjelaskan bagaimana membuat blinn lebih teduh secara fisik masuk akal.
Saya menerapkan model blinn yang dipasang di kertas, dan saya sangat suka tampilannya. Perubahan paling signifikan yang diusulkan (imo) adalah dimasukkannya reflektor fresnel, dan ini juga bagian yang memberi saya masalah. Sayangnya, penulis memilih untuk fokus pada bagian specular saja, menghilangkan pantulan difus. Diberikan misalnya refleksi difus lambertian, saya hanya tidak tahu bagaimana menggabungkannya dengan blinn 'ditingkatkan' - karena hanya menambahkan bagian difus & specular tampaknya tidak benar lagi.
Dalam beberapa shader saya telah melihat 'fresnel term' titik mengambang dalam rentang 0 - 1 yang digunakan, berdasarkan indeks bias media yang berpartisipasi. Perkiraan Schlick digunakan setiap saat:
float schlick( in vec3 v0, in vec3 v1, in float n1, in float n2 )
{
float f0 = ( n1 - n2 ) / ( n1 + n2 );
f0 *= f0;
return f0 + ( 1 - f0 ) * pow( dot( v0, v1 ), 5 );
}
Melakukannya seperti ini, maka seseorang dapat menginterpolasi secara linear antara kontribusi difus dan spekuler berdasarkan istilah fresnel, misalnya
float fresnel = schlick( L, H, 1.0002926 /*air*/, 1.5191 /*other material*/ );
vec3 color = mix( diffuseContrib, specularContrib, fresnel );
Dalam makalah, penulis menyatakan bahwa pendekatan ini tidak benar - karena pada dasarnya hanya menggelapkan warna specular setiap kali L sejajar atau hampir sejajar dengan H - dan bahwa alih-alih menghitung f0 berdasarkan indeks bias, Anda harus memperlakukan specular warna itu sendiri sebagai f0 dan minta pendekatan schlick Anda menghitung vec3, seperti ini:
vec3 schlick( in vec3 v0, in vec3 v1, in vec3 spec )
{
return spec + ( vec3( 1.0 ) - spec ) * pow( dot( v0, v1 ), 5 );
}
Ini menghasilkan warna specular menuju putih pada sudut pandang.
Sekarang pertanyaan saya adalah, bagaimana saya memperkenalkan komponen difus ke dalam ini? Pada 90 ° kontribusi specular sepenuhnya putih, ini berarti semua cahaya yang masuk dipantulkan, sehingga tidak mungkin ada kontribusi difus. Untuk sudut datang <90 °, dapatkah saya mengalikan seluruh bagian difus dengan (vec3 (1) - schlick), yaitu proporsi cahaya yang tidak dipantulkan?
vec3 diffuseContrib = max( dot( N, L ), 0.0 ) * kDiffuse * ( vec3( 1.0 ) - schlick( L, H, kSpec ) );
Atau apakah saya memerlukan pendekatan yang sama sekali berbeda?