Ejemplo n.º 1
0
        public Color GetColorOnEntity(Entity.HitResult hitResult, Entity entity, Ray ray)
        {
            var emission   = entity.EntityMaterial.Emission;
            var ambient    = entity.EntityMaterial.Ambient;
            var finalColor = emission.Add(ambient);

            // in case of precision issue
            var checkPoint = hitResult.HitPoint + Epsilon * hitResult.HitNorm;

            foreach (var light in Lights)
            {
                if (!light.HasLightOn(checkPoint, this))
                {
                    continue;
                }

                var lightVec     = light.GetLightVector(hitResult.HitPoint);
                var lightReflect = Vector3.Reflect(lightVec, hitResult.HitNorm);

                var attenuation = light.GetAttenuation(hitResult.HitPoint);
                var diffuse     = light.Diffuse.Moderate(entity.EntityMaterial.Diffuse);
                var specular    = light.Specular.Moderate(entity.EntityMaterial.Specular);

                var diffuseCoef =
                    Math.Max(Vector3.Dot(-Vector3.Normalize(hitResult.HitNorm), Vector3.Normalize(lightVec)), 0);
                var specularCoef =
                    Math.Max(Vector3.Dot(Vector3.Normalize(lightReflect), -Vector3.Normalize(ray.Direction)), 0);
                specularCoef = (float)Math.Pow(specularCoef, entity.EntityMaterial.Shininess);
                var lightColor = diffuse.Multiply(diffuseCoef).Add(specular.Multiply(specularCoef));
                finalColor = finalColor.Add(lightColor.Multiply(attenuation));
            }

            return(finalColor);
        }
Ejemplo n.º 2
0
        public Color GetColor(Ray ray, int maxDepth)
        {
            if (maxDepth == 0)
            {
                return(Color.Black);
            }

            var minDistanceSquared = float.MaxValue;

            Entity.HitResult realHitResult = null;
            Entity           realHitEntity = null;

            foreach (var entity in Entities)
            {
                var hitResult       = entity.GetHitResult(ray);
                var distanceSquared = Vector3.DistanceSquared(hitResult.HitPoint, ray.Origin);
                if (!hitResult.Hit || !(distanceSquared < minDistanceSquared))
                {
                    continue;
                }
                minDistanceSquared = distanceSquared;
                realHitResult      = hitResult;
                realHitEntity      = entity;
            }

            if (realHitResult == null)
            {
                return(Color.Black);
            }

            var baseColor      = Color.Black;
            var reflectedColor = Color.Black;

            if (realHitEntity.EntityMaterial.Reflectivity <= 1 - float.Epsilon)
            {
                baseColor = GetColorOnEntity(realHitResult, realHitEntity, ray);
            }

            if (realHitEntity.EntityMaterial.Reflectivity >= float.Epsilon)
            {
                // in case of precision issue
                var direction    = Vector3.Reflect(ray.Direction, realHitResult.HitNorm);
                var origin       = realHitResult.HitPoint + Epsilon * Vector3.Normalize(realHitResult.HitNorm);
                var reflectedRay = new Ray(origin, direction);

                reflectedColor = GetColor(reflectedRay, maxDepth - 1);
            }

            return(baseColor.Multiply(1 - realHitEntity.EntityMaterial.Reflectivity).Add(
                       reflectedColor.Multiply(realHitEntity.EntityMaterial.Reflectivity)
                       ));
        }