Beispiel #1
0
        public override Isect intersect(Ray ry)
        {
            double b, disc, t;
            Isect  ip;

            v.sub2(c, ry.P);
            b    = Vec.dot(v, ry.D);
            disc = b * b - Vec.dot(v, v) + r2;
            if (disc < 0.0)
            {
                return(null);
            }
            disc = Math.Sqrt(disc);
            t    = (b - disc < 1e-6) ? b + disc : b - disc;
            if (t < 1e-6)
            {
                return(null);
            }
            ip       = new Isect();
            ip.t     = t;
            ip.enter = Vec.dot(v, v) > r2 + 1e-6 ? 1 : 0;
            ip.prim  = this;
            ip.surf  = surf;
            return(ip);
        }
Beispiel #2
0
        /**
         * Launches a ray
         */
        Vec trace(int level, double weight, Ray r)
        {
            Vec  P, N;
            bool hit;

            // Checks the recursion level
            if (level > 6)
            {
                return(new Vec());
            }

            hit = intersect(r, 1e6);
            if (hit)
            {
                P = r.point(inter.t);
                N = inter.prim.normal(P);
                if (Vec.dot(r.D, N) >= 0.0)
                {
                    N.negate();
                }
                return(shade(level, weight, P, N, r.D, inter));
            }
            // no intersection --> col = 0,0,0
            return(voidVec);
        }
Beispiel #3
0
        /**
         * Return the Vector's reflection direction
         * @return The specular direction
         */
        Vec SpecularDirection(Vec I, Vec N)
        {
            Vec r;

            r = Vec.comb(1.0 / Math.Abs(Vec.dot(I, N)), I, 2.0, N);
            r.normalize();
            return(r);
        }
Beispiel #4
0
        /**
         * Return the Vector's transmission direction
         */
        Vec TransDir(Surface m1, Surface m2, Vec I, Vec N)
        {
            double n1, n2, eta, c1, cs2;
            Vec    r;

            n1  = m1 == null ? 1.0 : m1.ior;
            n2  = m2 == null ? 1.0 : m2.ior;
            eta = n1 / n2;
            c1  = -Vec.dot(I, N);
            cs2 = 1.0 - eta * eta * (1.0 - c1 * c1);
            if (cs2 < 0.0)
            {
                return(null);
            }
            r = Vec.comb(eta, I, eta * c1 - Math.Sqrt(cs2), N);
            r.normalize();
            return(r);
        }
Beispiel #5
0
        /**
         * Returns the shaded color
         * @return The color in Vec form (rgb)
         */
        Vec shade(int level, double weight, Vec P, Vec N, Vec I, Isect hit)
        {
            Vec     tcol;
            Vec     R;
            double  t, diff, spec;
            Surface surf;
            Vec     col;
            int     l;

            col  = new Vec();
            surf = hit.surf;
            R    = new Vec();
            if (surf.shine > 1e-6)
            {
                R = SpecularDirection(I, N);
            }

            // Computes the effectof each light
            for (l = 0; l < lights.Length; l++)
            {
                L.sub2(lights [l].pos, P);
                if (Vec.dot(N, L) >= 0.0)
                {
                    t = L.normalize();

                    tRay.P = P;
                    tRay.D = L;

                    // Checks if there is a shadow
                    if (Shadow(tRay, t) > 0)
                    {
                        diff = Vec.dot(N, L) * surf.kd *
                               lights [l].brightness;

                        col.adds(diff, surf.color);
                        if (surf.shine > 1e-6)
                        {
                            spec = Vec.dot(R, L);
                            if (spec > 1e-6)
                            {
                                spec   = Math.Pow(spec, surf.shine);
                                col.x += spec;
                                col.y += spec;
                                col.z += spec;
                            }
                        }
                    }
                }
            }

            tRay.P = P;
            if (surf.ks * weight > 1e-3)
            {
                tRay.D = SpecularDirection(I, N);
                tcol   = trace(level + 1, surf.ks * weight, tRay);
                col.adds(surf.ks, tcol);
            }
            if (surf.kt * weight > 1e-3)
            {
                if (hit.enter > 0)
                {
                    tRay.D = TransDir(null, surf, I, N);
                }
                else
                {
                    tRay.D = TransDir(surf, null, I, N);
                }
                tcol = trace(level + 1, surf.kt * weight, tRay);
                col.adds(surf.kt, tcol);
            }

            // garbaging...
            tcol = null;
            surf = null;

            return(col);
        }
Beispiel #6
0
        public void render(Interval interval)
        {
            int[] row        = new int[interval.width * (interval.yto - interval.yfrom)];
            int   pixCounter = 0;           //iterator

            int    x, y, red, green, blue;
            double xlen, ylen;
            Vec    viewVec;

            viewVec = Vec.sub(view.at, view.from);

            viewVec.normalize();

            Vec tmpVec = new Vec(viewVec);

            tmpVec.scale(Vec.dot(view.up, viewVec));

            Vec upVec = Vec.sub(view.up, tmpVec);

            upVec.normalize();

            Vec leftVec = Vec.cross(view.up, viewVec);

            leftVec.normalize();

            double frustrumwidth = view.dist * Math.Tan(view.angle);

            upVec.scale(-frustrumwidth);
            leftVec.scale(view.aspect * frustrumwidth);

            Ray r   = new Ray(view.from, voidVec);
            Vec col = new Vec();

            // For each line
            for (y = interval.yfrom; y < interval.yto; y++)
            {
                ylen = (double)(2.0 * y) / (double)interval.width - 1.0;
                for (x = 0; x < interval.width; x++)
                {
                    xlen = (double)(2.0 * x) / (double)interval.width - 1.0;
                    r.D  = Vec.comb(xlen, leftVec, ylen, upVec);
                    r.D.add(viewVec);
                    r.D.normalize();
                    col = trace(0, 1.0, r);

                    // computes the color of the ray
                    red = (int)(col.x * 255.0);
                    if (red > 255)
                    {
                        red = 255;
                    }
                    green = (int)(col.y * 255.0);
                    if (green > 255)
                    {
                        green = 255;
                    }
                    blue = (int)(col.z * 255.0);
                    if (blue > 255)
                    {
                        blue = 255;
                    }

                    checksum += red;
                    checksum += green;
                    checksum += blue;

                    // Sets the pixels
                    row [pixCounter] = alpha | (red << 16) | (green << 8) | (blue);
                    pixCounter++;
                }
            }
        }