Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local sin = math.sin
- local cos = math.cos
- local tan = math.tan
- local abs = math.abs
- local min = math.min
- local max = math.max
- local floor = math.floor
- local sqrt = math.sqrt
- local clock = os.clock
- -- Threshold values for RGB to RGBI conversion.
- R_THRESHOLD = 0.5
- G_THRESHOLD = 0.5
- B_THRESHOLD = 0.5
- I_THRESHOLD = 0.5
- -- Conversion of 4-bit RGBI to CC colors.
- local palette = {
- colors.black,
- colors.gray,
- colors.blue,
- colors.blue,
- colors.green,
- colors.lime,
- colors.cyan,
- colors.lightBlue,
- colors.red,
- colors.red,
- colors.purple,
- colors.magenta,
- colors.brown,
- colors.yellow,
- colors.lightGray,
- colors.white,
- }
- local function clamp(a, m, n)
- return (a > n) and n or (a < m and m or a)
- end
- -- Convert RGB to 4-bit RGBI index.
- local function rgbtorgbi(r, g, b)
- r = clamp(r, 0, 1)
- g = clamp(g, 0, 1)
- b = clamp(b, 0, 1)
- local R = r > R_THRESHOLD and 1 or 0
- local G = g > G_THRESHOLD and 1 or 0
- local B = b > B_THRESHOLD and 1 or 0
- local I = (r + g + b)/3 > I_THRESHOLD and 1 or 0
- return R * 8 + G * 4 + B * 2 + I
- end
- --[[ Vector functions ]]--
- local function length2(x, y)
- return sqrt(x*x + y*y)
- end
- local function length3(x, y, z)
- return sqrt(x*x + y*y + z*z)
- end
- local function normalize3(x, y, z)
- local len = length3(x, y, z)
- return x/len, y/len, z/len
- end
- local function vec3add(x, y, z, a, b, c)
- return x + a, y + b, z + c
- end
- local function vec3sub(x, y, z, a, b, c)
- return x - a, y - b, z - c
- end
- local function vec3mulscalar(x, y, z, a)
- return x * a, y * a, z * a
- end
- local function vec3abs(x, y, z)
- return abs(x), abs(y), abs(z)
- end
- --[[ Matrix functions ]]
- local function mat2mulvec2(m, x, y)
- return m[1] * x + m[2] * y,
- m[3] * x + m[4] * y
- end
- local function mat3mulvec3(m, x, y, z)
- return m[1] * x + m[2] * y + m[3] * z,
- m[4] * x + m[5] * y + m[6] * z,
- m[7] * x + m[8] * y + m[9] * z
- end
- local function getRotMat2(a)
- return { cos(a), -sin(a), sin(a), cos(a) }
- end
- local function getRotMat3x(a)
- return { 1, 0, 0,
- 0, cos(a), -sin(a),
- 0, sin(a), cos(a) }
- end
- local function getRotMat3y(a)
- return { cos(a), 0, sin(a),
- 0, 1, 0,
- -sin(a), 0, cos(a) }
- end
- local function getRotMat3z(a)
- return { cos(a), -sin(a), 0,
- sin(a), cos(a), 0,
- 0, 0, 1 }
- end
- local w, h = term.getSize()
- --[[ Distance functions ]]--
- local function sphere(x, y, z, r)
- return length3(x, y, z) - r, 0, 1, 0
- end
- local function box(x, y, z, a, b, c)
- return max(max(abs(x) - a, abs(y) - b), abs(z) - c), 1, 0, 0
- end
- -- Place all the models.
- local function map(x, y, z)
- local d1, r1, g1, b1 = sphere(x, y, z, 1)
- local d2, r2, g2, b2 = box(x, y, z, 0.8, 0.8, 0.8)
- local d
- if d1 < d2 then
- return d1, r1, g1, b1
- end
- return d2, r2, g2, b2
- end
- local EPSILON = 0.001
- local MAX_DIST = 10
- local function pixel(x, y)
- -- Fix stretching.
- local u, v = x/w, y/h
- u = u * w/h*2/3
- u = u - w/h*2/3/2
- v = v - 0.5
- -- Rotation
- local rox, roy, roz = mat3mulvec3(getRotMat3y(clock()), 0, 0, -3)
- rox, roy, roz = mat3mulvec3(getRotMat3z(clock()), rox, roy, roz)
- rox, roy, roz = mat3mulvec3(getRotMat3x(clock()), rox, roy, roz)
- local rdx, rdy, rdz = normalize3(u, v, 1)
- rdx, rdy, rdz = mat3mulvec3(getRotMat3y(clock()), rdx, rdy, rdz)
- rdx, rdy, rdz = mat3mulvec3(getRotMat3z(clock()), rdx, rdy, rdz)
- rdx, rdy, rdz = mat3mulvec3(getRotMat3x(clock()), rdx, rdy, rdz)
- -- Raymarching
- local l = 0
- for i = 1, 100 do
- local rx, ry, rz = vec3add(rox, roy, roz, vec3mulscalar(rdx, rdy, rdz, l))
- local d, r, g, b = map(rx, ry, rz)
- if d <= EPSILON then
- return r, g, b
- end
- if l > MAX_DIST then
- return 0, 0, 0
- end
- l = l + d
- end
- return 0, 0, 0
- end
- term.clear()
- local scp = term.setCursorPos
- local sbc = term.setBackgroundColor
- local tw = term.write
- -- Draw the pixels.
- while true do
- for i = 1, w do
- for j = 1, h do
- scp(i, j)
- sbc(palette[rgbtorgbi(pixel(i - 1, j - 1)) + 1])
- tw(" ")
- end
- end
- sleep(0)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement