Ejemplo n.º 1
0
 /// <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;
 }
Ejemplo n.º 2
0
        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;
                        }
                    }
                }
            }
        }