X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?a=blobdiff_plain;ds=sidebyside;f=raymarch.lua;h=5bace409102cc965b0cd42db6d4b4a63bec6690c;hb=46c1311e546ae5cefc4f596ed13476c649f12f66;hp=f1dbc3cad42f2c6cf9f64e1f8f85fd812f7f6dc2;hpb=1a83c3fa829a87138827cd937a50f1ef210f7e0b;p=raymarcher.git diff --git a/raymarch.lua b/raymarch.lua index f1dbc3c..5bace40 100644 --- a/raymarch.lua +++ b/raymarch.lua @@ -11,24 +11,26 @@ 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 @@ -44,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 @@ -51,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)} @@ -74,13 +78,14 @@ end local scene = { - sdf = O.union(P.make_sphere(V.new{0,0,0}, 1, - -- T.make_count_texture()), - T.make_phong({V.new{2,-1,2}}, {0,1,0}, - 1.0, 0.5, 100)), - P.make_sphere(V.new{1.5,0,1.0}, 0.5, - T.make_phong({V.new{2,-1,2}}, {0,0,1}, - 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},