建议在我的RayTracer上找到导致渲染伪像的原因

时间:2018-08-23 22:28:24

标签: c++ graphics raytracing

您好,我最近发送了我的RayTracer来渲染.obj模型(该模型具有对应的.mtl,尽管该模型的很大一部分似乎可以正确渲染,但其中很大一部分也不能:

iron-main-512.jpg

我想要的是关于如何找出上面出现的工件的原因的建议。

一些评论:据我所知,这些对象模型期望使用Phong阴影模型,但我没有使用它,而是只计算了漫反射颜色,复制了随附的.mtl文件中指定的漫反射颜色分量

也许我的主要障碍是所涉及的大量三角形。如果我有几百个三角形,那么很容易一直删除它们的一部分,直到我弄清楚三角形的渲染不正确。但是我有很多(在这种情况下超过200000),这完全不切实际。加上渲染它们的时间太长,以至于视觉检查是有问题的(我尚未实现加速结构)

另一个观察结果是.mtl文件中有几个重复的材料。看这里:

#Max2Mtl Version 4.0 Mar 10th, 2001
#
newmtl darksilver
Ka  0.0 0.0 0.0
Kd  0.8 0.8 0.8
Ks  0.2 0.2 0.2
d  1.0
Ns  10.0
illum 2
#
newmtl red
Ka  0.0 0.0 0.0
Kd  0.4 0.1 0.1
Ks  0.5 0.5 0.5
d  1.0
Ns  10.0
illum 2
#
newmtl gold
Ka  0.0 0.0 0.0
Kd  0.6 0.5 0.1
Ks  0.5 0.5 0.5
d  1.0
Ns  10.0
illum 2
#
newmtl silver
Ka  0.0 0.0 0.0
Kd  0.8 0.8 0.8
Ks  0.2 0.2 0.2
d  1.0
Ns  10.0
illum 2
#
newmtl lambert1
Ka  0.4 0.4 0.4
Kd  0.4 0.4 0.4
Ks  1.0 1.0 1.0
d  1.0
Ns  4.8
illum 2
#
newmtl yellow
Ka  1.0 1.0 1.0
Kd  1.0 1.0 1.0
Ks  0.2 0.2 0.2
d  1.0
Ns  10.0
illum 2
#
newmtl black
Ka  0.0 0.0 0.0
Kd  0.8 0.8 0.8
Ks  0.2 0.2 0.2
d  1.0
Ns  10.0
illum 2
#
# Multi/Sub Material__91 (2) to come 
#
newmtl red
Ka  0.0 0.0 0.0
Kd  0.4 0.1 0.1
Ks  0.5 0.5 0.5
d  1.0
Ns  10.0
illum 2
#
newmtl 14_-_Default
Ka  0.0 0.2 0.9
Kd  0.0 0.2 0.9
Ks  0.9 0.9 0.9
d  1.0
Ns  0.0
illum 2
#
# Multi/Sub Material__91 done 
#
# Multi/Sub Material__58 (2) to come 
#
newmtl red
Ka  0.0 0.0 0.0
Kd  0.4 0.1 0.1
Ks  0.5 0.5 0.5
d  1.0
Ns  10.0
illum 2
#
newmtl 14_-_Default
Ka  0.0 0.2 0.9
Kd  0.0 0.2 0.9
Ks  0.9 0.9 0.9
d  1.0
Ns  0.0
illum 2
#
# Multi/Sub Material__58 done 
#
# EOF

可以看出,红色和14 _-_ Default在文件中出现了3次(不知道原因,但如果有人知道可能的解释,我想听听)。可能与问题有关吗?

另一种可能与我的三角剖分算法有关。 在以下两个文件中,我注意到了视觉伪影,如下图所示:

car-2700_X-1000_Y-3000_Z.jpg cesna2.jpg

实际上,我什至不确定汽车图像中是否有伪影。我认为可能存在伪影的原因是缺少轮胎,而车轮上却有奇怪的东西。我意识到几乎所有汽车的颜色都是相同的,但这可能是几乎所有材料(包括大多数透明材料)具有相同的扩散成分的结果。

但是,第二张图像没有使用.mtl文件,可以清楚地看到飞机下面有几个不需要的三角形,机身上有一些小的黑点(一个是可见的黑色三角形),还有几个“蓝色” ”在其背面的孔上。

所以我决定发布我的三角剖分算法,该算法选择多个顶点面并从中生成三角形:

int color;
int number=0;
cout << "mat_name: " <<  mat_name << endl;
for (int i=0; i<mtl_material_container.size(); i++)
   if (mat_name==mtl_material_container[i].material_name)
      color=i;
Vec3f tmp [faces.size()];
for (int i=0; i<faces.size(); i++) 
   tmp [i] = vertices [faces[i] -1];    
Triangle triangle (tmp[0],tmp[1],tmp[2],color);
triangle_container.push_back (triangle);
for (int i=0; i<faces.size()-3; i++) {
   //Triangle triangle (tmp[i],tmp[i+2],tmp[i+3],0);
   Triangle triangle (tmp[i],tmp[i+2],tmp[i+3],color);
   triangle_container.push_back (triangle);
}

无论如何,这些是我至今可以想到的。渴望接受任何调试建议。感谢您的宝贵时间。

1 个答案:

答案 0 :(得分:0)

以下是一些提示:

为确保您应正常使用网格或三角形而不是光线跟踪来渲染网格,只是为了确定问题是否出在网格加载器或光线跟踪本身中。以后也会有用。当您也具有正常渲染几何图形的能力时,您可以渲染测试射线以检查射线追踪的正确性(检查放置网和对象的大小,检查折射和反射等)。查看此处,我的ray跟踪器和调试渲染屏幕截图的外观(出于某些启发):

obj中的索引1开始,而不是0,许多菜鸟都忘记了这些,但看来您处理得当。只需确保您没有在代码中的两个位置上对此进行更正(例如也将顶点推入点表中)。

我对三角剖分的方式略有不同:

for (i=2;i<pos.num;i++) obj.addface(pos[0],pos[i-1],pos[i]);

它的代码更少,更直接(类似于GL_TRIANGLE_FAN)。 我不确信您的三角剖分方法对于4点以上的人来说是正确的,但懒得在纸上画出草图以进行验证。要么使用地雷方法,要么仅渲染3个点面,然后查看越野车三角形是否消失。

无论如何,您可以在这里与我的 Wavefront obj C ++加载程序进行比较:

我不认为这是一个材料问题(除非三角形编码了某些照明效果或粒子方向或其他任何形式),为什么不仅渲染单个材料三角形以查看特定材料是否仅包含错误三角形和其余都可以吗?如果是这种情况,则可以识别受感染材料的 mtl 属性,以便您稍后可以自动忽略它们。