c++ - 在光线追踪中对球体进行荒谬的反射

标签 c++ graphics 3d raytracing

我正在尝试用 C++ 实现一个简单的基于 CPU 的 Raytracer。 但是在场景中实现反射时,我得到了一些荒谬的结果,反射没有覆盖我试图获得反射的整个对象。我已附上图片以供引用。

这是我正在使用的反射算法。

//reflected ray
                  Vec3 ref =(dir - 2*((dir.dot(Normal))*Normal)).normalized();
                  Vec3 reflect_orig;

                  if(depth < MAX_DEPTH && figurelist[figureHit]->reflectness>0.0f ){
                      if(ref.dot(Normal)<0.0f){

                          reflect_orig = p0 - (Normal*0.001f);

                      }
                      else{
                          reflect_orig = p0 + (Normal*1e-3f);
                      }
                      reflectcolour = reflectcolour+ray_trace(reflect_orig,ref,depth+1);
                      return Pixelcolour = reflectcolour;
                  }
                  else{
                     Pixelcolour = diffuse+specular;
                  }

其中“dir”是光线的方向。

The output image

最佳答案

图片看起来还不错。当我试图在我的场景中重现你的场景时 GLSL ray tracer我得到了这个结果:

result

正如您所看到的,除了不同的照明之外,它并没有太大的不同。我只是猜测了位置、大小、颜色、反射和折射系数,所以我的场景和你的不完全一样:

ray.beg();
//                 r   g   b rfl rfr   n                               x     y     z   rx   ry   rz
ray.add_material(0.8,0.8,0.6,0.0,0.0,_n_glass); ray.add_box       (  0.0,  0.0,-10.0,10.0,10.0, 0.1);
ray.add_material(0.8,0.8,0.6,0.0,0.0,_n_glass); ray.add_box       (  0.0,  0.0,+10.0,10.0,10.0, 0.1);
ray.add_material(1.0,0.1,0.1,0.0,0.0,_n_glass); ray.add_box       (-10.0,  0.0,  0.0, 0.1,10.0,10.0);
ray.add_material(0.1,1.0,0.1,0.0,0.0,_n_glass); ray.add_box       (+10.0,  0.0,  0.0, 0.1,10.0,10.0);
ray.add_material(0.8,0.6,0.8,0.0,0.0,_n_glass); ray.add_box       (  0.0,-10.0,  0.0,10.0, 0.1,10.0);
ray.add_material(0.8,0.6,0.8,0.0,0.0,_n_glass); ray.add_box       (  0.0,+10.0,  0.0,10.0, 0.1,10.0);
//                 r   g   b rfl rfr   n                               x     y     z   r
ray.add_material(0.7,0.0,0.0,0.0,0.0,_n_glass); ray.add_sphere    (+ 1.5,- 1.5,+ 0.5,1.5);
ray.add_material(0.0,0.0,0.7,0.8,0.0,_n_glass); ray.add_sphere    (- 1.5,+ 1.5,- 0.5,1.5);
ray.end();

我使用这些索引:

const GLfloat _n_glass=1.561;
const GLfloat _n_vacuum=1.0;

蓝色球体边缘的失真(不存在反射)可能是由于精度低造成的,您是否使用了 double?我不知道你使用的是什么库,但 Vec3 通常意味着只有 float 尝试 dVec3 或者什么......问题可能与此有关:

在纯 float 上往往会导致类似的伪影甚至在反射/折射球体的边缘产生噪声。这是我的相同引擎,但在 floats 上:

float noise

如您所见,噪声更常出现在您的输出根本没有反射(reflect)的区域,这表明类似的原因...

但是我在您的图像中看到一些宽高比失真,就像您期望的方形窗口和 640x480 矩形相反,因此您没有或反宽高比校正。这会稍微弄乱转换的光线方向,并在反射/折射后进一步扭曲图像 ...

关于c++ - 在光线追踪中对球体进行荒谬的反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58258962/

相关文章:

c++ - 在tpp文件中声明模板成员函数

c++ - 循环显示图像 vector

algorithm - 基本空间雕刻算法

c# - AxisAngleRotation3D.Axis 属性的真正含义是什么?

java - Java 中的 3D 转换

c++ - 使用 json c++ 的输出在字段中获取奇怪的字符

c++ - 如何禁用 QTableView 的 control+A 快捷方式并防止全选选项?

Java `DisplayMode` 在 Linux 上的位深度是 `-1`

swing - 绘制汽车时出现黑屏或找不到符号错误

algorithm - 与第一个生命点已知的射线盒相交