Модель отражения Блинна – Фонга
Модель отражения Блинна-Фонга , также называемая модифицированной моделью отражения Фонга, представляет собой модификацию, разработанную Джимом Блинном для модели отражения Фонга . [ 1 ]
Блинн-Фонг — это модель затенения, используемая в конвейере фиксированных функций OpenGL и Direct3D (до Direct3D 10 и OpenGL 3.1) и выполняется на каждой вершине при ее прохождении по графическому конвейеру ; значения пикселей между вершинами по умолчанию интерполируются с помощью затенения Гуро , а не более ресурсоемкого с точки зрения вычислений затенения Фонга . [ 2 ]
Описание
[ редактировать ]
При затенении Фонга необходимо постоянно пересчитывать скалярное произведение. между зрителем ( V ) и лучом источника света ( L ), отраженным ( R ) от поверхности.
Если вместо этого вычислить средний вектор между векторами зрителя и источника света,
можно заменить на , где – нормализованная нормаль поверхности. В приведенном выше уравнении и оба являются нормализованными векторами, и является решением уравнения где — это матрица Хаусхолдера , отражающая точку на гиперплоскости, содержащую начало координат и имеющую нормаль
Это скалярное произведение представляет собой косинус угла, который составляет половину угла, представленного скалярным произведением Фонга, если V , L , N и R все лежат в одной плоскости. Это соотношение между углами остается приблизительно верным, когда векторы не лежат в одной плоскости, особенно когда углы малы. Поэтому угол между N и H иногда называют средним углом.
Учитывая, что угол между средним вектором и нормалью к поверхности, вероятно, будет меньше, чем угол между R и V, используемый в модели Фонга (если только поверхность не рассматривается под очень крутым углом, для которого он, вероятно, будет больше), и поскольку Фонг использует показатель степени можно установить такой, что ближе к предыдущему выражению.
Для поверхностей с фронтальным освещением (зеркальные отражения на поверхностях, обращенных к зрителю), приведет к появлению зеркальных бликов, которые очень точно соответствуют соответствующим отражениям Фонга. Однако, хотя отражения Фонга всегда имеют круглую форму на плоской поверхности, отражения Блинна – Фонга становятся эллиптическими, если на поверхность смотреть под крутым углом. Это можно сравнить со случаем, когда солнце отражается в море близко к горизонту или когда далекий уличный фонарь отражается от мокрого тротуара, где отражение всегда будет гораздо более протяженным по вертикали, чем по горизонтали. [ 3 ]
Кроме того, хотя ее можно рассматривать как приближение к модели Фонга, она создает более точные модели эмпирически определенных функций распределения двунаправленной отражательной способности , чем модель Фонга, для многих типов поверхностей. [ 4 ]
Эффективность
[ редактировать ]Блинн-Фонг будет быстрее, чем Фонг, в случае, когда зритель и свет считаются очень удаленными, например, приближающимися или находящимися в бесконечности. Это относится к направленному освещению и орфографическим/изометрическим камерам. В этом случае средний вектор не зависит от положения и кривизны поверхности просто потому, что средний вектор зависит от направления к положению зрителя и направления к положению источника света, которые индивидуально сходятся на этом удаленном расстоянии, следовательно, можно рассматривать средний вектор в этом случае постоянна. поэтому его можно вычислить один раз для каждого источника света, а затем использовать для всего кадра, или даже пока источник света и точка обзора остаются в одном и том же относительном положении. Чего нельзя сказать о методе Фонга, использующем вектор отражения, который зависит от кривизны поверхности и должен пересчитываться для каждого пикселя изображения (или для каждой вершины модели в случае вершинного освещения). В 3D-сценах с перспективными камерами такая оптимизация невозможна.
Примеры кода
[ редактировать ]Пример кода языка шейдинга высокого уровня
[ редактировать ]Этот пример на языке шейдинга высокого уровня представляет собой метод определения рассеянного и зеркального света по точечному источнику света. Пропускается структура света, положение поверхности в пространстве, вектор направления взгляда и нормаль к поверхности. Возвращается структура освещения;
Ниже также необходимо ограничить некоторые скалярные произведения до нуля в случае отрицательных ответов. Без этого свет, идущий от камеры, обрабатывается так же, как и свет, идущий к ней. При расчете зеркального отражения неправильный «ореол» света, отскакивающий от краев объекта в сторону от камеры, может выглядеть таким же ярким, как свет, отражающийся непосредственно в камеру.
struct Lighting
{
float3 Diffuse;
float3 Specular;
};
struct PointLight
{
float3 position;
float3 diffuseColor;
float diffusePower;
float3 specularColor;
float specularPower;
};
Lighting GetPointLight(PointLight light, float3 pos3D, float3 viewDir, float3 normal)
{
Lighting OUT;
if (light.diffusePower > 0)
{
float3 lightDir = light.position - pos3D; //3D position in space of the surface
float distance = length(lightDir);
lightDir = lightDir / distance; // = normalize(lightDir);
distance = distance * distance;
//Intensity of the diffuse light. Saturate to keep within the 0-1 range.
float NdotL = dot(normal, lightDir);
float diffuseIntensity = saturate(NdotL);
// Calculate the diffuse light factoring in light color, power and the attenuation
OUT.Diffuse = diffuseIntensity * light.diffuseColor * light.diffusePower / distance;
//Calculate the half vector between the light vector and the view vector.
float3 H = normalize(lightDir + viewDir);
//Intensity of the specular light
float NdotH = dot(normal, H);
float specularIntensity = pow(saturate(NdotH), specularHardness);
//Sum up the specular light factoring
OUT.Specular = specularIntensity * light.specularColor * light.specularPower / distance;
}
return OUT;
}
Пример кода языка шейдеров OpenGL
[ редактировать ]Этот образец языка шейдеров OpenGL состоит из двух файлов кода или шейдеров . Первый из них представляет собой так называемый вершинный шейдер и реализует затенение Фонга , которое используется для интерполяции нормали к поверхности между вершинами. Второй шейдер представляет собой так называемый фрагментный шейдер и реализует модель затенения Блинна-Фонга для определения рассеянного и зеркального света от точечного источника света.
Вершинный шейдер
[ редактировать ]Этот вершинный шейдер реализует затенение Фонга :
attribute vec3 inputPosition;
attribute vec3 inputNormal;
uniform mat4 projection, modelview, normalMat;
varying vec3 normalInterp;
varying vec3 vertPos;
void main() {
gl_Position = projection * modelview * vec4(inputPosition, 1.0);
vec4 vertPos4 = modelview * vec4(inputPosition, 1.0);
vertPos = vec3(vertPos4) / vertPos4.w;
normalInterp = vec3(normalMat * vec4(inputNormal, 0.0));
}
Фрагментный шейдер
[ редактировать ]Этот фрагментный шейдер реализует модель затенения Блинна – Фонга. [ 5 ] и гамма-коррекция :
precision mediump float;
in vec3 normalInterp;
in vec3 vertPos;
uniform int mode;
const vec3 lightPos = vec3(1.0, 1.0, 1.0);
const vec3 lightColor = vec3(1.0, 1.0, 1.0);
const float lightPower = 40.0;
const vec3 ambientColor = vec3(0.1, 0.0, 0.0);
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
const vec3 specColor = vec3(1.0, 1.0, 1.0);
const float shininess = 16.0;
const float screenGamma = 2.2; // Assume the monitor is calibrated to the sRGB color space
void main() {
vec3 normal = normalize(normalInterp);
vec3 lightDir = lightPos - vertPos;
float distance = length(lightDir);
distance = distance * distance;
lightDir = normalize(lightDir);
float lambertian = max(dot(lightDir, normal), 0.0);
float specular = 0.0;
if (lambertian > 0.0) {
vec3 viewDir = normalize(-vertPos);
// this is blinn phong
vec3 halfDir = normalize(lightDir + viewDir);
float specAngle = max(dot(halfDir, normal), 0.0);
specular = pow(specAngle, shininess);
// this is phong (for comparison)
if (mode == 2) {
vec3 reflectDir = reflect(-lightDir, normal);
specAngle = max(dot(reflectDir, viewDir), 0.0);
// note that the exponent is different here
specular = pow(specAngle, shininess/4.0);
}
}
vec3 colorLinear = ambientColor +
diffuseColor * lambertian * lightColor * lightPower / distance +
specColor * specular * lightColor * lightPower / distance;
// apply gamma correction (assume ambientColor, diffuseColor and specColor
// have been linearized, i.e. have no gamma correction in them)
vec3 colorGammaCorrected = pow(colorLinear, vec3(1.0 / screenGamma));
// use the gamma corrected color in the fragment
gl_FragColor = vec4(colorGammaCorrected, 1.0);
}
Цвета окружающий цвет , диффузный цвет и SpecColor не должен иметь гамма-коррекцию . Если это цвета, полученные из файлов изображений с гамма-коррекцией ( JPEG , PNG и т. д.), перед работой с ними необходимо линеаризовать их, что делается путем масштабирования значений канала до диапазона [0, 1] и повышения их до значение гаммы изображения, которое для изображений в цветовом пространстве sRGB можно принять равным примерно 2,2 (хотя для этого конкретного цветового пространства простое степенное соотношение является лишь приближением фактического преобразования ). Современные графические API имеют возможность автоматически выполнять эту гамма-коррекцию при выборке из текстуры или записи в фреймбуфер . [ 6 ]
См. также
[ редактировать ]- Список распространенных алгоритмов затенения
- Модель отражения Фонга для соответствующей модели Фонга
- Гамма-коррекция
- Зеркальная подсветка
Ссылки
[ редактировать ]- ^ Джеймс Ф. Блинн (1977). «Модели отражения света для компьютерно синтезированных изображений». Материалы 4-й ежегодной конференции «Компьютерная графика и интерактивные технологии» . стр. 192–198. CiteSeerX 10.1.1.131.7741 . дои : 10.1145/563858.563893 . ISBN 9781450373555 . S2CID 8043767 .
- ^ Шрейнер, Дэйв; Рабочая группа Khronos OpenGL ARB (2010 г.). «Математика освещения». Руководство по программированию OpenGL: официальное руководство по изучению OpenGL, версии 3.0 и 3.1 (7-е изд.). Pearson Education, Inc., стр. 240–245. ISBN 978-0-321-55262-4 .
- ^ Крус, Кристофер (2014), Волновая модель и модель плавсредства для моделирования состояния моря , Университет Линчёпинга , стр. 97
- ^ Нган, Эдди; Дюран, Фредо; Матусик, Войцех (2004). «Экспериментальная проверка аналитических моделей BRDF» . Эскизы ACM SIGGRAPH 2004 - SIGGRAPH '04 . АКМ Пресс. п. 90. дои : 10.1145/1186223.1186336 . ISBN 1-59593-836-2 . S2CID 9259363 . Проверено 23 апреля 2019 г.
- ^ «Пример WebGL: затенение Фонга / Блинна Фонга» . www.mathematik.uni-marburg.de . Проверено 13 сентября 2019 г.
- ^ Фреймбуфер khronos.org