折射radiance推導
平面上各符号定義如下:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSPJRVT5VkeaVnRXF2c5w2YwZkMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLyATO0ETOzATM3EjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
目标:求出Lt和Li的關系,即ωt方向的出射光的radiance。
定義Fresnel反射是Fr。
入射的flux是Φi,反射出去的flux就是Φo = FrΦi,
根據能量守恒,折射出去的flux就是Φt = (1 - Fr)Φi。
根據入射的radiance定義:
Φi = Li cosθi dA dωi。
Φt = Lt cosθt dA dωt。
Lt cosθt dA dωt = (1 - Fr)Li cosθi dA dωi
由dω = sinθdθdφ,上式兩邊展開得到:
Lt cosθt sinθtdθtdφt = (1 - Fr)Li cosθi sinθidθidφi
對snell's law兩邊求導:
ηi cosθi dθi = ηt cosθt dθt
cosθi dθi / cosθt dθt = ηt / ηi。
代入Lt的公式得到:
最後再根據sinθi/sinθt = ηt/ηi,φi = φt + π,得到:
求折射ωt
首先要求出ωt的方向,
如上圖:已知的是ωo,ηi和ηt,求未知的ωt。
是以隻需要求出ωt//和ωt⊥就可以了。
用球面坐标表示ωt⊥:
ωo⊥ = (sinθocosφo, sinθosinφo, 0)
ωt⊥ = (sin(π - θt)cosφt, sin(π - θt)sinφt, 0) = (sinθtcosφt, sinθtsinφt, 0)
= (ηi/ηt sinθo cos(φo + π), ηi/ηt sinθosin(φo + π), 0)
= (-ηi/ηt sinθo cosφo, -ηi/ηt sinθosinφo, 0)
= -ηi/ηtωo⊥
ωo⊥ = ωo - (n·ωo)n
ωt⊥ = -ηi/ηt(ωo - (n·ωo)n)
ωt//和N平行且方向相反,N是歸一化向量,是以
ωt// = -||ωt//||N。
由于||ωt⊥|| = sinθt
最後:
代碼分析
兩種情況:
法線正向的面是etaA,反向的面是etaB,代碼如下:
bool entering = CosTheta(wo) > 0;
Float etaI = entering ? etaA : etaB;
Float etaT = entering ? etaB : etaA;