/// <summary> /// Default constructor /// </summary> /// <param name="source">Ray source</param> /// <param name="direction">Ray direction</param> public Ray(Vector3D source, Vector3D direction) { Source = source; direction.Normalize(); Direction = direction; }
private void GetColor(HitInfo info, Light light, ColorAccumulator colorAccu, int count) { Vector3D lightLocation = light.Location; Vector3D lightNormal = info.hitPoint - lightLocation; lightNormal.Normalize(); double lambert = Vector3D.DotProduct(lightNormal, info.normal); if (lambert <= 0) { int r, g, b; r = g = b = 0; int r2 = 0; int g2 = 0; int b2 = 0; info.hitObject.GetColor(info.hitPoint, ref r, ref g, ref b); if (info.hitObject.Material != null) { var objectMaterial = info.hitObject.Material; //Phong if (objectMaterial is SolidColor) { if (InShadow(info, lightLocation, lightNormal)) { return; } double phongTerm = Math.Pow(lambert, 20) * (objectMaterial as SolidColor).Phong * 2 * light.Intensity; r2 = (int)(light.Color.R * phongTerm); g2 = (int)(light.Color.G * phongTerm); b2 = (int)(light.Color.B * phongTerm); var intensityFactor = light.Intensity * -lambert / 255; colorAccu.R += (int)(light.Color.R * r * intensityFactor) + r2; colorAccu.G += (int)(light.Color.G * g * intensityFactor) + g2; colorAccu.B += (int)(light.Color.B * b * intensityFactor) + b2; } //Reflection else if (objectMaterial is Metal) { var metal = objectMaterial as Metal; //double phongTerm = Math.Pow(lambert, 20) * 0.6 * 2 * light.Intensity; //r2 = (int)(light.Color.R * phongTerm); //g2 = (int)(light.Color.G * phongTerm); //b2 = (int)(light.Color.B * phongTerm); double reflet = 2.0f * (Vector3D.DotProduct(info.normal, info.ray.Direction)); Vector3D direction = info.ray.Direction - info.normal * reflet; direction.Normalize(); direction += metal.Fuzz * StaticRandom.RandomVectorInUnitSphere(); //Random in cone //direction.Normalize(); Ray reflect = new Ray(info.hitPoint + direction / 100000, direction); ColorAccumulator reflectedColorAccu = CastRay(reflect, ++count); if (reflectedColorAccu != null) { var attenuation = metal.Reflection * light.Intensity; colorAccu.R += (int)(reflectedColorAccu.R * attenuation) + r2; colorAccu.G += (int)(reflectedColorAccu.G * attenuation) + g2; colorAccu.B += (int)(reflectedColorAccu.B * attenuation) + b2; } } } } }