示例#1
0
文件: Shape.cs 项目: qrush/q-tracer
        public override Color3 colorNormal(Color3 existing, Ray r, Hit h, Shape s, Light bulb)
        {
            switch (shader)
             {
            case ProcShading.Circle:
               return mapCircle(h);

            case ProcShading.Texture:
               return mapTexture(h);

            default:
               return mapSquare(h);
             }
        }
示例#2
0
文件: Shape.cs 项目: qrush/q-tracer
        public override Color3 colorShadow(Color3 existing, Hit h, double factor)
        {
            switch (shader)
             {
            case ProcShading.Circle:
               return Color3.shade(mapCircle(h), factor);

            case ProcShading.Texture:
               return Color3.shade(mapTexture(h), factor);

            default:
               return Color3.shade(mapSquare(h), factor);
             }
        }
示例#3
0
        public override Vector3 calcNormal(Hit h)
        {
            Vector3 v;

            if (normals.TryGetValue(h.intersect, out v))
            {
                return(v);
            }
            else
            {
                v.X = (h.intersect.x - center.x) / radius;
                v.Y = (h.intersect.y - center.y) / radius;
                v.Z = (h.intersect.z - center.z) / radius;
                v.Normalize();

                normals.Add(h.intersect, v);

                return(v);
            }
        }
示例#4
0
        // spawn a shadow ray from the intersection point to the light source.
        private static bool spawnShadow(Light bulb, Hit finalHit, Shape hitShape, Shape fromShape)
        {
            Ray shadowRay = new Ray();

            shadowRay.start     = finalHit.intersect;
            shadowRay.direction = Point3.vectorize(shadowRay.start, bulb.Location);
            double shadowDist = Point3.distance(shadowRay.start, bulb.Location);

            foreach (Shape s in layout.Shapes)
            {
                // If this is the object we're checking from, ignore. Duh.
                if (s.Equals(hitShape) || s.Equals(fromShape) || s.Material.Kt > 0)
                {
                    continue;
                }

                Hit shadowHit = s.intersect(shadowRay);

                if (shadowHit.intersect.z == Constants.FAR_AWAY)
                {
                    continue;
                }

                // We need to check if hitShape object is in FRONT OF the current one. if it is, we need to ignore this current shape.
                Vector3 frontTest = Point3.vectorize(shadowHit.intersect, finalHit.intersect);

                if (frontTest.X > 0 && frontTest.Y > 0 && frontTest.Z > 0)
                {
                    continue;
                }

                // something has to come between the light and the current shape.
                double shapeDist = Point3.distance(shadowRay.start, shadowHit.intersect);
                if (shapeDist < shadowDist)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#5
0
文件: Shape.cs 项目: qrush/q-tracer
        public override Hit intersect(Ray r)
        {
            Hit h = new Hit();

             double denominator =
            Vector3.DotProduct(normal, r.direction);

             if (denominator == 0.0)
             {
            h.intersect.z = Constants.FAR_AWAY;
             }
             else
             {
            double numerator = normal.X * r.start.x +
               normal.Y * r.start.y +
               normal.Z * r.start.z +
               distance;

            h.omega = -numerator / denominator;

            if (h.omega < 0)
            {
               h.intersect.z = Constants.FAR_AWAY;
            }
            else
            {
               h.intersect.x = r.start.x + r.direction.X * h.omega;
               h.intersect.y = r.start.y + r.direction.Y * h.omega;
               h.intersect.z = r.start.z + r.direction.Z * h.omega;

               // Boundary hit testing.
               if (h.intersect.x > Constants.RIGHT_PLANE_BOUNDARY || h.intersect.x < Constants.LEFT_PLANE_BOUNDARY)
               {
                  h.intersect.x = h.intersect.y = h.intersect.z = Constants.FAR_AWAY;
               }
            }

             }

             return h;
        }
示例#6
0
        public override Hit intersect(Ray r)
        {
            Hit h = new Hit();

            double denominator =
                Vector3.DotProduct(normal, r.direction);

            if (denominator == 0.0)
            {
                h.intersect.z = Constants.FAR_AWAY;
            }
            else
            {
                double numerator = normal.X * r.start.x +
                                   normal.Y * r.start.y +
                                   normal.Z * r.start.z +
                                   distance;

                h.omega = -numerator / denominator;

                if (h.omega < 0)
                {
                    h.intersect.z = Constants.FAR_AWAY;
                }
                else
                {
                    h.intersect.x = r.start.x + r.direction.X * h.omega;
                    h.intersect.y = r.start.y + r.direction.Y * h.omega;
                    h.intersect.z = r.start.z + r.direction.Z * h.omega;

                    // Boundary hit testing.
                    if (h.intersect.x > Constants.RIGHT_PLANE_BOUNDARY || h.intersect.x < Constants.LEFT_PLANE_BOUNDARY)
                    {
                        h.intersect.x = h.intersect.y = h.intersect.z = Constants.FAR_AWAY;
                    }
                }
            }


            return(h);
        }
示例#7
0
 public abstract Color3 colorNormal(Color3 existing, Ray r, Hit h, Shape s, Light bulb);
示例#8
0
文件: Tracer.cs 项目: qrush/q-tracer
        // spawn a shadow ray from the intersection point to the light source.
        private static bool spawnShadow(Light bulb, Hit finalHit, Shape hitShape, Shape fromShape)
        {
            Ray shadowRay = new Ray();
             shadowRay.start = finalHit.intersect;
             shadowRay.direction = Point3.vectorize(shadowRay.start, bulb.Location);
             double shadowDist = Point3.distance(shadowRay.start, bulb.Location);

             foreach (Shape s in layout.Shapes)
             {
            // If this is the object we're checking from, ignore. Duh.
            if (s.Equals(hitShape) || s.Equals(fromShape) || s.Material.Kt > 0)
               continue;

            Hit shadowHit = s.intersect(shadowRay);

            if (shadowHit.intersect.z == Constants.FAR_AWAY)
               continue;

            // We need to check if hitShape object is in FRONT OF the current one. if it is, we need to ignore this current shape.
            Vector3 frontTest = Point3.vectorize(shadowHit.intersect, finalHit.intersect);

            if (frontTest.X > 0 && frontTest.Y > 0 && frontTest.Z > 0)
               continue;

            // something has to come between the light and the current shape.
            double shapeDist = Point3.distance(shadowRay.start, shadowHit.intersect);
            if (shapeDist < shadowDist)
            {
               return true;
            }
             }

             return false;
        }
示例#9
0
文件: Shape.cs 项目: qrush/q-tracer
        public override Hit intersect(Ray r)
        {
            Hit h = new Hit();

             double b = 2 * (r.direction.X * (r.start.x - center.x) +
               r.direction.Y * (r.start.y - center.y) +
               r.direction.Z * (r.start.z - center.z));

             double c = Math.Pow(r.start.x - center.x, 2) +
            Math.Pow(r.start.y - center.y, 2) +
            Math.Pow(r.start.z - center.z, 2) -
            Math.Pow(radius, radius);

             double disc = Math.Pow(b, 2) - 4 * c;

             if (disc < 0)
             {
            h.intersect.z = Constants.FAR_AWAY;
             }
             else
             {
            h.omega = (-b + Math.Sqrt(disc)) / 2;
            h.intersect.x = r.start.x + r.direction.X * h.omega;
            h.intersect.y = r.start.y + r.direction.Y * h.omega;
            h.intersect.z = r.start.z + r.direction.Z * h.omega;
             }

             return h;
        }
示例#10
0
文件: Shape.cs 项目: qrush/q-tracer
 public override Color3 colorNormal(Color3 existing, Ray r, Hit h, Shape s, Light bulb)
 {
     return Color3.Black;
 }
示例#11
0
文件: Color3.cs 项目: qrush/q-tracer
        public static Color3 diffuse(Hit h, Shape s, Light bulb)
        {
            Color3 diffuse = Black;
             Vector3 normal = s.calcNormal(h);
             Vector3 lightDir = Point3.vectorize(bulb.Location, h.intersect);
             double diffuseDot = Vector3.DotProduct(lightDir, normal);

             if (diffuseDot >= 0)
            diffuse = (bulb.Color * s.Material.Diffuse) * diffuseDot;

             return diffuse;
        }
示例#12
0
 public override Color3 colorShadow(Color3 existing, Hit h, double factor)
 {
     return(Color3.shade(existing, factor));
 }
示例#13
0
 public override Color3 colorNormal(Color3 existing, Ray r, Hit h, Shape s, Light bulb)
 {
     return(Color3.Black);
 }
示例#14
0
 public override Vector3 calcNormal(Hit h)
 {
     return(normal);
 }
示例#15
0
 public abstract Color3 colorShadow(Color3 existing, Hit h, double factor);
示例#16
0
文件: Shape.cs 项目: qrush/q-tracer
 public abstract Color3 colorShadow(Color3 existing, Hit h, double factor);
示例#17
0
文件: Shape.cs 项目: qrush/q-tracer
        public override Vector3 calcNormal(Hit h)
        {
            Vector3 v;

             if (normals.TryGetValue(h.intersect, out v))
             {
            return v;
             }
             else
             {
            v.X = (h.intersect.x - center.x) / radius;
            v.Y = (h.intersect.y - center.y) / radius;
            v.Z = (h.intersect.z - center.z) / radius;
            v.Normalize();

            normals.Add(h.intersect, v);

            return v;
             }
        }
示例#18
0
文件: Color3.cs 项目: qrush/q-tracer
 public static Color3 floor(Color3 existing, Hit h, Plane p)
 {
     return Color3.Green;
 }
示例#19
0
文件: Shape.cs 项目: qrush/q-tracer
 public override Color3 colorShadow(Color3 existing, Hit h, double factor)
 {
     return Color3.shade(existing, factor);
 }
示例#20
0
文件: Color3.cs 项目: qrush/q-tracer
        public static Color3 specular(Ray r, Hit h, Shape s, Light bulb)
        {
            Color3 specular = Black;
             Vector3 normal = s.calcNormal(h);

             Vector3 lightDir = Point3.vectorize(bulb.Location, h.intersect);
             Vector3 refDir = lightDir - (2 * (Vector3.DotProduct(lightDir, normal) / Math.Pow(normal.Abs(), 2)) * normal);
             double specularDot = Vector3.DotProduct(r.direction, refDir);

             if (specularDot >= 0)
            specular = (bulb.Color * s.Material.Specular) * Math.Pow(specularDot, s.Material.Ke);

             return specular;
        }
示例#21
0
文件: Shape.cs 项目: qrush/q-tracer
 public override Vector3 calcNormal(Hit h)
 {
     return normal;
 }
示例#22
0
文件: Shape.cs 项目: qrush/q-tracer
        private Color3 mapCircle(Hit h)
        {
            Color3 shadeColor;
             const double SPHERESIZE = Constants.SPHERESIZE;

             int row = (int)Math.Round(h.intersect.x / SPHERESIZE);
             int col = (int)Math.Round(h.intersect.z / SPHERESIZE);

             double centerX = row * SPHERESIZE + SPHERESIZE / 4;
             double centerY = col * SPHERESIZE + SPHERESIZE / 4;
             double r = SPHERESIZE / 4;

             if (h.intersect.x <= centerX + r && h.intersect.x >= centerX - r &&
               h.intersect.z <= centerY + r && h.intersect.z >= centerY - r)
             {
            double circle = Math.Pow(h.intersect.x - centerX, 2) + Math.Pow(h.intersect.z - centerY, 2);

            if (circle <= Math.Pow(r, 2))
               shadeColor = Color3.Yellow;
            else
               shadeColor = Color3.Red;
             }
             else
             {
            shadeColor = Color3.Red;
             }

             return shadeColor;
        }
示例#23
0
文件: Shape.cs 项目: qrush/q-tracer
        private Color3 mapSquare(Hit h)
        {
            Color3 shadeColor;
             int row = (int)Math.Round(h.intersect.x / Constants.CHECKSIZE);
             int col = (int)Math.Round(h.intersect.z / Constants.CHECKSIZE);

             if (row % 2 == 0 && col % 2 == 0)
            shadeColor = Color3.Red;
             else if (row % 2 == 0)
            shadeColor = Color3.Yellow;
             else if (col % 2 == 0)
            shadeColor = Color3.Yellow;
             else
            shadeColor = Color3.Red;

             return shadeColor;
        }
示例#24
0
文件: Shape.cs 项目: qrush/q-tracer
        private Color3 mapTexture(Hit h)
        {
            Color3 shadeColor = Color3.Black;

             int texWidth = TextureLoader.Texture.Width;
             int texHeight = TextureLoader.Texture.Height;

             int row = (int)Math.Round(h.intersect.x / texWidth);
             int col = (int)Math.Round(h.intersect.z / texHeight);

             int startX = row * texWidth;
             int startY = col * texHeight;

             int texX = (int) Math.Round(Math.Abs(h.intersect.x - startX));
             int texY = (int) Math.Round(Math.Abs(h.intersect.z - startY));

             if (texX < TextureLoader.Texture.Width && texY < TextureLoader.Texture.Height)
             {
            System.Drawing.Color texColor = TextureLoader.Texture.GetPixel(texX, texY);
            shadeColor = new Color3(texColor.R, texColor.G, texColor.B);
             }

             return shadeColor;
        }
示例#25
0
 public static Color3 floor(Color3 existing, Hit h, Plane p)
 {
     return(Color3.Green);
 }
示例#26
0
文件: Shape.cs 项目: qrush/q-tracer
 public abstract Vector3 calcNormal(Hit h);
示例#27
0
文件: Tracer.cs 项目: qrush/q-tracer
        private static Color3 fireRay(Ray incomingRay, int depth, Shape fromShape)
        {
            double closest = Constants.FAR_AWAY;
             Color3 retColor = Constants.BGCOLOR;
             int whichObject = 0, hitObject = 0;
             Hit finalHit = new Hit();

             foreach (Shape s in layout.Shapes)
             {
            Hit rayHit = s.intersect(incomingRay);
            whichObject++;

            if (rayHit.intersect.z == Constants.FAR_AWAY)
               continue;

            double dist = Point3.distance(layout.Cam.Eye, rayHit.intersect);

            if (dist < closest && !s.Equals(fromShape))
            {
               closest = dist;
               hitObject = whichObject;
               finalHit = rayHit;
            }
             }

             if (hitObject <= 0)
            return Constants.BGCOLOR;

             Shape hitShape = layout.Shapes[hitObject - 1];
             retColor = Color3.ambient(hitShape);

             // phongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphong
             Color3 diffuseColor = Color3.Black, specularColor = Color3.Black;
             foreach (Light bulb in layout.Lights)
             {
            if (spawnShadow(bulb, finalHit, hitShape, fromShape))
            {
               retColor = hitShape.colorShadow(retColor, finalHit, layout.Lights.Count * 3);
            }
            else
            {
               if (hitShape is Plane)
               {
                  retColor = hitShape.colorNormal(retColor, incomingRay, finalHit, hitShape, bulb);
               }
               else
               {
                  diffuseColor += Color3.diffuse(finalHit, hitShape, bulb);
                  specularColor += Color3.specular(incomingRay, finalHit, hitShape, bulb);
               }
            }
             }

             if (hitShape is Sphere)
             {
            retColor += diffuseColor * hitShape.Material.Kd;
            retColor += specularColor * hitShape.Material.Ks;
             }

             if (depth < Constants.MAX_DEPTH)
             {
            Color3 reflectColor = Color3.Black;

            if (hitShape.Material.Kr > 0)
            {
               Ray reflectRay = new Ray();
               reflectRay.start = finalHit.intersect;

               Vector3 normalVec = hitShape.calcNormal(finalHit);

               double c = -Vector3.DotProduct(normalVec, incomingRay.direction);
               reflectRay.direction = -(incomingRay.direction + (2 * normalVec * c));
               reflectRay.direction.Normalize();
               reflectColor = fireRay(reflectRay, depth + 1, hitShape);

               retColor += reflectColor * hitShape.Material.Kr;
            }

            if (hitShape.Material.Kt > 0)
            {
               Ray transRay = new Ray();
               double indexRefract;
               Vector3 normalVec = Vector3.FaceForward(hitShape.calcNormal(finalHit), -incomingRay.direction);

               if (Vector3.DotProduct(-incomingRay.direction, hitShape.calcNormal(finalHit)) < 0)
                  indexRefract = Constants.REFRACTION_INDEX_SPHERE / Constants.REFRACTION_INDEX_AIR;
               else
                  indexRefract = Constants.REFRACTION_INDEX_AIR / Constants.REFRACTION_INDEX_SPHERE;

               double discrim = 1 + (Math.Pow(indexRefract, 2) * (Math.Pow(Vector3.DotProduct(-incomingRay.direction, normalVec), 2) - 1));

               // Total internal reflection!
               if (discrim < 0)
               {
                  retColor += reflectColor * hitShape.Material.Kt;
               }
               else
               {
                  discrim = indexRefract * Vector3.DotProduct(-incomingRay.direction, normalVec) - Math.Sqrt(discrim);

                  transRay.direction = (indexRefract * incomingRay.direction) + (discrim * normalVec);
                  transRay.start = finalHit.intersect;

                  Color3 transColor = fireRay(transRay, depth + 1, hitShape);
                  retColor += transColor * hitShape.Material.Kt;
               }
            }
             }

             return retColor;
        }
示例#28
0
文件: Shape.cs 项目: qrush/q-tracer
 public abstract Color3 colorNormal(Color3 existing, Ray r, Hit h, Shape s, Light bulb);
示例#29
0
        private static Color3 fireRay(Ray incomingRay, int depth, Shape fromShape)
        {
            double closest = Constants.FAR_AWAY;
            Color3 retColor = Constants.BGCOLOR;
            int    whichObject = 0, hitObject = 0;
            Hit    finalHit = new Hit();

            foreach (Shape s in layout.Shapes)
            {
                Hit rayHit = s.intersect(incomingRay);
                whichObject++;

                if (rayHit.intersect.z == Constants.FAR_AWAY)
                {
                    continue;
                }

                double dist = Point3.distance(layout.Cam.Eye, rayHit.intersect);

                if (dist < closest && !s.Equals(fromShape))
                {
                    closest   = dist;
                    hitObject = whichObject;
                    finalHit  = rayHit;
                }
            }

            if (hitObject <= 0)
            {
                return(Constants.BGCOLOR);
            }

            Shape hitShape = layout.Shapes[hitObject - 1];

            retColor = Color3.ambient(hitShape);

            // phongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphongphong
            Color3 diffuseColor = Color3.Black, specularColor = Color3.Black;

            foreach (Light bulb in layout.Lights)
            {
                if (spawnShadow(bulb, finalHit, hitShape, fromShape))
                {
                    retColor = hitShape.colorShadow(retColor, finalHit, layout.Lights.Count * 3);
                }
                else
                {
                    if (hitShape is Plane)
                    {
                        retColor = hitShape.colorNormal(retColor, incomingRay, finalHit, hitShape, bulb);
                    }
                    else
                    {
                        diffuseColor  += Color3.diffuse(finalHit, hitShape, bulb);
                        specularColor += Color3.specular(incomingRay, finalHit, hitShape, bulb);
                    }
                }
            }

            if (hitShape is Sphere)
            {
                retColor += diffuseColor * hitShape.Material.Kd;
                retColor += specularColor * hitShape.Material.Ks;
            }

            if (depth < Constants.MAX_DEPTH)
            {
                Color3 reflectColor = Color3.Black;

                if (hitShape.Material.Kr > 0)
                {
                    Ray reflectRay = new Ray();
                    reflectRay.start = finalHit.intersect;

                    Vector3 normalVec = hitShape.calcNormal(finalHit);

                    double c = -Vector3.DotProduct(normalVec, incomingRay.direction);
                    reflectRay.direction = -(incomingRay.direction + (2 * normalVec * c));
                    reflectRay.direction.Normalize();
                    reflectColor = fireRay(reflectRay, depth + 1, hitShape);

                    retColor += reflectColor * hitShape.Material.Kr;
                }

                if (hitShape.Material.Kt > 0)
                {
                    Ray     transRay = new Ray();
                    double  indexRefract;
                    Vector3 normalVec = Vector3.FaceForward(hitShape.calcNormal(finalHit), -incomingRay.direction);

                    if (Vector3.DotProduct(-incomingRay.direction, hitShape.calcNormal(finalHit)) < 0)
                    {
                        indexRefract = Constants.REFRACTION_INDEX_SPHERE / Constants.REFRACTION_INDEX_AIR;
                    }
                    else
                    {
                        indexRefract = Constants.REFRACTION_INDEX_AIR / Constants.REFRACTION_INDEX_SPHERE;
                    }

                    double discrim = 1 + (Math.Pow(indexRefract, 2) * (Math.Pow(Vector3.DotProduct(-incomingRay.direction, normalVec), 2) - 1));

                    // Total internal reflection!
                    if (discrim < 0)
                    {
                        retColor += reflectColor * hitShape.Material.Kt;
                    }
                    else
                    {
                        discrim = indexRefract * Vector3.DotProduct(-incomingRay.direction, normalVec) - Math.Sqrt(discrim);

                        transRay.direction = (indexRefract * incomingRay.direction) + (discrim * normalVec);
                        transRay.start     = finalHit.intersect;

                        Color3 transColor = fireRay(transRay, depth + 1, hitShape);
                        retColor += transColor * hitShape.Material.Kt;
                    }
                }
            }

            return(retColor);
        }
示例#30
0
 public abstract Vector3 calcNormal(Hit h);