public Color3 illuminate(RayContext rayContext, BRDF brdf)
        {
            Ray newRay = new Ray();

            double invPdf = 0;

            //във finalColor ще сумираме резултатния цвят
            Color3 finalColor = new Color3();

            //задаваме максималната бройка лъчи
            //с които ще проследяваме грапави отражения
            int numSamples = 10;
            int curSample = 0;  //номер на текущ лъч

            for (curSample = 0; curSample < numSamples; curSample++)
            {
                //генерирме двойка случайни числа (ru, rv)
                double ru = rayContext.getRandom(0, curSample);
                double rv = rayContext.getRandom(1, curSample);

                //искаме brdf да конструира лъч използвайки (ru, rv)
                bool isValidSample = brdf.getSample(rayContext, ru, rv, out newRay.dir, out invPdf);

                if (!isValidSample)
                    continue;

                //конструираме нов лъч от текущата точка
                //и го обвиваме във собствен контекст
                newRay.p = rayContext.hitData.hitPos;
                RayContext newContext = RayContext.createNewContext(rayContext, newRay);
                //извикваме функцията shade, която проследява
                //лъча в сцената и го осветява
                rayContext.scene.shade(newContext);

                double cosT = rayContext.hitData.hitNormal * (newRay.dir);
                if (cosT < 0.0) cosT *= -1.0;

                double pdf;

                Color3 w = new Color3(1, 1, 1);
                //пресмятаме, каква част от светлината ще отрази BRFD-a
                w = brdf.eval(rayContext, newRay.dir, out pdf);

                if (!brdf.isSingular())
                {
                    w *= cosT * invPdf;
                }
                //добавяме енергията на новия лъч
                finalColor += newContext.resultColor * w;

                //if (Double.IsNaN(finalColor.getIntensity()))
                //    break;

                if (brdf.isSingular())
                    break;
            }

            //сумираме енергията от всички лъчи
            if (curSample > 0)
                finalColor *= 1.0 / (double)curSample;

            return finalColor;
        }