private Vector3 CalcReflection(HitPoint hp, Vector3 OP, RenderSettings settings, int depth, float reflectionDecay) { if (!hp.IsHit()) { return(_baseColor); } if (depth >= REFLECTION_LIMIT) { return(Vector3.Zero); } if (_spheres[hp.SphereIndex].ReflectionFactor <= 0.0f) { return(Vector3.Zero); } var position = hp.Position; var n = Vector3.Normalize(position - _spheres[hp.SphereIndex].Center); var r = Vector3.Reflect(hp.Direction, n); var H = position + n * 0.01f; var hp2 = _spheres.GetHitPoint(r, H); if (!hp2.IsHit()) { return(_baseColor); } return(_spheres[hp.SphereIndex].ReflectionFactor * reflectionDecay * CalcColor(hp2, settings) + CalcReflection(hp2, H, settings, depth + 1, reflectionDecay * reflectionDecay)); }
private Vector3 CalcColor(HitPoint hp, RenderSettings settings) { if (!hp.IsHit()) { return(_baseColor); } var sphere = _spheres[hp.SphereIndex]; var position = hp.Position; var n = Vector3.Normalize(position - sphere.Center); var colorDiffuse = Vector3.Zero; var colorSpecular = Vector3.Zero; foreach (var light in _lights) { var l = Vector3.Normalize(light.Position - position); var r = 2 * Vector3.Dot(l, n) * n - l; var cosTheta = Vector3.Dot(n, l); if (cosTheta >= 0) { // Diffuse lighting if (settings.Diffuse) { Vector3 diff = light.Color * cosTheta * sphere.GetColor(n); if (settings.Shadow) { diff *= CalcShadowFactor(position + n * 0.01f, light); } colorDiffuse += diff; } // Specular lighting if (settings.Specular) { var alpha = Vector3.Dot(r, Vector3.Normalize(position - hp.Origin)); if (alpha < 0) { colorSpecular += light.Color * (float)Math.Abs(Math.Pow(alpha, K)); } } } } return(sphere.Emission + colorDiffuse + colorSpecular); }