Итак, я пытаюсь переписать свой трассировщик лучей в C #, и я получаю эти странные артефакты.Сначала я мог подумать, что это были артефакты черных пятен, которые не добавили эпсилон к теневому лучу , как описано здесь .
Однако я добавляю эпсилон и пятнане черные (но я добавляю эмбиент).Вот пример изображения (я сделал фон желтым, чтобы он немного выделялся)
Вот мой код освещения:
private Vector4 CalculateBlinnPhongLight(Ray ray, Intersection its)
{
Vector4 blinnPhongColor = Color.Blue.ToVector4();
//Step 1: Calculate intersection point. Since our direction was never normalized we need to do it here.
Microsoft.Xna.Framework.Vector3 itsPoint = ray.Origin + ray.Direction*its.TimeInterval.StartTime;
//Step 2: Calculate half vector h - bisector of angle of v (from intersection to eye) and l (intersection to light)
Microsoft.Xna.Framework.Vector3 v = -1 * ray.Direction; v.Normalize();
//Step 3: For ecah light in the scene grab it's contribution
foreach (Light light in Lights)
{
//Step 4: Setup unit vectors for Blinn Phong Lighting model: pg.84
Microsoft.Xna.Framework.Vector3 l = light.Position - itsPoint; l.Normalize();
Microsoft.Xna.Framework.Vector3 h = v + l; h.Normalize();
Microsoft.Xna.Framework.Vector3 n = its.Normal;
//Step 5: Shadow-Check - send shadow ray and see if it intersects with anything
if (IsInShadow(l, itsPoint) )
{
continue;
//TO DO: Check if the material is dielectric (see through)
}
//Step 6: Calculate light attenuation
//TODO:
//Step 7: Perform Blinn Phong calculation
//color = color + diffuse * I * max(0, n.l)
//color = color + specular * I * max(0, n.h)^phong
blinnPhongColor += its.ClosestNode.Material.DiffuseColor.ToVector4() * light.Color.ToVector4() * Math.Max(0, Microsoft.Xna.Framework.Vector3.Dot(n, l));
blinnPhongColor += its.ClosestNode.Material.SpecularColor.ToVector4() * light.Color.ToVector4() * (float)Math.Pow(Math.Max(0, Vector3.Dot(n, h)), its.ClosestNode.Material.PhongExponent);
}
//Step 8: Add ambient Color
blinnPhongColor += its.ClosestNode.Material.AmbientColor.ToVector4() * AmbientColor.ToVector4();
return blinnPhongColor;
}
private bool IsInShadow(Microsoft.Xna.Framework.Vector3 dirToLight, Microsoft.Xna.Framework.Vector3 itsPoint)
{
//Step 1: Need to add epsilon go itsPoint otherwise we might intersect ourselves
Microsoft.Xna.Framework.Vector3 epsItsPoint = itsPoint + 0.000001f*dirToLight;
Ray shadowRay = new Ray(epsItsPoint, dirToLight);
return ! this.Root.IntersectRay(shadowRay).Hit;
}
Это возможноСтоит отметить, что мои Направления лучей не являются единичными векторами.Я сделал это целенаправленно, основываясь на инструкциях к книге, которую я читаю, чтобы, когда я могу преобразовать луч с помощью матриц преобразования, я даю каждому примитиву возможность легкого создания экземпляров.