据我所知,伪代码应如下所示:
ambient light
for each light source
direction of light = light point - point on the object
test for an intersection starting at the point on the object, until you hit something
if (the intersection test returned a distance > distance from point on object to light point)
(do diffuse and specular shading)
关于我的实现,有一件快速的事情要提:如果没有相交,则相交测试将返回9999999。
我尝试过的一些事情是:反转阴影射线的方向-无效果。进行比较的相交距离-光照距离>(一些小的epsilon值)-不变。手动将光源移到另一侧-镜面反射移到新的点,但是没有变化。
这是我最新输出的图片,我试图在浅灰色平面的左下角添加阴影。
任何帮助将不胜感激。
这是我代码的相关部分:
//iterate through all lights
if (myLights.size() > 0)
{
for (int i = 0; i < myLights.size(); i++)
{
//calculate the direction of the light
glm::vec3 ldir = (myLights[i].position - surfacePoint);
//this the length of the distance between the light and the surface
float ldist= sqrt(pow(ldir.x, 2.0f) + pow(ldir.y, 2.0f) + pow(ldir.z, 2.0f));
//check if the light can see the surface point
float intersections = myObjGroup->testIntersections(surfacePoint, normalize(ldir));
if (abs(intersections-ldist) > 0.0000001f)
{
//diffuse and specular shading have been cut for brevity
}
}
}
编辑:新图像:
>
#1 楼
您的if
条件使我感到怀疑。如果相交测试没有碰到物体,则应包括漫反射和镜面反射阴影。也就是说,如果intersections > ldist
。因此,您的代码应如下所示:if (intersections > ldist)
{
colour += diffuse(...);
colour += specular(...);
}
与0.0000001f的比较表明,您在自相交方面也遇到了麻烦(即,光线与阴影对象相交)。在一次命中的跟踪器中,您不能仅通过丢弃相交来解决该问题,因为您仍然不知道阴影射线是否会进一步相交于另一个对象。为避免自相交,您需要通过epsilon沿射线的方向推动射线的起点:
glm::vec3 direction = normalize(ldir);
glm::vec3 start = surfacePoint + epsilon * direction;
float intersections = myObjGroup->testIntersections(start, direction);
另一件事:不要忘记测试光线在您要照明的表面的前面。您可以使用
ldir
的点积和表面法线来执行此操作:如果点积为正,则光线在正确的一侧;否则,该点为正。如果为负,则光线在表面后面,因此甚至在投射射线之前就被遮盖了。评论
$ \ begingroup $
非常感谢您的帮助,非常感谢您抽出宝贵的时间来编写它。我已经执行了您的建议。不幸的是,我的影子仍然不见了。我最近的输出是在原始问题中。我假设这意味着问题在代码的上游。当然,这大约是我设定阶段的200-300行。如果您有足够的胃,我就把它放在pastebin上。如果您不这样做,我完全理解。非常感谢您的协助;我已经很久很接近这个了,我想我一直对自己的错误视而不见
$ \ endgroup $
–user1764241
2015年11月19日23:55
$ \ begingroup $
如果仍然遇到问题,只需应用常规的调试技术即可。继续简化代码以将问题空间减少一半。尝试删除所有阴影计算,然后将颜色设置为交叉点/ 999999,这样您未阴影的交叉点就是白色。在较浅的位置绘制一个对象,以确保它是正确的:在两个渲染中,看起来它都可能位于图像的右下角,在两个对象之间。在阴影坐标上设置一个断点,并逐步遍历您知道应该在阴影中的一个特定点的阴影。
$ \ endgroup $
–丹·赫尔姆
15年11月20日在9:19
评论
专家提示:x * x比pow(x,2.0f)快得多。