|
Главная
Статьи
Ссылки
Скачать
Скриншоты
Юмор
Почитать
Tools
Проекты
Обо мне
Гостевая
Форум
|
В 2012 Brent Burley из Walt Disney Animation Studios опубликовал оказавшую заметное влияние работу, описывающую BRDF, которая применяется в Disney. В этой работе была описана диффузная модель, заметно отличающаяся от классической модели Ламберта.
В этой модели использовалась неровность поверхности - оказалось, что когда направление почти касается поверхности, то отражательная способность материала сильно зависит от неровности. И эта зависимость довольно хорошо описывается коэффициентом Френеля.
Для новой модели была введена следующая функция (фактически это приближение Шлика для коэффициента Френеля)
\[F_D(\omega)=1 + (F_{D90}-1)(1-(n,\omega))^5\]
Коэффициент \(F_{D90}\) задается следующей формулой: \[F_{D90}=\frac{1}{2} + 2 \cdot roughness \cdot (h,\omega_{out})^2\]
И, тогда, итоговая BRDF задается следующей формулой:
\[f_{baseDiffuse}=\frac{baseColor}{\pi}F_D(\omega_{in})F_D(\omega_{out})\]
Через \(\omega_i\) и \(\omega_o\) обозначены углы между нормалью \(n\) и векторами на источник света \(l\) и на камеру \(v\).
Ниже приводится изображение, полученное при помощи данной модели
Рис.
Рис. Диффузное освещение Lambert (слева) по сравнению с Burley (справа)
Шейдер для этой модели очень прост, ниже приводится только фрагментный шейдер.
#version 330 core
in vec3 n;
in vec3 l;
in vec3 v;
in vec3 h;
out vec4 color;
const vec4 clr = vec4 ( 0.7, 0.3, 0.1, 1.0 ) * 2;
const float ka = 0.2;
const float kd = 0.8;
uniform float roughness = 0.9;
float sqr ( in float x )
{
return x*x;
}
// fast computation of pow (x, 5)
float pow5 ( in float x )
{
float x2 = x * x;
return x2 * x2 * x;
}
float fd ( in float fd90, in vec3 n, in vec3 omega )
{
return 1 + (fd90 - 1) * pow5 ( 1 - abs ( dot ( n, omega ) ) );
}
void main(void)
{
vec3 n2 = normalize ( n );
vec3 l2 = normalize ( l );
vec3 h2 = normalize ( h );
vec3 v2 = normalize ( v );
float hv = dot ( h2, v2 );
float FD90 = 0.5 + 2.0 * roughness * sqr ( hv );
color = clr / 3.1415926 * fd ( FD90, n2, l2 ) * fd ( FD90, n2, v2 ) * abs ( dot ( n2, l2 ) );
}
Кроме того, было предложено дополнение, моделирующее подповерхностное рассеивание без дополнительный проходов рендеринга на основе модели Lommel-Seeliger:
\[ f_{subsurface} = \frac{1.25 \cdot baseColor}{\pi} \left( F_{SS}(\omega_{in}) F_{SS}(\omega_{out}) \left (\frac{1}{|(n,\omega_{in})| + |(n,\omega_{out})|} - 0.5 \right) + 0.5 \right) |(n,\omega_{out})| \]
Здесь
\[ F_{SS90} = roughness \cdot (h, \omega_{out})^2 \]
\[F_{SS}(\omega) = (1 + (F_{SS90} - 1)(1 - |(n,\omega)|)^5\]
Итоговая диффузная BRDF задается следующей формулой:
\[f_{dissuse} = (1-subsurface) \cdot f_{baseDiffuse} + subsurface \cdot f_{subsurface}\]
Рис. Освещение с учетом подповерхностного рассеивания
Соответствующий фрагментый шейдер.
#version 330 core
in vec3 n;
in vec3 l;
in vec3 v;
in vec3 h;
out vec4 color;
const vec4 clr = vec4 ( 0.7, 0.3, 0.1, 1.0 ) * 2;
const float ka = 0.2;
const float kd = 0.8;
uniform float roughness = 0.9;
uniform float subsurface = 0.3;
float sqr ( in float x )
{
return x*x;
}
// fast computation of pow (x, 5)
float pow5 ( in float x )
{
float x2 = x * x;
return x2 * x2 * x;
}
float fd ( in float fd90, in vec3 n, in vec3 omega )
{
return 1 + (fd90 - 1) * pow5 ( 1 - abs ( dot ( n, omega ) ) );
}
void main(void)
{
vec3 n2 = normalize ( n );
vec3 l2 = normalize ( l );
vec3 h2 = normalize ( h );
vec3 v2 = normalize ( v );
float hv = dot ( h2, v2 );
float FD90 = 0.5 + 2.0 * roughness * sqr ( hv );
float FSS90 = roughness * sqr ( hv );
float fBaseDiffuse = 1.0 / 3.1415926 * fd ( FD90, n2, l2 ) * fd ( FD90, n2, v2 ) * abs ( dot ( n2, l2 ) );
float fSubsurface = 1.0 / 3.1415926 * ( fd ( FSS90, n2, l2 ) * fd ( FSS90, n2, v2 ) * (1.0 / ( abs ( dot ( n2, l2 ) ) + abs ( dot ( n2, v2 ) ) ) - 0.5 ) + 0.5 );
float f = (1 - subsurface) * fBaseDiffuse + subsurface * fSubsurface;
color = clr * f;
}