我正在尝试用 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”是光线的方向。
最佳答案
图片看起来还不错。当我试图在我的场景中重现你的场景时 GLSL ray tracer我得到了这个结果:
正如您所看到的,除了不同的照明之外,它并没有太大的不同。我只是猜测了位置、大小、颜色、反射和折射系数,所以我的场景和你的不完全一样:
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
上往往会导致类似的伪影甚至在反射/折射球体的边缘产生噪声。这是我的相同引擎,但在 float
s 上:
如您所见,噪声更常出现在您的输出根本没有反射(reflect)的区域,这表明类似的原因...
但是我在您的图像中看到一些宽高比失真,就像您期望的方形窗口和 640x480 矩形相反,因此您没有或反宽高比校正。这会稍微弄乱转换的光线方向,并在反射/折射后进一步扭曲图像 ...
关于c++ - 在光线追踪中对球体进行荒谬的反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58258962/