X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;f=raymarch.lua;h=5bace409102cc965b0cd42db6d4b4a63bec6690c;hb=46c1311e546ae5cefc4f596ed13476c649f12f66;hp=d296c2379787ac48a0caebca22fc875b631b92b4;hpb=c86e8c7637a7368950add912b9bce244bbf9e689;p=raymarcher.git diff --git a/raymarch.lua b/raymarch.lua index d296c23..5bace40 100644 --- a/raymarch.lua +++ b/raymarch.lua @@ -4,28 +4,33 @@ local V = Vector require "Primitives" local P = Primitives +require "Operations" +local O = Operations + require "Textures" local T = Textures local eps = 0.01 -local max_dist = 50 -local bg_col = {1,0,1} +local max_dist2 = 20^2 +local bg_col = {0.1,0.1,0.1} local function calculate_normal(sdf, l) local delta = 1e-3; - return -V.new{sdf(l+V.x*delta).dist-sdf(l-V.x*delta).dist, - sdf(l+V.y*delta).dist-sdf(l-V.y*delta).dist, - sdf(l+V.z*delta).dist-sdf(l-V.z*delta).dist}/(2*delta) + return V.new{sdf(l+V.x*delta).dist-sdf(l-V.x*delta).dist, + sdf(l+V.y*delta).dist-sdf(l-V.y*delta).dist, + sdf(l+V.z*delta).dist-sdf(l-V.z*delta).dist}/(2*delta) end -local function march(location, ray_dir, sdf, count) +local function march(start, location, ray_dir, sdf, count) + if V.norm2(location-start) > max_dist2 then + return bg_col + end + local p = sdf(location) if p.dist < eps then return p.texture(location, ray_dir, calculate_normal(sdf, location-(ray_dir*eps)), count) - elseif p.dist > max_dist then - return bg_col else - return march(location + ray_dir*p.dist, + return march(start, location + ray_dir*p.dist, ray_dir, sdf, count+1) end end @@ -41,6 +46,8 @@ local function render(scene, width, height, filename) local right = V.normalize(c.right) local up = V.cross(right,cam_dir) local aspect = height/width; + + local normalize = V.normalize -- optimization for y=1,height do @@ -48,11 +55,11 @@ local function render(scene, width, height, filename) print(y/math.floor(height/10) * 10 .. "%") end - local rayy = cam_dir + up*((y/height - 0.5)*c.fov*aspect) + local rayy = cam_dir + up*((0.5 - y/height)*c.fov*aspect) for x=1,width do - local ray_dir = V.normalize(rayy + right*((x/width - 0.5)*c.fov)) - local col = march(c.location, ray_dir, scene.sdf, 0) + local ray_dir = normalize(rayy + right*((x/width - 0.5)*c.fov)) + local col = march(c.location, c.location, ray_dir, scene.sdf, 0) col = {math.min(col[1]*255, 255), math.min(col[2]*255, 255), math.min(col[3]*255, 255)} @@ -68,9 +75,18 @@ local function render(scene, width, height, filename) print("done") end + + local scene = { - sdf = P.make_sphere(V.new{0,0,0}, 1, - T.make_phong({V.new{2,0,2}}, {0,1,0}, 1.0, 0.5, 100)), + sdf = + O.union( + P.make_sphere(V.new{0,0,0}, 1, + T.make_phong_texture({V.new{2,-3,1}}, + T.make_solid_pigment({0,1,0}), + 0.2, 0.7, 1.0, 100)), + P.make_plane(V.new{0,0,-3.0}, V.new{0,0,1}, + T.make_flat_texture(T.make_checkered_pigment({0,0,1}, {1,1,1})))), + camera = {location = V.new{0,-5,0}, point_at = V.new{0,0,0}, right = V.new{1,0,0},