python手写光线追踪(不使用图形学API)——第二期

本文未经允许禁止转载
B站:https://space.bilibili.com/455965619
作者:Heskey0 / 赫斯基皇

二.specular材质和glass材质

在这个案例中,总共有4种材质

none
specular
glass
lambertian

注意:由于每种材质的复杂度不同,我会分开介绍这些材质中如何实现能量守恒

1.specular材质

对于specular材质,我们 不考虑折射,只考虑反射
(1) 我们首先对出射光的方向进行采样

def reflect(d, n):
    # d and n are both normalized
    ret = d - 2.0 * d.dot(n) * n   # d - 2*|d|*|n|*n*cos<d,n>(theta) = d - 2 |d|*cos(theta) * (n/|n|)
    return ret

请添加图片描述
代码的原理很简单,就是初中学习的 光的反射
(2) 计算pdf值
由于 只考虑反射,所以 pdf=1

2.glass材质

glass材质 既要考虑反射,也要考虑折射
(1) 我们首先对出射光的方向进行采样

对于 反射, 可按照上面specular材质的计算方式计算出出射光方向
对于 折射,我们需要利用高中学习的 光的折射

def refract(d, n, ni_over_nt):
    dt = d.dot(n)
    discr = 1.0 - ni_over_nt * ni_over_nt * (1.0 - dt * dt)     # discr:折射角的cos
    rd = (ni_over_nt * (d - n * dt) - n * ti.sqrt(discr)).normalized()
    return rd

请添加图片描述
注意: 不同于specular材质,我们还需要考虑一个问题:

入射光的能量 = 反射光的能量 + 折射光的能量。那么,拆分后的能量的关系是什么?

对于这个问题,我们需要运用 《PBRT》 第八章提到的菲涅尔反射的能量公式

我们先求出反射比r0

    r0 = (1.0 - eta) / (1.0 + eta)
    r0 = r0 * r0 

然后根据schlick近似公式计算brdf

r0 + (1 - r0) * ((1.0 - cos)**5)

我们回忆brdf的概念,brdf表示的是 表面反射微分辐射率和入射微分辐照度的比率辐射率通过单位面积单位立体角的辐射通量。而在glass材质中,反射光是集中的,不需要想漫反射那样去做半球采样,反射光就是位于单位立体角
所以,这里得到的brdf的值,就可以直接作为我们分配 反射能量折射能量的比率。所以我们就可以写出下列代码,利用random进行光照能量的分配

       refl_prob = schlick(cos, refr_idx)
       if ti.random() < refl_prob:     # 反射
           u = reflect(indir, normal)
       else:                           # 折射
           u = refract(indir, outn, ni_over_nt)

random的值小于这个比率的时候,我们按照反射处理
random的值大于这个比率的时候,我们按照折射处理

(2) 计算pdf
由于是glass材质,所以不需要进行半球采样,故pdf = 1



在下一章的lambertian材质中,我会详细介绍半球采样,最后别忘了逛逛作者的B站哦 https://space.bilibili.com/455965619

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值