예제 #1
0
        /// <summary>
        /// Trace single ray in a given direction.
        /// </summary>
        /// <param name="origin"></param>
        /// <param name="direction"></param>
        /// <param name="depth">Current recursion level.</param>
        /// <param name="lastReflected">The object from ray was cast.</param>
        /// <returns></returns>
        Color TraceSingleRay(Vector <double> origin, Vector <double> direction, uint depth = 0, ICollidable lastReflected = null)
        {
            if (depth >= MaxDepth)
            {
                return(Skybox.GetColorInDirection(direction));
            }

            var nearest = GetNearestEntity(origin, direction, lastReflected);

            // If nearest entity is null it means that ray hasn't collide with anything
            if (nearest.Entity == null)
            {
                return(Skybox.GetColorInDirection(direction) * new Color(0.5, 0.5, 0.5));
            }

            // Point of collision.
            var point = origin + nearest.Distance * direction;

            var entity = nearest.Entity;

            var material = entity.Material;
            var fragment = entity.GetMaterialFragmentInPoint(point);

            var localColor   = material.GetColor(fragment);
            var diffuseColor = GetDiffuseColor(entity, point);

            // If reflection coefficient is zero no further casting is needed
            var reflectionColor = Color.Zero;

            if (material.ReflectionCoefficient > double.Epsilon)
            {
                reflectionColor = GetReflectionColor(entity, point, direction, depth);
            }


            return(localColor * (diffuseColor + material.ReflectionCoefficient * reflectionColor));
        }