Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Где я туплю? Спекулярная компонента по Фонгу для неосвещенных (отвернутых) поверхностей

Где я туплю? Спекулярная компонента по Фонгу для неосвещенных (отвернутых) поверхностей

Dmitry_MilkПостоялецwww11 янв. 20180:45#0
Делал свою модель освещения для специфических условий, отталкиваясь от Фонга.
Вроде все нормально получилось, но на неосвещенных/отвернутых поверхностях (угол между вектором на источник света и нормалью больше 90 градусов) заметил глюк освещения.

Разбор полетов показал, что "виновата" спекулярная компонента, коэффициент которой при некоторых углах обзора может оказываться больше нуля. Вроде бы понятно - на поверхностях с такой ориентацией освещение должно быть занулено (за исключением амбъента и эмиссии). Стал искать, где же я что-то потерял, когда переделывал исходный Фонг-алгоритм.

И ... не нашел!
Смотрю на исходный шейдер (конкретно этот взят с википедии)

+ Показать

и понимаю (то есть, не понимаю, как это так), что в нем эта проблема точно также должна проявляться!

А именно - max(dot(r, e), 0.0) на неосвещенной поверхности точно также как и у меня может оказаться больше нуля: предположим, что угол между l и n совсем чуть-чуть больше 90, тогда r хоть и смотрит "под поверхность", угол между r и e может быть меньше 90 градусов, если я смотрю на поверхность "вскользь". То есть, этот алгоритм тоже может давать ненулевой спекуляр на неосвещенной поверхности.

В каком месте у меня в ДНК ошибка? почему нигде не пишут о таком глюке (да и я его вроде не наблюдал, когда делал этот алгоритм напрямую).

Great V.Пользовательwww11 янв. 20181:35#1
Dmitry_Milk
1. Скрины
2. Обнуляй при (n,l) < 0
Были бы тени - не заметил бы.
innuendoПостоялецwww11 янв. 20189:47#2

vec4 Ispec = gl_FrontLightProduct[li].specular * pow(max(dot(r, e), 0.0), gl_FrontMaterial.shininess) * max(dot(n, l), 0.0);;
Dmitry_MilkПостоялецwww11 янв. 201812:07#3
Great V.
> 2. Обнуляй при (n,l) < 0

innuendo
> * max(dot(n, l), 0.0)

Да это понятно (кстати, все же правильнее * step(0, dot(n, l)), как Great V. предложил).

Меня просто смутило, почему этот момент не упоминается ни в одной из найденных мной статей по фонг-освещению (везде в лоб ищется отраженный вектор и берется pow от скалярного произведения нормализованных отражения и взора), и в результате, если освещение чисто фонговское без теней и самозатенения, то на теневой стороне действительно может вылезать спекуляр (скажем, заметно на шарах при невысоком shininess,  ярком specular-цвете и слабом ambient-цвете материала). Впрочем, возможно на это просто забивают на фоне тех недостатков чистого фонга, что проявляются из-за отсутствия честного замозатенения на сложных выпукло/вогнутых фигурах (правда вышеописанный глюк проявляется даже на шарах).

g-contПостоялецwww11 янв. 201813:38#4
Dmitry_Milk
я тоже обращал на это внимание но никогда не придавал значения. Всегда умножал спекуляр на NdotL и не парился.

/ Форум / Программирование игр / Графика

2001—2018 © GameDev.ru — Разработка игр