我在网上看过很多光线跟踪算法。但是,我对阴影和阴影没有清楚的认识。根据我的理解,下面的伪代码是否写得正确?
for each primitive
check for intersection
if there is one
do color be half of the background color
Ishadow = true
break
for each ambient light in environment
calculate light contribution to the color
if ( Ishadow == false )
for each point light
calculate diffuse shading
calculate reflection direction
calculate specular light
trace for reflection ray // (i)
add color returned from i after multiplied by some coefficient
trace for refraction ray // (ii)
add color returned from ii after multiplied by some coefficient
return color value calculated until this point
答案 0 :(得分:0)
您应该将阴影与正常光线追踪路径整合: 对于每个屏幕像素,您通过场景发送光线,最终确定最近的物体交叉点:在最近的物体交叉点处,您将首先读出像素颜色(该点处物体的纹理),除了计算反射矢量等(使用法线矢量),您现在另外将光线从该交叉点投射到场景中的每个光源:如果这些光线与其他物体相交在击中光源之前,交点处于阴影中,您可以相应地调整该点的最终颜色。
答案 1 :(得分:0)
伪代码的问题在于它很容易变得“伪”,以至于它变得与我们试图通过远离自然语言而避免的模糊性相同。 “颜色是背景颜色的一半?”在您迭代光源之前出现这条线的事实令人困惑。在迭代光源之前,如何设置Ishadow?
也许更好的描述是:
given a ray in space
find nearest object with which ray intersects
for each point light
if normal at surface of intersected object points toward light (use dot product for this)
cast a ray into space from the surface toward the light
if ray intersection is closer than light* light is shadowed at this point
*如果您在阴影中看到奇怪的瑕疵,那么每个程序员在编写第一个光线跟踪器时都会犯一个错误。浮点(或双精度)数学是不精确的,并且在进行阴影跟踪时,您将经常(大约一半的时间)重新交叉。如果没有图表,解释有点难以描述,但让我看看我能做些什么。
如果在球体表面上有一个交点,在大多数情况下,该点在浮点寄存器中的表示在数学上并不精确。它可以在球体内部略微内侧或稍微外侧。如果它在球体内并且您尝试对光源运行相交测试,则最近的交点将是球体本身。交叉点距离将非常小,因此您可以简单地拒绝任何比例如.000001单位更接近的阴影射线交叉点。如果你的几何体都是凸面的并且无法合法地遮蔽自身,那么你可以在进行阴影测试时跳过测试球体。