затенение физически, как объединить зеркальные и диффузные части?

8

После того, как я некоторое время писал «стандартные» шейдеры phong & blinn, я недавно начал заниматься физическим шейдингом. Ресурс, который мне очень помог, - это заметки о курсе , особенно эта статья, в которой объясняется, как сделать блины более правдоподобными.

Я реализовал модель blinn, изложенную в статье, и мне очень нравится, как она выглядит. Наиболее существенным предложенным изменением (imo) является включение коэффициента отражения Френеля, и это также та часть, которая доставляет мне проблемы. К сожалению, автор решил сосредоточиться только на зеркальной части, исключив диффузное отражение. Учитывая, например, диффузное отражение Ламберта, я просто не знаю, как объединить его с «улучшенным» блином - потому что простое добавление рассеянных и зеркальных частей кажется неправильным.

В некоторых шейдерах я видел «термин Френеля» с плавающей точкой в ​​диапазоне 0 - 1, основанный на показателях преломления участвующих сред. Аппроксимация Шлика используется каждый раз:

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 );
} 

Делая это таким образом, можно затем линейно интерполировать между диффузным и зеркальным вкладом на основе члена Френеля, например

float fresnel = schlick( L, H, 1.0002926 /*air*/, 1.5191 /*other material*/ );
vec3 color = mix( diffuseContrib, specularContrib, fresnel );

В статье автор заявляет, что этот подход неверен - потому что он в основном просто затемняет зеркальный цвет всякий раз, когда L параллелен или почти параллелен H - и что вместо вычисления f0 на основе показателей преломления вы должны рассматривать зеркальное отражение раскрасьте себя как f0 и сделайте, чтобы ваше приближение schlick вычислило vec3, например так:

vec3 schlick( in vec3 v0, in vec3 v1, in vec3 spec )
{
    return spec + ( vec3( 1.0 ) - spec ) * pow( dot( v0, v1 ), 5 );
}

Это приводит к зеркальному цвету, идущему к белому под скользящими углами.

Теперь мой вопрос: как бы я ввел диффузный компонент в это? При 90 ° зеркальный вклад полностью белый, это означает, что весь входящий свет отражается, поэтому не может быть рассеянного вклада. Для углов падения <90 ° могу ли я просто умножить всю диффузную часть на (vec3 (1) - schlick), то есть на долю света, который не отражается?

vec3 diffuseContrib = max( dot( N, L ), 0.0 ) * kDiffuse * ( vec3( 1.0 ) - schlick( L, H, kSpec ) );

Или мне нужен совершенно другой подход?

gemse
источник
2
Вы когда-нибудь решали это? У меня сейчас точно такая проблема.
1
Я тоже хотел бы получить ответ на этот вопрос. Лагард также предлагал аналогичное вычитание зеркального цвета (которое он в конечном итоге «не использовал»), но все это кажется очень произвольным.
v.oddou

Ответы:

1

Краткий ответ:

Это выглядит достаточно хорошо?

  • Да, сохрани.

  • Нет - возиться с этим еще немного.

Длинный ответ:

Для получения точного реалистичного физического затенения требуется больше ресурсов графического процессора, чем это возможно, вам всегда придется прибегать к фальшивым вещам по той простой причине, что компьютер не может имитировать всю вселенную, даже весь спектр видимого света.

Это «сверхъестественная долина» затенения.

Не только из-за окружающего освещения и окклюзии, но, например, из-за внешней среды, как дневного, так и лунного света, имеется огромное количество света ультрафиолетового спектра, крошечная часть которого возвращается в видимый спектр различными материалами, в основном органическими. Различные типы люминесцентных ламп и HID также излучают большое количество ультрафиолета.

Эффект незаметен, но благодаря годам эволюции мозг инстинктивно обрабатывает его, поскольку это означало разницу между хорошей едой и, возможно, долгой мучительной смертью, поэтому, если что-то немного не в нашем мозгу, звучит сигнал «что-то не так» ,

Мультипликационные, нереалистичные и почти реалистичные, но намеренно отклоненные от нормы (например, Halo) художественные стили избегают этой проблемы.

Другая проблема заключается в том, что ни у двух людей нет ни одного присутствия рецептора RYGBL, ни кривой отклика, в то время как мониторы строго RGB и поэтому не могут идеально воспроизводить изображения для всех людей. (Красный, Желтый, Зеленый, Синий и Лума, см. Тетрахроматизм - http://en.wikipedia.org/wiki/Tetrachromacy )

Неважно, насколько усердно вы работаете, в этом будет «что-то не так» и есть место для улучшения, по крайней мере, для кого-то где-то.

И это одна из причин, почему существует так много моделей затенения.

Из-за всего этого хороший художник всегда заканчивает тем, что обманывает уровни освещения и светового отклика в окружающей среде, чтобы в какой-то степени достичь «достаточно хорошего» результата (он никогда не бывает идеальным), просто предоставьте им доступ к настройкам и обманите их путь к приятным результатам.

Стефан Хоккенхалл
источник
В этой области слишком много исследований, чтобы дать такой ответ.
Тара
@Tara, добро пожаловать в Stack Exchange. Я уверен, что со всеми этими «слишком большими исследованиями в этой области» вы потратите время, чтобы написать правильный «не ответ» и внести свой вклад в сообщество, а не просто комментарий в одну строку. На этой странице есть маленькая кнопка с надписью «Добавить другой ответ», если вы можете найти ее. Возможно, нужно немного исследований, чтобы найти его, но он есть.
Стефан Хоккенхалл
Ух, как пассивно-агрессивный. Я не сказал, что знаю лучше. Я сказал, что знаю, что есть куча исследований, которые пытаются решить эту проблему, не просто «просто делай что угодно», а касаясь человеческого мозга и смерти.
Тара
Я до сих пор не вижу нового ответа, кроме того, что «2014 год не отвечает» и однострочного, неконструктивного, активно-агрессивного комментария, размещенного 5 лет спустя. Вы на 100% можете принять все те исследования (из которых вы предоставили до сих пор нулевые ссылки, только однострочный комментарий), которые совершенно применимы к игровым движкам реального времени, и потратьте время, чтобы обобщить их в правильный ответ.
Стефан Хоккенхалл
Я хорошо, спасибо. Я уже отклонил вопрос и добавил свой первоначальный комментарий, чтобы объяснить, почему я это сделал, потому что людям не нравятся необъяснимые отрицательные голоса.
Тара