首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何解释在阴影射线中的镜面相互作用?

我如何解释在阴影射线中的镜面相互作用?
EN

Computer Graphics用户
提问于 2020-12-14 20:27:20
回答 1查看 80关注 0票数 1

我一直在使用PBRT,在Rust中实现我自己的版本。现在我正在研究阴影射线,看起来pbrt对镜面的行为没有任何解释,它把像完美玻璃一样的材料当作阴影不透明的东西。我决定尝试实现一个解释这种行为的版本,但是我没有看到任何视觉上的区别。忽略导致我的一些线程被卡住的错误,最上面的是我试图对镜面行为进行解释的尝试,而最下面的是一个“正常”的实现,它投射出一条射线来查看它是否击中了光线。

我看不出地面看上去有什么不同,我也不相信它应该看起来像一个完美的镜面玻璃模型。我的实现如下(它是用Rust表示的,所以我进行了注释,以了解一般的想法):

代码语言:javascript
复制
pub fn occlusion_intersects(&self, ray: &Ray, tmin: f64, tmax: f64, depth: i32) -> Option<HitRecord> {
    // find intersection with scene
    let ans = self.intersects(ray, tmin, tmax);
    // if no intersection was found, return None
    if ans.is_none() {
        return None
    }
    let mut ans = ans.unwrap(); // rust stuff, ignore this
    // compute the bsdf for the material
    Material::compute_scattering_default(&mut ans);
    // we only want to specular transmission or reflection
    let bsdf_type = BSDF_TRANSMISSION | BSDF_REFLECTION | BSDF_SPECULAR;
    // sample_f returns a new outgoing direction according to a bsdf that matches
    // one of the types above, or (0, 0, 0) if no matching bsdfs.
    let (wi, .. ) = ans.bsdf.sample_f(&ans.wo, bsdf_type);
    // if there was no specular bsdf or we've recursed too many times:
    if (wi == util::zero_vector() || depth == MAX_DEPTH {
        // then return the current intersection to check if it
        // hit the expected light object
        return Some(ans);
    }
    // otherwise make a new ray going in the new specular direction
    let new_ray = ans.spawn_ray(&wi);
    // and return that answer
    return self.occlusion_intersects(&new_ray, tmin, tmax, depth + 1);
}

作为参考,默认的实现是:

代码语言:javascript
复制
pub fn occlusion_intersects(&self, ray: &Ray, tmin: f64, tmax: f64, depth: i32) -> Option<HitRecord> {
    // return the first intersection, ignore all specular behavior
    return self.intersects(ray, tmin, tmax);
}

我的实现有什么问题吗?我有点猜到它将如何工作,但在评论中所写的逻辑对我来说是有意义的。

EN

回答 1

Computer Graphics用户

回答已采纳

发布于 2020-12-14 23:39:59

击中玻璃表面或类似物体的阴影射线会停止,因为没有从光源到阴影点的直接路径--有一块玻璃挡在路上。

对于完美的镜面传输/反射,您可以继续跟踪阴影射线,因为对于给定的传入向量,只有一个可能的输出矢量

这是行不通的,因为透射/反射会改变光线的方向。阴影射线大概是通过指向光源而产生的,但是在透射/反射之后,它很可能不会再击中光源了。

直接向光源发射光线的想法可以看作是一种抽样策略,目的是利用光线最有可能来自哪个方向的知识,并将你的光线放入这些方向。如果你是通过镜面相互作用而不是直接从光源接收光,你就不知道你应该从哪个方向取样。

我想,对于简单的情况,比如玻璃球体,你可以用代数方法解出一条光路,它会折射到光源上的某个点。然后你就可以沿着那条路追踪影子射线了。但是,当你进入像龙一样复杂的几何学中时,就没有现实的方法来计算光线将从哪个方向进入。

当镜面如玻璃或金属聚焦到漫射表面时,会产生腐蚀性。由于这个问题,腐蚀性是香草路径追踪的一个臭名昭著的痛点--没有办法知道在哪里集中你的样本,让你的射线击中光源,所以你能做的最好的就是从各个方向(或BRDF的样品),并希望足够多的射线找到一个光源。从技术上讲,路径跟踪可以正确地呈现焦散,但要做到这一点需要大量的样本。

更实际地说,这个问题可以通过使用光子映射(正是为了处理焦散问题而发明的)来解决,或者是一些像大都会和朋友这样的路径引导方法,它们可以“发现”焦散点,并动态地将样本集中在它们周围。

票数 1
EN
页面原文内容由Computer Graphics提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://computergraphics.stackexchange.com/questions/10493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档