这里是渲染具有50/50理想反射混合的对象的渲染。并以每像素80个样本的理想漫射度:
即将结束。特别是腿上那些怪异的底部高光,向左延伸得最远。我有一种很强烈的感觉,我实现错误。
这是路径跟踪部分的伪实现。它使用显式光采样。基于smallpt路径跟踪器。
rayColor(ray r, depth, int E=1)
{
if(r doesn't hit triangle)
return 0
if(r hit is a light)
{
if(E)
return light_emission
else
return 0
}
vector x = r.origin + r.direction*t // x is point where r hit tri
vector n = normal where ray hit triangle
n.normalize()
vector nl = n.dot(r.d) < 0 ? n : n*(-1) // properly orient normal
if(++depth > 5) return 0 // max bounces
float triangle_area = area of emitting triangle
vector x_light_random = random point on emitting triangle
vector light_normal = normal of emitting triangle
vector d = x_light_random = x_converted;
if(light_normal.dot(d) > 0) light_normal *= -1; // make it emit
// both sides
object_normal.normalize();
light_normal.normalize();
BRDF = 1/PI // perfect diffuse
light_emitted = 1 // emission of 1
vector light_out = 0
if(ray starting at x towards d hits light (i.e. not in shadow))
{
light_out = BRDF*light_emitted*(object_normal.dot(d))*
(-1*light_normal.dot(d)*triangle_area)/
(d.length*d.length*d.length*d.length)
}
vector direct_light = color_of_object_triangle*light_out;
//----SPECULAR-----
vector d2 = r.dir-n*2*n.dot(r.dir); // ideal reflection
vector light_color = 1 // white since dialectics don't change spec
vector specular = light_color*rayColor(createRay(x, d2),depth)
float P = 0.5; // 50/50 chance of mirror/diffuse
if(erand(Xi) < P)
return direct_light/P
else
return spec/(1-P)
感谢任何可以为我提供指导的人!再次,很抱歉,如果这确实令人费解。我已经做到了,我将要放弃,但是我感觉自己已经接近了。
#1 楼
正如评论中所建议的那样,我使用相同的.obj在Blender中创建了一个精确的场景。添加混合着色器节点并将一侧设置为漫反射,另一侧设置为完美的镜像后,您可以看到结果几乎相同。这表明我的实现是正确的。这里是并排比较。我的在左边,搅拌器在右边:
评论
您是否有想要获得的图像的参考图片?首先复制现有图像并比较结果可能会更容易。@JulienGuertault非常感谢您的建议!那真是太好了,我希望我早些想到。那会帮助拉很多头发。看到我编辑的帖子。 T
现在,您已经将其发布为单独的问题,因此我已经编辑了“另一件事”部分。请注意,该页面右侧的“链接”部分中现在出现了单独的问题,因为该问题包含该问题的链接。
如果有帮助,这里是有关路径跟踪基础知识的简短读物,并附带一些简单的c ++源代码:blog.demofox.org/2016/09/21/…