예제 #1
0
        public override IntersectionInfo intersect(Ray ray)
        {
            IntersectionInfo info = new IntersectionInfo();

            info.shape = this;

            Vector3D dst = Vector3D.subtract(ray.position, this.position);

            double B = dst.dot(ray.direction);
            double C = dst.dot(dst) - (this.radius * this.radius);
            double D = (B * B) - C;

            if (D > 0)
            { // intersection!
                info.isHit    = true;
                info.distance = (-B) - Math.Sqrt(D);
                info.position = Vector3D.add(ray.position, Vector3D.multiplyScalar(ray.direction, info.distance));
                info.normal   = Vector3D.subtract(info.position, this.position).normalize();
                info.color    = this.material.getColor(0, 0);
            }
            else
            {
                info.isHit = false;
            }

            return(info);
        }
예제 #2
0
        public Color getPixelColor(Ray ray, Scene scene)
        {
            IntersectionInfo info = this.testIntersection(ray, scene, null);

            if (info.isHit)
            {
                Color color = this.rayTrace(info, ray, scene, 0);
                return(color);
            }
            return(scene.background.color);
        }
예제 #3
0
        public override IntersectionInfo intersect(Ray ray)
        {
            IntersectionInfo info = new IntersectionInfo();

            double Vd = this.position.dot(ray.direction);

            if (Vd == 0)
            {
                return(info);         // no intersection
            }
            double t = -(this.position.dot(ray.position) + this.d) / Vd;

            if (t <= 0)
            {
                return(info);
            }

            info.shape    = this;
            info.isHit    = true;
            info.position = Vector3D.add(ray.position, Vector3D.multiplyScalar(ray.direction, t));
            info.normal   = this.position;
            info.distance = t;

            if (this.material.hasTexture)
            {
                Vector3D vU = new Vector3D(this.position.y, this.position.z, -this.position.x);
                Vector3D vV = vU.cross(this.position);
                double   u  = info.position.dot(vU);
                double   v  = info.position.dot(vV);
                info.color = this.material.getColor(u, v);
            }
            else
            {
                info.color = this.material.getColor(0, 0);
            }

            return(info);
        }
예제 #4
0
        public IntersectionInfo testIntersection(Ray ray, Scene scene, BaseShape exclude)
        {
            int hits = 0;
            IntersectionInfo best = new IntersectionInfo();

            best.distance = 2000;

            for (int i = 0; i < scene.shapes.Count; i++)
            {
                BaseShape shape = scene.shapes[i];

                if (shape != exclude)
                {
                    IntersectionInfo info = shape.intersect(ray);
                    if (info.isHit && info.distance >= 0 && info.distance < best.distance)
                    {
                        best = info;
                        hits++;
                    }
                }
            }
            best.hitCount = hits;
            return(best);
        }
예제 #5
0
        public Color rayTrace(IntersectionInfo info, Ray ray, Scene scene, int depth)
        {
            // Calc ambient
            Color  color     = Color.multiplyScalar(info.color, scene.background.ambience);
            Color  oldColor  = color;
            double shininess = Math.Pow(10, info.shape.material.gloss + 1);

            for (int i = 0; i < scene.lights.Count; i++)
            {
                Light light = scene.lights[i];

                // Calc diffuse lighting
                Vector3D v = Vector3D.subtract(light.position, info.position).normalize();

                if (this.options.renderDiffuse)
                {
                    double L = v.dot(info.normal);
                    if (L > 0.0)
                    {
                        color = Color.add(color, Color.multiply(info.color, Color.multiplyScalar(light.color, L)));
                    }
                }

                // The greater the depth the more accurate the colours, but
                // this is exponentially (!) expensive
                if (depth <= this.options.rayDepth)
                {
                    // calculate reflection ray
                    if (this.options.renderReflections && info.shape.material.reflection > 0)
                    {
                        Ray reflectionRay     = this.getReflectionRay(info.position, info.normal, ray.direction);
                        IntersectionInfo refl = this.testIntersection(reflectionRay, scene, info.shape);

                        if (refl.isHit && refl.distance > 0)
                        {
                            refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
                        }
                        else
                        {
                            refl.color = scene.background.color;
                        }

                        color = Color.blend(color, refl.color, info.shape.material.reflection);
                    }

                    // Refraction
                    /* TODO */
                }

                /* Render shadows and highlights */

                IntersectionInfo shadowInfo = new IntersectionInfo();

                if (this.options.renderShadows)
                {
                    Ray shadowRay = new Ray(info.position, v);

                    shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
                    if (shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/)
                    {
                        Color  vA = Color.multiplyScalar(color, 0.5);
                        double dB = (0.5 * Math.Pow(shadowInfo.shape.material.transparency, 0.5));
                        color = Color.addScalar(vA, dB);
                    }
                }

                // Phong specular highlights
                if (this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0)
                {
                    Vector3D Lv = Vector3D.subtract(info.shape.position, light.position).normalize();
                    Vector3D E  = Vector3D.subtract(scene.camera.position, info.shape.position).normalize();
                    Vector3D H  = Vector3D.subtract(E, Lv).normalize();

                    double glossWeight = Math.Pow(Math.Max(info.normal.dot(H), 0), shininess);
                    color = Color.add(Color.multiplyScalar(light.color, glossWeight), color);
                }
            }
            color.limit();
            return(color);
        }