ДР12/Т5 - Glossy reflection BRDF

Glossy reflection BRDF

Добавете поддръжка на glossiness < 1 към eval()/spawnRay() методите на Reflection. За BRDF-а ще ползваме следната дефиниция:

BRDF_Glossy(x, ω, ω') := (cos(∠(reflect(ω), ω')) ≥ minCos ? S(minCos) : 0

Където константата minCos зависи от glossiness параметъра на Reflection по следния начин:

minCos := cos(2*atan(10.02 - 8*glossiness)),

а скалиращият коефициент S(minCos) зависи от minCos:

S(minCos) := 1 / (2*π*(1 - minCos)).

В eval(): намерете отражението на w_in спрямо x.norm, измерете косинуса от ъгъла между това отражение и w_out, и ако надвишава minCos, върнете reflColor умножен по скалиращя коефициент S(minCos).

В spawnRay(): копирайте кода от glossiness < 1 случая на Reflection::computeColor(). Вместо да генерираме много лъчи, ще генерираме един-единствен, по досегашния метод. Сметнете brdf-то по същия начин, както и в eval() (само тук не е нужно да правите проверката за minCos, тя директно следва от начина на генерирането на лъчите), а за pdf ползвайте S(minCos).

Внимавайте да не забравите да проверявате, дали генерираният "грапаво-отразен" лъч не задълбава под повърхността (както е в Reflection::computeColor).

Помислете какво следва да се прави с RF_GI_DIFFUSE флага на лъчите при spawnRay. Подсказка: при glossiness близко до 1, материалът се държи като огледало; при glossiness близко до 0, материалът се държи като Lambert, и добавянето на RF_GI_DIFFUSE ще намали количеството шум в сцената.

За тестове ползвайте smallpt.hexray, като зададете glossiness параметър на Reflection материала.

Примери (@ 1024 pathsPerPixel):