全体をよりよく理解するために、基本的なレイトレーサーを作成しています。球体のディフューズ シェーディングです。次のソースからの数式を使用して、球の交差と拡散シェーディングを計算しました。
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);