Пример #1
0
        public Color GetColor()
        {
            int r = 0;
            int g = 0;
            int b = 0;

            var totalRays = _Rays.Count;

            for (int i = 0; i < _Rays.Count; ++i)
            {
                var ray = _Rays.ElementAt(i);

                List <Intersection> intersections = null;

                intersections = (from obj in Scene.Objects
                                 let Ints = obj.Intersects(ray)
                                            where Ints.Distance.HasValue && Ints.Distance.Value > 0
                                            orderby Ints.Distance ascending
                                            select Ints).ToList();

                if (intersections.Count > 0)
                {
                    if (intersections[0].Primitive.IsLight)
                    {
                        r += intersections[0].Primitive.Diffuse.R;
                        g += intersections[0].Primitive.Diffuse.G;
                        b += intersections[0].Primitive.Diffuse.B;
                        continue;
                    }

                    var distance = intersections[0].Distance.Value;
                    var intersection_position = ray.Position + ray.Direction * distance;

                    if (intersections[0].Primitive.Reflect == true)
                    {
                        var rayI = _Rays.ElementAt(i);
                        rayI.Position  = intersection_position;
                        rayI.Direction = Vector3.Reflect(rayI.Direction, intersections[0].Primitive.GetNormal(intersection_position));
                        _Rays[i]       = rayI;
                        --i;
                        continue;
                    }

                    foreach (var light in Scene.Lights)
                    {
                        var vecToLight       = light.Position - intersection_position;
                        var directionToLight = vecToLight;
                        directionToLight.Normalize();

                        var shadowRay = new Ray(intersection_position, directionToLight);

                        var lightRayMag = vecToLight.Length();

                        List <Intersection> shadowRayIntersections = null;

                        shadowRayIntersections = (from obj in Scene.Objects
                                                  let Ints = obj.Intersects(shadowRay)
                                                             where Ints.Distance.HasValue &&
                                                             Ints.Distance.Value > 0 &&
                                                             Ints.Distance < lightRayMag &&
                                                             Ints.Primitive != intersections[0].Primitive
                                                             orderby Ints.Distance ascending
                                                             select Ints).ToList();

                        var shadowValue = shadowRayIntersections.Count + 1;

                        var surfaceNormal = intersections[0].Primitive.GetNormal(intersection_position);

                        float lightIntensity = Vector3.Dot(directionToLight, surfaceNormal) * (1.0f / (vecToLight.LengthSquared()));

                        if (lightIntensity > 0)
                        {
                            r += Convert.ToInt32(intersections[0].Primitive.Diffuse.R * lightIntensity / shadowValue);
                            g += Convert.ToInt32(intersections[0].Primitive.Diffuse.G * lightIntensity / shadowValue);
                            b += Convert.ToInt32(intersections[0].Primitive.Diffuse.B * lightIntensity / shadowValue);
                        }
                    }
                }
                else
                {
                    var sunsetColor = new Color(250, 214, 165);
                    var skyBlue     = new Color(135, 206, 235);

                    var lerpR = (int)MathHelper.Lerp((float)sunsetColor.R, (float)skyBlue.R, ray.Direction.Y);
                    var lerpG = (int)MathHelper.Lerp((float)sunsetColor.G, (float)skyBlue.G, ray.Direction.Y);
                    var lerpB = (int)MathHelper.Lerp((float)sunsetColor.B, (float)skyBlue.B, ray.Direction.Y);
                    r += lerpR;
                    g += lerpG;
                    b += lerpB;
                }
            }

            r /= _Rays.Count;
            g /= _Rays.Count;
            b /= _Rays.Count;

            r = (int)MathHelper.Clamp(r, 0, 255);
            g = (int)MathHelper.Clamp(g, 0, 255);
            b = (int)MathHelper.Clamp(b, 0, 255);

            return(new Color(r, g, b));
        }