我正在编写ray示踪剂的实现,并且在此图像中看到了可以看到的结果。


所以您可以看到某些深色部分重叠了。我认为即使在我认为应该亮点的地方也可以使用它们。有两个灯从上方看,第二个灯从右下角。

我有两个问题。这样对吗?我确实尝试过搜索一些参考文献,但是失败了。我仍然不确定我的想象中的结果是正确的。

第二个结果是从哪里来的呢?

我使用通常的朗伯阴影模型并有一些东西在我的代码中是这样的:

pixel = (0, 0, 0)
normal = get normal of sphere in point of intersection;
normal = unit vector of normal;
for each light from light_set {
    light = unit vector of light;
    pixel = pixel + diffuseColor * max(0, scalar multiplication of light and normal);
}


我真的很努力地找出这种奇怪的事物来自何处。但是找不到。

UPD0:添加了一些我的真实代码。此处描述的部分是下一个:

Material mat = surfaces[closestSurfase]->getMaterial();
Color pixel = Color(0, 0, 0);
Vector3f normal = surfaces[closestSurfase]->getNormal(point).getUnitVector();
Vector3f view = -ray.getDirection().getUnitVector();
for (size_t i = 0; i < lights.size(); ++i) {
    Vector3f normal_light = lights[i]->getDirection().getUnitVector();
    Vector3f specVect = (normal_light + view).getUnitVector();
    float intenst = lights[i]->getIntensity();
    pixel = pixel + mat.getDiffuse() * std::max(0.0f, normal_light.dotMultiply(normal)) * intenst;
}
result->setPixel(x, y, pixel);


或者您可以在此处找到更多内容:https://github.com/minebv/ray_tracer/tree/lambertian_shading_fix/src

上面的描述来自于Camera的getRender方法。

UPD1:@PaulHK回答,这看起来像是在伽玛空间而不是线性颜色中混合颜色的问题。

但是我还是有一些问题。在这里您可以看到2个渲染器。

在左侧,我将所有颜色转换为线性空间后完成所有工作,我的意思是在我的代码中是这样的:

pixel = pixel + mat.getDiffuse().toLinear() * std::max(0.0f, normal_light.dotMultiply(normal)) * intenst;


在右边的一个乘上后进行变换:

pixel = pixel + (mat.getDiffuse() * std::max(0.0f, normal_light.dotMultiply(normal)) * intenst).toLinear();


我并没有忘记将像素毕竟再次放入伽马空间工作。

对我来说,正确的选择更正确。但是,还有一个问题:为什么我要对伽马空间的角度进行乘法运算?还是我认为正确的方法不正确?

UPD3:看起来整个过程实际上是关于在伽玛空间中混合颜色而不是线性的。这是环境光的结果。


关于重叠的灯光,这也是我不正确的思维方式。我终于找到了具有相同含义的参考资料。在Blender docs上找到它。

谢谢大家的回答。

评论

看起来确实很奇怪。您能否提供一些实际代码供我们查看?伪代码显示了您的意图,看起来不错,但问题可能出在一些微妙的数学或拼写错误(:

@AlanWolfe更新了我的问题,添加了一些真实的代码。

#1 楼

我认为您要描述的是在伽玛空间中混合颜色时发生的情况。混合时应该使用线性颜色空间。

读取灯光和材质的颜色时,请使用反伽马函数将它们从伽玛转换为线性。

colourLin = pow(colourLight, 2.2);
... do lambert calculation here and accumulate in 'colour' variable ..

// On output (linear->gamma conversion)
gl_FragColor = pow(colour, 1.0/2.2);


关于这个主题,GPU Gems中有一个深入的章节:线性的重要性。

评论


$ \ begingroup $
完成。看来问题确实出在浴室。但是我还有一个问题。有我的光线追踪的结果。在第一个我
$ \ endgroup $
–瓦莱里·博尔达科夫
16年8月22日在4:27



$ \ begingroup $
很抱歉发送垃圾邮件。过去不习惯使用Enter按钮发送评论。有延续。在左侧,我首先进行伽玛到线性转换,然后将其乘以max(0,光与法线的标量乘积),然后求和得到像素。并再次将结果转换为伽玛空间。在右边的那一列中,我仅将颜色乘以max(0,light和normal的标量乘积),然后才将颜色转换为线性空间。我不太明白为什么要在伽玛空间中相乘。 !img
$ \ endgroup $
–瓦莱里·博尔达科夫
16年8月22日在4:40

$ \ begingroup $
最重要的是将输出转换为伽马(意味着您的光累积是线性的)。因为您的输入是恒定的颜色,所以它对阴影的影响不如输出转换那么大。
$ \ endgroup $
–PaulHK
16年8月22日在4:50

$ \ begingroup $
如果您可以发布更新,我很想看看您的新图像输出
$ \ endgroup $
–PaulHK
16年8月22日在4:51

$ \ begingroup $
别忘了,您是使用伽马空间监视器通过眼睛(大概)选择了橙色/绿色的,所以这些颜色可能是正确的/预期的颜色。
$ \ endgroup $
–PaulHK
16年8月22日在4:54