From 16d14ce7ffc1e70269fda8d375f1da11c3907af8 Mon Sep 17 00:00:00 2001 From: Tim Vaughan Date: Fri, 24 Feb 2023 14:14:25 +0100 Subject: [PATCH] Added image pigment. --- Textures.lua | 53 ++++++++++++++++++++++++++++++++++++++++++++++--- mandel_wall.lua | 34 ++++++++++++++++++++----------- 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/Textures.lua b/Textures.lua index 2b2e701..ccc7dbc 100644 --- a/Textures.lua +++ b/Textures.lua @@ -63,16 +63,63 @@ local function make_solid_pigment(colour) end end -local function make_checkered_pigment(colour1, colour2) +local function make_checkered_pigment(pigment1, pigment2) return function(x,y) if (x%1 < 0.5 and y%1 < 0.5) or (x%1 > 0.5 and y%1 > 0.5) then - return colour1 + return pigment1(x,y) else - return colour2 + return pigment2(x,y) end end end +local function make_image_pigment(filename,scale) + + print("Loading image pigmant from '" .. filename .. "'...") + + local f = assert(io.open(filename, "rb")) + local data = f:read("*all") + f:close() + + local start,_,wstr,hstr,dstr,raster = + string.find(data, "^P6[%s%c]+(%d+)[%s%c]+(%d+)[%s%c]+(%d+)[%s%c](.*)$") + + if start ~= 1 then + error("Error reading image. Is it in PPM(P6) format?") + end + + if dstr ~= "255" then + error("Only images with a depth of 255 are supported.") + end + + local width = tonumber(wstr) + local height = tonumber(hstr) + local depth = tonumber(dstr) + + local pixels = {} + local i = 1 + for triple in string.gmatch(raster, "...") do + local _,_,r,g,b = string.find(triple, "(.)(.)(.)") + pixels[i] = {string.byte(r)/depth, string.byte(g)/depth, string.byte(b)/depth} + i = i + 1 + end + + print("done.") + print("(Read " .. tostring(#pixels) .. " pixels.)") + + local pixels_per_unit = math.max(width,height) + + return function(x,y) + local xi = math.floor(((x+0.5)*pixels_per_unit/scale)%width) + 1 + local yi = math.floor(((y+0.5)*pixels_per_unit/scale)%height) + 1 + local i = width*(yi-1) + xi + if pixels[i] == nil then + error("Pixel not found at xi=" .. tostring(xi) .. " yi=" .. tostring(yi)) + end + return pixels[i] + end +end + local function make_mandelbrot_pigment(set_pigment, nonset_pigment, max_iter) local function get_col(x,y,cx,cy,iter) diff --git a/mandel_wall.lua b/mandel_wall.lua index 127a27b..3c1f741 100644 --- a/mandel_wall.lua +++ b/mandel_wall.lua @@ -12,6 +12,8 @@ local T = Textures require "Render" + + local lights = {V.new{1,-1,1}} local plane_normal = V.normalize(V.new{0.0,-1,0.0}) @@ -19,21 +21,29 @@ local texture_y = V.normalize(V.cross(plane_normal,V.x)) local texture_x = V.cross(texture_y,plane_normal) local scene = { - -- sdf = P.make_plane(V.new{0,0,0}, plane_normal, - -- T.make_phong_texture(lights, - -- T.map_rectangular( - -- T.make_mandelbrot_pigment( - -- T.make_checkered_pigment({0.5,0.2,1.0},{1,1,1}), - -- T.make_checkered_pigment({1,1,1},{0.5,0.2,1.0}), - -- 20), - -- texture_x, texture_y), - -- 0.2, 1.0, 0, 1)), - - sdf = P.make_plane(V.origin, plane_normal, T.make_phong_texture(lights,T.map_rectangular(T.make_solid_pigment({0.5,0.2,1.0}), texture_x, texture_y), 0.2, 1.0, 0.5, 20)), + sdf = P.make_plane(V.new{0,0,0}, plane_normal, + T.make_phong_texture(lights, + T.map_rectangular( + T.make_mandelbrot_pigment( + make_image_pigment("images/wood1.ppm",1), + make_image_pigment("images/wood2.ppm",1), + 20), + texture_x, texture_y), + 0.2, 1.0, 0, 1)), + + -- sdf = P.make_plane(V.origin, plane_normal, + -- T.make_phong_texture( + -- lights, + -- T.map_rectangular( + -- -- T.make_solid_pigment({0.5,0.2,1.0}), + -- T.make_checkered_pigment( + -- make_image_pigment("images/wood1.ppm", 1), + -- make_image_pigment("images/wood2.ppm", 1)), + -- texture_x, texture_y), 0.2, 1.0, 0.5, 20)), camera = {location = V.new{0,-5,0}, point_at = V.new{0,0,0}, right = V.x, fov = 1}} -Render.render(scene, 300, 200, "mandel_wall.ppm") +Render.render(scene, 1280, 960, "mandel_wall.ppm") -- 2.20.1