Пример #1
0
        // sample: samples a single path up to a maximum depth
        private Vector3 Sample(Ray ray, int depth, int x, int y)
        {
            // find nearest ray/scene intersection
            Scene.Intersect(ray);
            if (ray.objIdx == -1)
            {
                // no scene primitive encountered; skybox
                return(1.0f * scene.SampleSkydome(ray.D));
            }
            // calculate intersection point
            Vector3 I = ray.O + ray.t * ray.D;
            // get material at intersection point
            Material material = scene.GetMaterial(ray.objIdx, I);

            if (material.emissive)
            {
                // hit light
                return(material.diffuse);
            }
            // terminate if path is too long
            if (depth >= MAXDEPTH)
            {
                return(Vector3.Zero);
            }
            // handle material interaction
            float   r0 = RTTools.RandomFloat();
            Vector3 R  = Vector3.Zero;

            if (r0 < material.refr)
            {
                // dielectric: refract or reflect
                RTTools.Refraction(ray.inside, ray.D, ray.N, ref R);
                Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f);
                extensionRay.inside = (Vector3.Dot(ray.N, R) < 0);

                return(material.diffuse * Sample(extensionRay, depth + 1, x, y));
            }
            else if ((r0 < (material.refl + material.refr)) && (depth < MAXDEPTH))
            {
                // pure specular reflection
                R = Vector3.Reflect(ray.D, ray.N);
                Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f);

                return(material.diffuse * Sample(extensionRay, depth + 1, x, y));
            }
            else
            {
                // diffuse reflection
                if (x == 500 && y == 400)
                {
                    //Console.WriteLine("test");
                    //return new Vector3(255,255,255);
                }
                R = RTTools.DiffuseReflection(RTTools.GetRNG(), ray.N);
                Ray extensionRay = new Ray(I + R * EPSILON, R, 1e34f);
                return(Vector3.Dot(R, ray.N) * material.diffuse * Sample(extensionRay, depth + 1, x, y));
            }
        }
Пример #2
0
        public void Update()
        {
            // construct a look-at matrix
            E     = Vector3.Normalize(target - pos);
            up    = Vector3.UnitY;
            right = Vector3.Cross(up, E);
            float[] rightxs = { right.X, right.X, right.X, right.X };
            float[] rightys = { right.Y, right.Y, right.Y, right.Y };
            float[] rightzs = { right.Z, right.Z, right.Z, right.Z };
            rightx4 = new Vector <float>(rightxs);
            righty4 = new Vector <float>(rightys);
            rightz4 = new Vector <float>(rightzs);

            up = Vector3.Cross(E, right);
            float[] upxs = { up.X, up.X, up.X, up.X };
            float[] upys = { up.Y, up.Y, up.Y, up.Y };
            float[] upzs = { up.Z, up.Z, up.Z, up.Z };
            upx4 = new Vector <float>(upxs);
            upy4 = new Vector <float>(upys);
            upz4 = new Vector <float>(upzs);

            // calculate focal distance
            Ray ray = new Ray(pos, E, 1e34f);

            Scene.Intersect(ray);
            focalDistance = Math.Min(20, ray.t);
            // calculate virtual screen corners
            Vector3 C = pos + focalDistance * E;

            p1 = C - 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up;
            p2 = C + 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up;
            p3 = C - 0.5f * focalDistance * aspectRatio * right - 0.5f * focalDistance * up;

            float[] p1sX = { p1.X, p1.X, p1.X, p1.X };
            float[] p2sX = { p2.X, p2.X, p2.X, p2.X };
            float[] p3sX = { p3.X, p3.X, p3.X, p3.X };

            float[] p1sY = { p1.Y, p1.Y, p1.Y, p1.Y };
            float[] p2sY = { p2.Y, p2.Y, p2.Y, p2.Y };
            float[] p3sY = { p3.Y, p3.Y, p3.Y, p3.Y };

            float[] p1sZ = { p1.Z, p1.Z, p1.Z, p1.Z };
            float[] p2sZ = { p2.Z, p2.Z, p2.Z, p2.Z };
            float[] p3sZ = { p3.Z, p3.Z, p3.Z, p3.Z };

            p1x4 = new Vector <float>(p1sX);
            p1y4 = new Vector <float>(p1sY);
            p1z4 = new Vector <float>(p1sZ);

            p2x4 = new Vector <float>(p2sX);
            p2y4 = new Vector <float>(p2sY);
            p2z4 = new Vector <float>(p2sZ);

            p3x4 = new Vector <float>(p3sX);
            p3y4 = new Vector <float>(p3sY);
            p3z4 = new Vector <float>(p3sZ);
        }
Пример #3
0
        public void Update()
        {
            // construct a look-at matrix
            E     = Vector3.Normalize(target - pos);
            up    = Vector3.UnitY;
            right = Vector3.Cross(up, E);
            up    = Vector3.Cross(E, right);
            // calculate focal distance
            Ray ray = new Ray(pos, E, 1e34f);

            Scene.Intersect(ray);
            focalDistance = Math.Min(20, ray.t);
            // calculate virtual screen corners
            Vector3 C = pos + focalDistance * E;

            p1 = C - 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up;
            p2 = C + 0.5f * focalDistance * aspectRatio * right + 0.5f * focalDistance * up;
            p3 = C - 0.5f * focalDistance * aspectRatio * right - 0.5f * focalDistance * up;
        }