Пример #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
        static public void Refraction(bool inside, Vector3 D, Vector3 N, ref Vector3 R)
        {
            float nc = inside ? 1 : 1.2f, nt = inside ? 1.2f : 1;
            float nnt = nt / nc, ddn = Vector3.Dot(D, N);
            float cos2t = 1.0f - nnt * nnt * (1 - ddn * ddn);

            R = Vector3.Reflect(D, N);
            if (cos2t >= 0)
            {
                float r1 = RTTools.RandomFloat();
                float a = nt - nc, b = nt + nc, R0 = a * a / (b * b), c = 1 + ddn;
                float Tr = 1 - (R0 + (1 - R0) * c * c * c * c * c);
                if (r1 < Tr)
                {
                    R = (D * nnt - N * (ddn * nnt + (float)Math.Sqrt(cos2t)));
                }
            }
        }