How to port smallpt into microstudio
To be honest, this was just an excuse to try out the new post function :P. However, Around a month ago, I released a raytracer as my first project on microstudio. In the comments, gilles commented that it he would 'like' to see smallpt - https://www.kevinbeason.com/smallpt/ - ported into microstudio some day. So let's see how many features we can get into microstudio : ) !
Currently, I know how to do three things - reflection, soft shadows and DOF in a pathtracer. Please note that a pathtracer is just a raytracer but you take a certain number of repeats to the raytracing process and then average the RGB colour between them.
Reflection is done by tracing another ray from the point of intersection in the direction of the reflection vector, which is :
2*normal*dot(normal,ray)-ray
(so the code would look like this to set up a ray before checking object intersections again and then mixing in the new RGB colour)
centrex=intersectx
centrey=intersecty
centrez=intersectz
dot=rayx*normalx+rayy*normaly+rayz*normalz
rayx=2*normalx*dot-rayx
rayy=2*normaly*dot-rayy
rayz=2*normalz*dot-rayz
Soft shadows are done by randomising the light source between certain values each sample. In my raytracer you would just set lightx,lighty and lightz to a random value between certain points for each sample. But for smallpt, we need to distribute the light source in an unbiased circle. Instead of using monte-carlo distribution, this method is much simpler:
unbiaseddistribution=function(radius)
direction=360*random.next()
dist=sqrt(random.next()*radius^2)
outputx=sind(direction)*dist
outputy=cosd(direction)*dist
end
Last of all, DOF (depth of field) is done by connecting a point on the aperture to a point on the focal plane. The aperture is a pinhole opening on a camera. The higher the aperture, the higher the depth of field. So we again use the unbiased circle distribution with the aperture radius. So the code is (where focal length is the focus distance and FOV is the field of view):
getray=function(x,y,apertureradius) //X and y are the 2d positions on the screen
unbiaseddistribution(apertureradius)
rayx=outputx-(focallength*x/FOV) //Connect point on the aperture to point on focal plane
rayy=outputy-(focallength*y/FOV)
dist=sqrt(rayx^2+rayy^2+focallength^2) //Normalise for final ray direction
rayx=rayx/dist
rayy=rayy/dist
rayz=focallength/dist
end
Does anyone know how to do global illumination? Also, please note I just edited the code.