Esempio n. 1
0
        public override bool HitTest(ref Ray ray, ref HitTestResult result)
        {
            Vector eo = Center;

            eo.Sub(ref ray.Position);
            double v    = Vector.Dot(ref eo, ref ray.Direction);
            var    disc = Radius * Radius - Vector.Dot(ref eo, ref eo) + v * v;

            if (disc < 0)
            {
                return(false);
            }
            disc = v - Math.Sqrt(disc);
            if (disc < 0.001f)
            {
                return(false);
            }
            result.Shape    = this;
            result.Position = ray.Position + ray.Direction * disc;
            result.Normal   = result.Position - Center;
            result.Normal.Normalize();
            result.Distance = disc;
            return(true);
        }
Esempio n. 2
0
 public abstract bool HitTest(ref Ray ray, ref HitTestResult result);
Esempio n. 3
0
        private Color Trace(ref Ray ray, Scene scene, int depth)
        {
            HitTestResult hittest = new HitTestResult();

            hittest.Distance = double.MaxValue;
            if (!scene.HitTest(ref ray, ref hittest))
            {
                return(Color.Black);
            }

            var d          = ray.Direction;
            var pos        = hittest.Distance * ray.Direction + ray.Position; //交点位置
            var normal     = hittest.Normal;                                  //交点法向量
            var cosa       = normal * d;                                      //-Cos(入射角)
            var reflectDir = d - 2 * cosa * normal;                           //反射方向

            Color color;

            if (cosa < 0)
            {
                color = GetNaturalColor(hittest.Shape, ref pos, ref normal, ref reflectDir, scene);
            }
            else
            {
                color = Color.Black;
            }
            if (depth <= 0)
            {
                return(color);
            }
            depth--;

            //追踪反射光线
            var ray1    = new Ray(pos, reflectDir);
            var rcolor1 = Trace(ref ray1, scene, depth);

            rcolor1.Multiply(hittest.Shape.Surface.Reflect(pos));

            //追踪折射光线
            var n = hittest.Shape.Surface.Refraction(pos);// 折射率

            if (n > 0)
            {
                if (cosa > 0)
                {
                    n = 1 / n;
                }

                var f = Math.Acos(-cosa);                      //入射角
                var t = Math.Asin(Math.Sqrt(1 - cosa * cosa)); //折射角

                //fresnel公式,计算反射比
                double s1     = Math.Sin(f - t);
                double s2     = Math.Sin(f + t);
                double t1     = Math.Tan(f - t);
                double t2     = Math.Tan(f + t);
                var    factor = (((s1 * s1) / (s2 * s2) + (t1 * t1) / (t2 * t2)) / 2);

                if (factor < 1 && factor >= 0) //等于1时发生了全反射
                {
                    rcolor1.Multiply(factor);

                    //折射定律矢量形式:n2 * e2 - n1 * e1 = (n2 * cos(t) - n1 * cos(f)) * normal
                    var dir = ((n * Math.Cos(t) - Math.Cos(f)) * normal) * (1 / n);
                    dir.Normalize();
                    var ray2 = new Ray(pos, dir);

                    var rcolor2 = Trace(ref ray2, scene, depth);
                    rcolor2.Multiply(1 - factor);
                    color.Add(ref rcolor2);
                }
            }

            color.Add(ref rcolor1);

            return(color);
        }