понедельник, 9 апреля 2012 г.

Lightning Models

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

Lambert Lighthing Model

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

I = max(0, dot(N, L));

где:
I - итоговый коэффициент затенения,
N - нормаль полигона в мировом пространстве,
L - направление света.

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

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
   const float3 lightDir = float3(1, 0, 1);
   float LdotN = max(0.0, dot(lightDir, input.Normal));
   return float4(0.5, 0.5, 0.5, 1) * LdotN;
}



Исходный код к статье  lambert.zip



Phong Lightning Model

Следующая модель освещения - это бликовая модель освещения Фонга.
В отличии от модели Ламберта, она не только учитывает нормали, но так-же учитывает отражение света по отношению к наблюдателю.
Код пиксельного шейдера приведен ниже:

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    const float3 lightDir = float3(1, 0, 1);
    const float3 viewDir = normalize(float3(0, -75, 0));
    float LdotN = dot(lightDir, input.Normal);
    float3 Reflection = normalize(2.0f * input.Normal * LdotN - lightDir);
    float RdotV = max(0.0, dot(Reflection, viewDir));
    float SpecExp = 50;
    float4 SpecColor = float4(1, 1, 1, 1);
    float4 TotalSpecular = SpecColor * pow(RdotV, SpecExp);
    return float4(0.5, 0.5, 0.5, 1) * saturate(max(0.0, LdotN)) + TotalSpecular;
}

Исходный код к статье  PhongModel.zip


Normal + Specular Mapping


 Совмещая бликовую и диффузную модели освещения, можно получать более сложные эффекты. Одним из таких эффектов является Normal Mapping. Мы уже знаем что для расчета диффузного освещения нужно использовать дот продукт векторов нормали и направления света. Нормали обычно хранятся в самой модели. Можно сказать, что для одного полигона
(треугольника) нормаль расчитывается как среднее арифметическое из трех нормалей вершин полигона. Соответственно, детализация объекта ограничивается сложностью модели. Для того что-бы придать модели более детализированный вид, был придуман следующий способ. Художники сохраняли нормали в текстуру, и после текстурирования такой текстурой модели, нужно считать нормаль из нее и использовать для расчета освещения. В результате, можно добиться высокой визуальной сложности моделей, не затрагивая ее сетки.



Реализацию этой техники можно найти здесь SpecularBump.zip

Комментариев нет:

Отправить комментарий

Physically Based Rendering