Beispiel #1
0
 void tRender(int start, int end)
 {
     for (int i = start; i < end; i++)
     {
         for (int j = -_height / 2; j < _height / 2; j++)
         {
             Point3D  p = _center + _direction * _distance + v1 * i / _zoom + v2 * j / _zoom;
             Vector3D v = (Vector3D)p - (Vector3D)_center;
             v /= v.Length;
             Ray ray = new Ray(v, _center, 1, 1);
             if (UpdateBitmap != null)
             {
                 UpdateBitmap(renderer, i + _width / 2, j + _height / 2, ray.TraceRay(_space));
             }
         }
     }
     renderCounter++;
 }
Beispiel #2
0
        public Color TraceRay(Space3D space)
        {
            List <Intersection> intersections = new List <Intersection>();

            foreach (Traceable t in space.objects)
            {
                if (t.FindIntersect(this) != null)
                {
                    intersections.Add(t.FindIntersect(this));
                }
            }

            int    index    = -1;
            double distance = double.MaxValue;

            for (int i = 0; i < intersections.Count; i++)
            {
                if (intersections[i].distance < distance && intersections[i].distance > 1)
                {
                    distance = intersections[i].distance;
                    index    = i;
                }
            }

            double r = 0;
            double g = 0;
            double b = 0;

            if (index > -1)
            {
                //if (traceDepth > 1)
                //{
                //    System.Diagnostics.Trace.WriteLine("Hit after reflection!");
                //}
                Point3D intersectionPoint = origin + distance * vector;
                //ambient
                r += (double)space.ambient.R / 255 * (double)intersections[index].ambient.R / 255;
                g += (double)space.ambient.G / 255 * (double)intersections[index].ambient.G / 255;
                b += (double)space.ambient.B / 255 * (double)intersections[index].ambient.B / 255;

                //lights
                foreach (Light light in space.lights)
                {
                    //diffuse
                    Color    lightColor     = light.getColor(intersectionPoint);
                    Vector3D lightDirection = light.getDirection(intersectionPoint);
                    Vector3D normal         = intersections[index].normal;
                    lightDirection /= lightDirection.Length;
                    double dotProduct = Vector3D.DotProduct(lightDirection, normal);
                    if (dotProduct < 0)
                    {
                        r += ((double)intersections[index].ambient.R / 255) * ((double)lightColor.R / 255) * -dotProduct;
                        g += ((double)intersections[index].ambient.G / 255) * ((double)lightColor.G / 255) * -dotProduct;
                        b += ((double)intersections[index].ambient.B / 255) * ((double)lightColor.B / 255) * -dotProduct;

                        //specular
                        //refract
                        double refractConstRatio = refractConst / intersections[index].refractConst;

                        Vector3D refractDirection = refractConstRatio * lightDirection + (refractConstRatio * -dotProduct - Math.Sqrt(1 - Math.Pow(refractConstRatio, 2) * (1 - Math.Pow(dotProduct, 2)))) * normal;
                        refractDirection /= refractDirection.Length;

                        dotProduct = Vector3D.DotProduct(refractDirection, normal);
                        if (dotProduct > 0)
                        {
                            r += ((double)intersections[index].material.R / 255) * ((double)lightColor.R / 255) * Math.Pow(-dotProduct, intersections[index].specularConst);
                            g += ((double)intersections[index].material.G / 255) * ((double)lightColor.G / 255) * Math.Pow(-dotProduct, intersections[index].specularConst);
                            b += ((double)intersections[index].material.B / 255) * ((double)lightColor.B / 255) * Math.Pow(-dotProduct, intersections[index].specularConst);
                        }

                        //reflect
                        Vector3D lightReflect = lightDirection - 2 * dotProduct * normal;
                        lightReflect /= lightReflect.Length;
                        dotProduct    = Vector3D.DotProduct(lightReflect, vector);
                        if (dotProduct < 0)
                        {
                            //System.Diagnostics.Trace.WriteLine("dotproduct = " + dotProduct);
                            r += ((double)intersections[index].specular.R / 255) * ((double)lightColor.R / 255) * Math.Pow(-dotProduct, intersections[index].specularConst);
                            g += ((double)intersections[index].specular.G / 255) * ((double)lightColor.G / 255) * Math.Pow(-dotProduct, intersections[index].specularConst);
                            b += ((double)intersections[index].specular.B / 255) * ((double)lightColor.B / 255) * Math.Pow(-dotProduct, intersections[index].specularConst);
                        }
                    }
                }

                //reflection
                if (traceDepth < space.MaxDepth)
                {
                    Vector3D normal     = intersections[index].normal;
                    double   dotProduct = Vector3D.DotProduct(vector, normal);

                    if (dotProduct < 0)
                    {
                        Ray   reflectRay   = new Ray(vector - 2 * dotProduct * normal, intersectionPoint, refractConst, traceDepth + 1);
                        Color reflectColor = reflectRay.TraceRay(space);

                        r += (double)reflectColor.R / 255;
                        g += (double)reflectColor.G / 255;
                        b += (double)reflectColor.B / 255;
                    }
                }

                //refraction
                if (traceDepth < space.MaxDepth && intersections[index].refractConst != 0)
                {
                    Vector3D normal            = intersections[index].normal;
                    double   dotProduct        = Vector3D.DotProduct(vector, normal);
                    double   refractConstRatio = refractConst / intersections[index].refractConst;

                    if (dotProduct < 0)
                    {
                        Vector3D refractDirection = refractConstRatio * vector + (refractConstRatio * -dotProduct - Math.Sqrt(1 - Math.Pow(refractConstRatio, 2) * (1 - Math.Pow(dotProduct, 2)))) * normal;
                        refractDirection /= refractDirection.Length;

                        dotProduct = Vector3D.DotProduct(refractDirection, normal);
                        if (dotProduct < 0)
                        {
                            Ray   refractRay   = new Ray(refractDirection, intersectionPoint, intersections[index].refractConst, traceDepth + 1);
                            Color refractColor = refractRay.TraceRay(space);

                            r += intersections[index].material.R / 255 * (double)refractColor.R / 255;
                            g += intersections[index].material.G / 255 * (double)refractColor.G / 255;
                            b += intersections[index].material.B / 255 * (double)refractColor.B / 255;
                        }
                    }
                    if (dotProduct > 0)
                    {
                        Vector3D refractDirection = refractConstRatio * vector + (refractConstRatio * dotProduct - Math.Sqrt(1 - Math.Pow(refractConstRatio, 2) * (1 - Math.Pow(dotProduct, 2)))) * normal;
                        refractDirection /= refractDirection.Length;

                        dotProduct = Vector3D.DotProduct(refractDirection, normal);
                        if (dotProduct > 0)
                        {
                            Ray   refractRay   = new Ray(refractDirection, intersectionPoint, 1, traceDepth + 1);
                            Color refractColor = refractRay.TraceRay(space);

                            r += (double)refractColor.R / 255;
                            g += (double)refractColor.G / 255;
                            b += (double)refractColor.B / 255;
                        }
                    }
                }
            }

            if (r > 1)
            {
                r = 1;
            }
            r *= 255;
            if (g > 1)
            {
                g = 1;
            }
            g *= 255;
            if (b > 1)
            {
                b = 1;
            }
            b *= 255;

            return(Color.FromArgb((int)r, (int)g, (int)b));
        }