Image:

Spoiler

Code for intersection:

Spoiler

using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenTK; namespace RayTracing { public class Triangle : IIntersectable { public Vector3[] Verticies = new Vector3[3]; public Material Material { get; set; } private const float Epilson = 1e-06f; public Intersection Intersect(Ray ray) { Intersection its = new Intersection(); Vector3[] V = Verticies; // Just to save some time typing its.Hit = false; Vector3 diff = ray.Position - V[0]; Vector3 edge1 = V[1] - V[0]; Vector3 edge2 = V[2] - V[0]; Vector3 normal = Vector3.Cross(edge1, edge2); float DdN = Vector3.Dot(ray.Direction, normal); float sign; if (DdN > Epilson) { sign = 1.0f; } else if (DdN < -Epilson) { sign = -1.0f; DdN = -DdN; } else { //Ray is parallel to triangle. No intersection. return its; } float DdQ = sign * Vector3.Dot(ray.Direction, Vector3.Cross(diff, edge2)); if (DdQ >= 0.0f) { float DdE = sign * Vector3.Dot(ray.Direction, Vector3.Cross(edge1, diff)); if (DdE >= 0.0f) { if (DdQ + DdE <= DdN) { float QdN = -sign * Vector3.Dot(diff, normal); if (QdN >= 0.0f) { //float mTriBary1 = DdQ * inv; //float mTriBary2 = DdE * inv; //float mTriBary0 = 1.0f - mTriBary1 - mTriBary2; float inv = 1.0f / DdN; float t = QdN * inv; its.Hit = true; its.Material = this.Material; its.Distance = t; its.Position = Vector3.Multiply(ray.Direction, t); its.Normal = normal; } } } } return its; } } }

Code for generating eye rays:

Spoiler

using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenTK; namespace RayTracing { public class Camera { public Vector3 Position { get; set; } public Vector3 Rotation { get; set; } public float FovX { get; set; } public float FovY { get; set; } public RayTracer RayTracer { get; set; } private Matrix4 rotationMatrix = Matrix4.Identity; public Camera(RayTracer r) { RayTracer = r; FovX = MathHelper.PiOver4; Update(); } public Ray GetRay(int x, int y) { Ray r = new Ray(); float rX, rY; rX = ((2.0f * (float)x - (float)RayTracer.Width) / (float)RayTracer.Width) * (float)Math.Tan(FovX); rY = ((2.0f * (float)y - (float)RayTracer.Height) / (float)RayTracer.Height) * (float)Math.Tan(FovY); r.Position = Position; r.Direction = new Vector3(rX, rY, -1.0f); r.Direction = Vector3.Normalize(r.Direction); r.Direction = Vector3.Transform(r.Direction, rotationMatrix); return r; } public void Update() { FovY = (float)RayTracer.Height / (float)RayTracer.Width * FovX; rotationMatrix = Matrix4.CreateRotationX(Rotation.X) * Matrix4.CreateRotationY(Rotation.Y) * Matrix4.CreateRotationZ(Rotation.Z); } } }

I think the problem is in generating eye rays, but I don't see anything wrong here.