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); }
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) )); }