From f385f4b589fc49dc55c3ce4447b4450c3e515123 Mon Sep 17 00:00:00 2001 From: Tim Vaughan Date: Sat, 18 Mar 2023 19:47:27 +0100 Subject: [PATCH] Shifted mandelbulb sdf out to primitives. --- Colours.lua | 12 ++++++++++++ Primitives.lua | 35 +++++++++++++++++++++++++++++++++++ mandelbulb.lua | 45 ++++++--------------------------------------- 3 files changed, 53 insertions(+), 39 deletions(-) create mode 100644 Colours.lua diff --git a/Colours.lua b/Colours.lua new file mode 100644 index 0000000..8a71cbe --- /dev/null +++ b/Colours.lua @@ -0,0 +1,12 @@ +--- Some pre-defined colours + +Colours = { + red = {1,0,0}, + green = {0,1,0}, + blue = {0,0,1}, + yellow = {1,1,0}, + magenta = {1,0,1}, + cyan = {0,1,1} +} + +return Colours diff --git a/Primitives.lua b/Primitives.lua index c13966b..b1efbfb 100644 --- a/Primitives.lua +++ b/Primitives.lua @@ -24,6 +24,41 @@ local function make_pipe(centre, radius, axis, texture) end end +local function make_mandelbulb(centre, max_iter, power, texture) + return function(p) + local z = p - centre + local dr = 1.0 + local r = 0.0 + + for i=1,max_iter do + r = V.norm(z) + if r>2.0 then + break + end + + -- convert to polar coordinates + theta = math.acos(z[3]/r) + phi = math.atan(z[2],z[1]) + dr = math.pow(r, power-1.0)*power*dr + 1.0 + + -- scale and rotate the point + zr = math.pow(r, power) + theta = theta*power + phi = phi*power + + -- convert back to cartesian coordinates + z = V.new{math.sin(theta)*math.cos(phi), + math.sin(phi)*math.sin(theta), + math.cos(theta)} * zr + z = z + p + end + + return {dist = 0.5*math.log(r)*r/dr, + texture = texture} + end +end + + Primitives = { make_sphere = make_sphere, diff --git a/mandelbulb.lua b/mandelbulb.lua index eca6da2..7d7a011 100644 --- a/mandelbulb.lua +++ b/mandelbulb.lua @@ -12,47 +12,14 @@ local T = Textures require "Render" -local function make_mandelbulb(max_iter, power, texture) - return function(p) - local z = V.new(p) - local dr = 1.0 - local r = 0.0 - - for i=1,max_iter do - r = V.norm(z) - if r>2.0 then - break - end - - -- convert to polar coordinates - theta = math.acos(z[3]/r) - phi = math.atan(z[2],z[1]) - dr = math.pow(r, power-1.0)*power*dr + 1.0 - - -- scale and rotate the point - zr = math.pow(r ,power) - theta = theta*power - phi = phi*power - - -- convert back to cartesian coordinates - z = V.new{math.sin(theta)*math.cos(phi), - math.sin(phi)*math.sin(theta), - math.cos(theta)} * zr - z = z + p - end - - return {dist = 0.5*math.log(r)*r/dr, - texture = texture} - end -end local scene = { -- sdf = make_mandelbulb(T.make_count_texture(0.1)), - sdf = make_mandelbulb(100, 8, - T.make_phong_texture( - {V.new{3,-5,3}}, - T.make_solid_pigment{0,0.5,1.0}, - 0.1, 1.0, 0.0, 30)), + sdf = P.make_mandelbulb(V.origin, 100, 8, + T.make_phong_texture( + {V.new{3,-5,3}}, + T.make_solid_pigment{0,0.5,1.0}, + 0.1, 1.0, 0.0, 30)), camera = {location = V.new{0,-5,0}, point_at = V.origin, @@ -61,4 +28,4 @@ local scene = { Render.eps = 0.001 Render.bg_col = {0,0,0} -Render.render(scene, 640, 480, "out/mandelbulb.ppm") +Render.render(scene, 2560, 1440, "out/mandelbulb.ppm") -- 2.20.1