《 Ray Tracing from the Ground Up》官方代码的潜在的纹理映射问题

最近,小编在《 Ray Tracing from the Ground Up》的基础上尝试实现BART的动画。写过一篇博文来总结初期实现的结果:
“在《 Ray Tracing from the Ground Up》的基础上实现BART的动画”
https://blog.csdn.net/libing_zeng/article/details/80632942

文中提到两个遗留问题:
问题一:为什么可以透过物体看到被物体挡住的另一个物体?
问题二:toycar上的license图片怎么显示全白?

在小编看来,这两个问题不是太好查。尤其是“问题二”,小编之前也提到过,本人曾经花了整整一天的时间,也没有解决这个问题。后来,由于某种原因,在小编看来,非常有必要解决这些问题。

后面问题解决之后,发现整两个问题其实是同一个问题:物体的纹理受到后面物体的影响。

查问题的过程无非是:隔离存在问题的物体;降低采样率;减少像素总数;找到问题出现的临界点;对比有无“后面物体”时临界点附近相关数据(撞击点及其距离、法向量、纹理坐标)的变化;等等

发现“后面物体”的存在对最终的纹理坐标产生了影响。进一步检查,发现是Compound::hit()和World::hit()中没有保存有效的纹理坐标。当物体撞击到“后面物体”时,会将“后面物体”上的撞击点及其距离、法向量、纹理坐标写到sr中。在Compound::hit()和World::hit()中根据距离判断撞击点有效性时,会舍弃“后面物体”上的这个撞击点数据,用原先保存的撞击点及其距离、法向量覆盖“后面物体”的sr中的数据。但是,由于Compound::hit()和World::hit()中没有保存纹理坐标的数据,所以,“后面物体”的sr中的纹理坐标还是“后面物体”上的撞击点的数据。之所以能够透过物体看到被物体挡住的另一个物体,正式因为这个区域的纹理坐标错误地使用了“后面物体”撞击点处的纹理坐标。

问题查到这个程度,改起来就简单了:
(在这两个函数中添加如下代码即可)
这里写图片描述

这里写图片描述

分析一下,为什么这个问题会长期隐藏在代码中:
1,官方的代码是按章节释放的,然后,我们按章节将代码合并起来。在纹理映射章节,书上告诉我们要添加哪些文件/函数,然而对于原有文件/函数中需要修改的地方可能未能面面俱到(也有可能是小编自己忽略了)。这种情况下,如果产生编译错误,我们还能及时发现被遗漏的地方。如果只是数据的存储/更新,问题就不容易被发现。
2,这个“纹理坐标更新”问题之所以没能及时被发现,还要个原因是:书上该章节使用的都是简单场景;对于mesh的纹理映射只是点了一下;过程纹理中更难暴露这个问题。

各位童鞋,如果也在学习《Ray Tracing from the Ground Up》,及时改了这个问题哈。因为,这个导致的问题,查起来确实费劲。后面贴几张修改这个问题前后渲染的Kitchen场景的图片:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/libing_zeng/article/details/80660545