Exemple #1
0
        public Color ShadeHit(Comps comps, int remaining = 5)
        {
            var result = Color.Black;

            foreach (var light in this.Lights)
            {
                var surface = comps.Object.Material.Lighting(
                    comps.Object,
                    light,
                    comps.OverPoint,
                    comps.Eye,
                    comps.Normal,
                    light.IntensityAt(comps.OverPoint, this));

                var reflected = this.ReflectedColor(comps, remaining);
                var refracted = this.RefractedColor(comps, remaining);

                var material = comps.Object.Material;
                if (material.Reflective > 0 && material.Transparency > 0)
                {
                    var reflectance = comps.Schlick();
                    result += surface + reflected * reflectance + refracted * (1 - reflectance);
                }
                else
                {
                    result += surface + reflected + refracted;
                }
            }

            return(result);
        }
Exemple #2
0
        public Color RefractedColor(Comps comps, int remaining = 5)
        {
            if (remaining < 1 || comps.Object.Material.Transparency == 0)
            {
                return(Color.Black);
            }

            // Find the ratio of first index of refraction to the second.
            // (Yup, this is inverted from the definition of Snell's Law.)
            var n_ratio = comps.n1 / comps.n2;
            // cos(theta_i) is the same as the dot product of the two vectors
            var cos_i = comps.Eye.Dot(comps.Normal);
            // Find sin(theta_t)^2 via trigonometric identity
            var sin2_t = n_ratio * n_ratio * (1 - cos_i * cos_i);

            if (sin2_t > 1)
            {
                return(Color.Black);
            }

            Interlocked.Increment(ref Stats.SecondaryRays);
            // Find cos(theta_t) via trigonometric identity
            var cos_t = Math.Sqrt(1.0 - sin2_t);
            // Compute the direction of the refracted ray
            var direction = comps.Normal * (n_ratio * cos_i - cos_t) - comps.Eye * n_ratio;
            // Create the refracted ray
            var refract_ray = new Ray(comps.UnderPoint, direction, RayType.Refraction);

            // Find the color of the refracted ray, making sure to multiply
            // by the transparency value to account for any opacity
            return(this.ColorAt(refract_ray, remaining - 1) * comps.Object.Material.Transparency);
        }
Exemple #3
0
        public Color ReflectedColor(Comps comps, int remaining = 5)
        {
            if (remaining < 1 || comps.Object.Material.Reflective == 0)
            {
                return(Color.Black);
            }

            var specularComp = Color.White;

            if (comps.Object.Material.SpecularMap != null)
            {
                specularComp = comps.Object.Material.SpecularMap.PatternAtShape(comps.Object, comps.OverPoint);
            }

            Interlocked.Increment(ref Stats.SecondaryRays);
            var reflectRay = new Ray(comps.OverPoint, comps.Reflect, RayType.Reflection);
            var color      = this.ColorAt(reflectRay, remaining - 1);

            return(color * comps.Object.Material.Reflective * specularComp);
        }