public void RayTrace(Camera camera, StringBuilder[,] logs)
    {
      int width = myBitmap.Width;
      int height = myBitmap.Height;

      var forward = camera.Right ^ camera.Top;
      var xAngle = width > height ? camera.ViewAngle : camera.ViewAngle * width / height;
      var yAngle = height > width ? camera.ViewAngle : camera.ViewAngle * height / width;
      
      for (int i = 0; i < height; i++)
        for (int j = 0; j < width; j++)
        {
          lock (LockObject)
          {
            Vector color = Vector.Zero;

            for (int ii = 0; ii < AntiAliasPasses; ii++)
              for (int jj = 0; jj < AntiAliasPasses; jj++)
              {
                var x = (double) (j * AntiAliasPasses + jj) / (width * AntiAliasPasses) - 0.5;
                var y = (double) (i * AntiAliasPasses + ii) / (height * AntiAliasPasses) - 0.5;
                var direction = camera.Right * Math.Sin(x * xAngle) +
                                camera.Top * Math.Sin(y * yAngle) +
                                forward * (Math.Cos(x * camera.ViewAngle) + Math.Cos(y * camera.ViewAngle));

                var ray = new Ray(camera.Origin, direction);

                myTraceDepth = 0;
                color = color + TraceRay(ray, logs == null ? null : logs[j, height - 1 - i]);
              }

            myBitmap.SetPixel(j, height - 1 - i, ColorUtil.ToColor((color / (AntiAliasPasses * AntiAliasPasses))));
          }
        }
    }
    private bool IntersectRay(Ray ray, out IShape minShape, out IntersectionData mint)
    {
      mint = new IntersectionData(ray, double.PositiveInfinity, null);
      minShape = null;

      foreach (var shape in Shapes)
      {
        var t = shape.Intersect(ray);
        if (t == null) continue;

        if (t.Value.RayPoint < mint.RayPoint)
        {
          mint = t.Value;
          minShape = shape;
        }
      }

      return minShape != null;
    }
Beispiel #3
0
    public override IntersectionData? Intersect(Ray ray)
    {
      double t1;
      double t2;
      var origin = ray.Origin - myCenter;
      if (!MathUtil.SolveSquareEq(ray.Direction * ray.Direction, 
                             2.0 * origin * ray.Direction,
                             (origin * origin) - (myRadius * myRadius), out t1, out t2))
        return null;
      if (t1 < 0 && t2 < 0)
        return null;
      double t;
      if (t1 <= 0 && t2 > 0)
        t = t2;
      else if (t1 > 0 && t2 <= 0)
        t = t1;
      else
        t = Math.Min(t1, t2);

      return new IntersectionData(ray, t, (ray[t] - Center).Normalize());
    }
    private Vector TraceRay(Ray ray, StringBuilder log)
    {
      myTraceDepth++;
      if (myTraceDepth > 5)
        return Vector.Zero;

      if (log != null)
        log.AppendLine(string.Format("Incoming ray: {0}", ray));

      IShape shape;
      IntersectionData intersectionData;
      if (!IntersectRay(ray, out shape, out intersectionData))
        return Vector.Zero;

      var intersectionPoint = ray[intersectionData.RayPoint] + intersectionData.Normal.Normalize(MathUtil.Epsilon); 
      if (log != null)
      {
        log.AppendLine(string.Format("Intersection: {0}", intersectionPoint));
        log.AppendLine(string.Format("Normal: {0}", intersectionData.Normal));
        log.AppendLine(string.Format("Shape: {0}", shape.Name));
      }

      var texCoords = shape.GetTextureCoords(intersectionPoint);
      var color = shape.Texture.GetColor(texCoords.X, texCoords.Y) * shape.Ambient;
      foreach (var light in Lights)
      {
        var lightDirection = light.Point - intersectionPoint;
        IShape lightShape;
        IntersectionData lightIntersectionData;
        var rayToLight = new Ray(intersectionPoint, lightDirection);
        if (log != null)
          log.AppendLine(string.Format("Ray to light: {0}", rayToLight));
        if (IntersectRay(rayToLight, out lightShape, out lightIntersectionData))
          if (lightIntersectionData.RayPoint < 1)
            continue;

        var specular = ray.Direction & Reflect(lightDirection.Normalize(), intersectionData.Normal);
        if (specular > 0)
          specular = Math.Pow(specular, shape.Shineness) * shape.Specular;
        else
          specular = 0;

        color = color + (light.Color * light.Luminosity * shape.Diffuse * MathUtil.Cast(lightDirection & intersectionData.Normal)) + (light.Color * specular);
      }

      var reflectedDirection = Reflect(ray.Direction.Normalize(), intersectionData.Normal);

      var reflectedColor = TraceRay(new Ray(intersectionPoint, reflectedDirection), log);

      color = color + shape.Reflect * reflectedColor;

      return color.Cast(1);
    }
Beispiel #5
0
 public override IntersectionData? Intersect(Ray ray)
 {
   var t = (-myDistance - (ray.Origin * myNormal)) / (ray.Direction * myNormal);
   if (t < 0) return null;
   return new IntersectionData(ray, t, myNormal);
 }
 public abstract IntersectionData? Intersect(Ray ray);