Aptarimas:Šviesos laužimas

Page contents not supported in other languages.
Iš Wikibooks.

Pavyzdžio gale ne visko gal reikia[keisti]

  • Duotas trikampis, kurio taškai (viršūnės) yra A(3; 4; 5), B(10; 13; 17), C(2; 6; 1). Rasime vektorius AB ir AC.
AB={10-3; 13-4; 17-5}={7; 9; 12};
AC={2-3; 6-4; 1-5}={-1; 2; -4}.
Sudauginę vektorius AB ir AC vektorine vektorių sandauga (cross product) gausime vektorių inNormal (gausime trikampio normalės vektorių).
Vektorius viewVec yra viewVec={5; 8; 4}. Rasime vektorių g (vektorius g guli ant trikampio ABC plokštumos, nes vektorius inNormal yra status trikampio plokštumai).
g=cross(viewVec, inNormal)=
Suprastinus vektorius g lygus g={24; -71; 112}.
Toliau rasime vektorių y.
y=cross(g, inNormal)=
Net iš normalizuotų vektorių vektorinė vektorių sandauga neduoda normalizuoto vektoriaus (jei duoti normalizuoti vektoriai a={0.8; 0.6; 0} ir b={-0.8; 0.6; 0}, tai z koordinatė vektoriaus c=cross(a, b) lygi k(0.8*0.6-(-0.8)*0.6)=k(0.48+0.48)=0.96 k, kas ne lygu 1 k). Todėl reikia normalizuoti vektorių y.
Normalizuosime vektorių viewVec={5; 8; 4}.
Toliau normalizuosime vektorių inNormal={-60; 16; 23}.
Padarę skaliarinę vektorių sandaugą gausimę kosinusą kampo tarp vektoriaus viewVec ir vektoriaus inNormal.
cosine = dot(viewVec, inNormal)=
Randame sinusą
sine = sqrt(1 - cosine * cosine) =
Jei kampas tarp dviejų vektorių 0 laipsnių, tai kosinusas lygus 1, o sinusas lygus 0. O jei kampas tarp dviejų vektorių lygus 90 laipsnių, tai kosinusas lygus 0, o sinusas lygus 1.
Funkcija saturate(x) yra ekvivalenti funkcijai clamp(0, 1, x). Funkcija clamp(0, 1, x) duoda reikšmes tik nuo 0 iki 1. Jei x daugiau už 1, tada vis tiek funkcija clamp(0, 1, x) grąžins 1.

Ir jeigu x mažiau už 0, tai vis tiek bus 0. Funkcija saturate duoda reikšmes intervale nuo 0 iki 1. O didesnias arba mažesnes reikšmes paverčia į 1 arba 0.

// Note that the saturate(x) function is equivalent to
// using clamp(0,1,x).
Jei šitą kodą
float3 x = -inNormal;
float3 y = normalize(cross(cross(viewVec, inNormal), inNormal));
Out.Refract = x * cosine2 + y * sine2;
pakeisti tokiu kodu
float3 x = -inNormal;
float3 y = normalize(cross(cross(viewVec, inNormal), inNormal));
Out.Refract = x * cosine + y * sine;
tai tada bus gautas viewVec arba -viewVec vektorius (sunku pasakyti ar reikalingas minusas ar ne). Tai yra
\\ Out.Refract = x * cosine + y * sine = viewVec
arba
\\ Out.Refract = x * cosine + y * sine = -viewVec
Vektorius x = -inNormal. O vektorius y yra projekcija vektoriaus viewVec (arba vektoriaus -viewVec, neaišku ar reikia to minuso) ant trikampio plokštumos.
Normalizuosime vektorių
Galimas dalykas, kad "Out.Refract" vektorių reikia normalizuoti. Nes jei viewVec normalizuotas, tai tuomet ir Refract vektorius turėtų būti normalizuotas (sudėjus du normalizuotus vektorius negaunamas normalizuotas vektorius, kaip pavyzdžiui {1; 0}+{0; 1}={1; 1}, o ne {0,7071; 0,7071}). Paskutines kodo eilutes galima būtų perrašyt taip:
float3 x = -inNormal;
float3 y = normalize(cross(cross(viewVec, inNormal), inNormal));
Out.Refract = normalize(x * cosine2 + y * sine2);
Bet turbut nereikia normalizuoti Refract vektoriaus, nes tam skirti cosine2 ir sine2, kad subalansuotų vektorių x ir y ilgius. Kiek sutrumpėja kiekvienos koordinatės vektoriaus ilgis, tiek procentų sutrumpėja ir bendras vektoriaus ilgis. Jeigu, pavyzdžiui, vienetinio vektorius a={0.7071; 07071} ilgis ||a||=1, tai padaugintas iš 0.7071 bus 0.5, o jo ilgis bus Iš to matosi, kad jeigu sine=0.7071, o cosine=0.7071, tai padaugintas vektorius a iš, tarkim, cosine sutrumpės per puse (kaip ir kiekviena jo koordinatė).
Jei duotas vektorius a={0.7071; 07071} ilgio ||a||=1, tai padaugintas iš kosinuso 0.7071 (kai sinusas irgi 0.7071) vektoriaus a ilgis turėtų būti kosinusas (0,7071). Bet taip nėra, o vektoriaus ilgis tampa a=0.5, nes tada a vektorius tampa A={0.7071; 07071}*0.7071={0.5; 0.5}. Ilgis vektoriaus A apskaičiuojamas Pasirodo pamiršta ištraukti šaknį.
Vektoriai x=-inNormal ir y=normalize(cross(cross(viewVec, inNormal), inNormal)) vienas kitam stati. Jei cosine=0.7071 ir sine=0.7071. O vektorius x={0.7071; 0.7071} ir y={-0.7071; 0.7071}. Tai padauginus x ish cosine ir y ish sine gausime x={0.5; 0.5} ir y={-0.5; 0.5}. O sud4jus x ir y gausime {0; 1}. Gavome normalizuotą vektorių ({0; 1)).