Even though I didn't know about monte carlo path tracing when I wrote this, I accidentally described it. Ironically, monte carlo path tracing is the answer I was looking for at the time.
Naive monte carlo path tracing works by evaluating something called the rendering equation to numerically solve the color value of a pixel. It takes random samples by randomly jittering within a pixel (there are better sampling strategies, and filtering: What is the fundamental reasoning for anti aliasing using multiple random samples within a pixel?) and also by bouncing in random directions when a ray hits a surface.
It can take a lot of samples to give you good results, and with not enough samples, your image will look noisy. It takes 4 times as many samples to cut the noise in half. Render times can be on the order of an hour using 8 modern CPU cores for a simple scene.
There are more advanced monte carlo path tracing techniques that let you get better images more quickly, such as importance sampling, or denoising the image after it's rendered.
Monte carlo path tracing can make photorealistic images and gives you many advanced rendering features just because it follows physical laws so gives realistic results.
You can read more about it here:
http://blog.demofox.org/2016/09/21/path-tracing-getting-started-with-diffuse-and-emissive/
Here is an example image, which took about an hour to render using all 8 of my cpu cores:
