我正在编写一个基本的光线追踪器,以更好地理解整个事情。我遇到了一个困扰我一段时间的问题,球体的漫反射阴影。我使用来自以下来源的公式来计算球体交叉点和漫反射阴影。
http://www.ccs.neu.edu/home/fell/CSU540/programs/RayTracingFormulas.htm
之前显示了我的计算阴影的代码(尝试复制链接上的源代码)。在大多数情况下,计算有时在某些球体上看起来是正确的,但是取决于灯光位置,取决于球体阴影看起来的正确/损坏程度。
TVector intersect (ray.getRayOrigin().getVectX() + t * (ray.getRayDirection().getVectX() - ray.getRayOrigin().getVectX()),
ray.getRayOrigin().getVectY() + t * (ray.getRayDirection().getVectY() - ray.getRayOrigin().getVectY()),
ray.getRayOrigin().getVectZ() + t * (ray.getRayDirection().getVectZ() - ray.getRayOrigin().getVectZ()));
//Calculate the normal at the intersect point
TVector NormalIntersect (intersect.getVectX() - (position.getVectX()/r),
intersect.getVectY() - (position.getVectY()/r),
intersect.getVectZ() - (position.getVectZ()/r));
NormalIntersect = NormalIntersect.normalize();
//Find unit vector from intersect(x,y,z) to the light(x,y,z)
TVector L1 (light.GetPosition().getVectX() - intersect.getVectX(),
light.GetPosition().getVectY() - intersect.getVectY(),
light.GetPosition().getVectZ() - intersect.getVectZ());
L1 = L1.normalize();
double Magnitude = L1.magnitude();
TVector UnitVector(L1.getVectX() / Magnitude,
L1.getVectY() / Magnitude,
L1.getVectZ() / Magnitude);
//Normalized or not, the result is the same
UnitVector = UnitVector.normalize();
float Factor = (NormalIntersect.dotProduct(UnitVector));
float kd = 0.9; //diffuse-coefficient
float ka = 0.1; //Ambient-coefficient
Color pixelFinalColor(kd * Factor * (color.getcolorRed()) + (ka * color.getcolorRed()) ,
kd * Factor * (color.getcolorGreen()) + (ka * color.getcolorGreen()) ,
kd * Factor * (color.getcolorBlue()) + (ka * color.getcolorBlue()) ,1);
从图片中可以看出,一些球体似乎被正确着色,而另一些球体则完全破碎。起初我认为问题可能在于 UnitVector 计算,但是当我查看它时,我无法找到问题。任何人都可以看到问题的原因吗?
注意:我使用 OpenGL 来渲染我的场景。
更新:我仍然遇到一些问题,但我认为在你们的帮助下,大部分问题已经得到解决,并且对我计算单位向量的方式进行了一些更改。更新如下所示。非常感谢所有给出答案的人。
TVector UnitVector (light.GetPosition().getVectX() - intersect.getVectX(),
light.GetPosition().getVectY() - intersect.getVectY(),
light.GetPosition().getVectZ() - intersect.getVectZ());
UnitVector = UnitVector.normalize();
float Factor = NormalIntersect.dotProduct(UnitVector);
//Set Pixel Final Color
Color pixelFinalColor(min(1,kd * Factor * color.getcolorRed()) + (ka * color.getcolorRed()) ,
min(1,kd * Factor * color.getcolorGreen()) + (ka * color.getcolorGreen()) ,
min(1,kd * Factor * color.getcolorBlue()) + (ka * color.getcolorBlue()) ,1);