Added mandelbulb!!
[raymarcher.git] / mandelbulb.lua
1 require "Vector"
2 local V = Vector
3
4 require "Primitives"
5 local P = Primitives
6
7 require "Operations"
8 local O = Operations
9
10 require "Textures"
11 local T = Textures
12
13 require "Render"
14
15 local function make_mandelbulb(max_iter, power, texture)
16    return function(p)
17       local z = V.new(p)
18       local dr = 1.0
19       local r = 0.0
20
21       for i=1,max_iter do
22          r = V.norm(z)
23          if r>2.0 then
24             break
25          end
26          
27          -- convert to polar coordinates
28          theta = math.acos(z[3]/r)
29          phi = math.atan(z[2],z[1])
30          dr =  math.pow(r, power-1.0)*power*dr + 1.0
31          
32          -- scale and rotate the point
33          zr = math.pow(r ,power)
34          theta = theta*power
35          phi = phi*power
36          
37          -- convert back to cartesian coordinates
38          z = V.new{math.sin(theta)*math.cos(phi),
39                    math.sin(phi)*math.sin(theta),
40                    math.cos(theta)} * zr
41          z = z + p
42       end
43    
44       return {dist = 0.5*math.log(r)*r/dr,
45               texture = texture}
46    end
47 end
48
49 local scene = {
50    -- sdf = make_mandelbulb(T.make_count_texture(0.1)),
51    sdf = make_mandelbulb(100, 8,
52                          T.make_phong_texture(
53                             {V.new{3,-5,3}},
54                             T.make_solid_pigment{0,0.5,1.0},
55                             0.1, 1.0, 0.0, 30)),
56
57    camera = {location = V.new{0,-5,0},
58              point_at = V.origin,
59              right = V.x,
60              fov = 1}}
61
62 Render.eps = 0.001
63 Render.bg_col = {0,0,0}
64 Render.render(scene, 640, 480, "out/mandelbulb.ppm")