Sau khi viết shader 'tiêu chuẩn' phong & blinn một thời gian, gần đây tôi bắt đầu học cách tạo bóng dựa trên cơ thể. Một tài nguyên đã giúp tôi rất nhiều là những ghi chú khóa học , đặc biệt là bài viết này - nó giải thích làm thế nào để làm cho blinn trở nên bóng hơn về mặt vật lý.
Tôi đã mô phỏng mô hình blinn được đạo cụ trong bài báo, và tôi thực sự thích nó trông như thế nào. Sự thay đổi đáng kể nhất được đề xuất (imo) là sự bao gồm của phản xạ fresnel, và đây cũng là phần mang lại cho tôi các vấn đề. Thật không may, tác giả đã chọn chỉ tập trung vào phần đầu cơ, bỏ qua phản xạ khuếch tán. Ví dụ như một phản xạ khuếch tán lambertian, tôi chỉ không biết làm thế nào để kết hợp nó với blinn 'được cải thiện' - bởi vì chỉ cần thêm các phần khuếch tán & đặc biệt dường như không còn đúng nữa.
Trong một số shader tôi đã thấy một dấu phẩy động 'thuật ngữ fresnel' trong phạm vi 0 - 1 đang được sử dụng, dựa trên các chỉ số khúc xạ của phương tiện tham gia. Xấp xỉ của Schlick được sử dụng mỗi lần:
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 );
}
Làm như thế này, người ta có thể nội suy tuyến tính giữa đóng góp khuếch tán và đầu cơ dựa trên thuật ngữ fresnel, ví dụ
float fresnel = schlick( L, H, 1.0002926 /*air*/, 1.5191 /*other material*/ );
vec3 color = mix( diffuseContrib, specularContrib, fresnel );
Trong bài báo, tác giả nói rằng cách tiếp cận này không chính xác - vì về cơ bản, nó chỉ làm tối màu cơ bản bất cứ khi nào L song song hoặc gần như song song với H - và thay vì tính toán một chỉ số dựa trên các chỉ số khúc xạ, bạn nên xử lý đặc điểm tô màu chính nó như là 0,2 và có xấp xỉ schlick của bạn tính toán một vec3, như thế này:
vec3 schlick( in vec3 v0, in vec3 v1, in vec3 spec )
{
return spec + ( vec3( 1.0 ) - spec ) * pow( dot( v0, v1 ), 5 );
}
Điều này dẫn đến màu sắc đặc trưng sẽ chuyển sang màu trắng ở các góc nhìn.
Bây giờ câu hỏi của tôi là, làm thế nào tôi sẽ giới thiệu một thành phần khuếch tán vào đây? Ở 90 °, phần đóng góp đặc biệt có màu trắng hoàn toàn, điều này có nghĩa là tất cả ánh sáng tới được phản xạ, do đó không thể có sự đóng góp lan tỏa. Đối với các góc tới <90 °, tôi có thể nhân toàn bộ phần khuếch tán với (vec3 (1) - schlick), tức là tỷ lệ ánh sáng không bị phản xạ không?
vec3 diffuseContrib = max( dot( N, L ), 0.0 ) * kDiffuse * ( vec3( 1.0 ) - schlick( L, H, kSpec ) );
Hay tôi cần một cách tiếp cận hoàn toàn khác?