added tsm scene; smoothunion, more transforms, fix mat3 product; expose problem with lua api
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
@@ -70,7 +70,7 @@ local function randomtorus()
|
||||
local thickness = util.randab(radius/4, radius)
|
||||
local orientation = randomorientation()
|
||||
|
||||
return obj.affinetransform(obj.torus(pos, radius, thickness), orientation, vec3.O)
|
||||
return util.transform(obj.torus(pos, radius, thickness), orientation)
|
||||
end
|
||||
|
||||
local function randomcuboid()
|
||||
@@ -86,13 +86,12 @@ local function randomcylinder()
|
||||
local height = util.randab(0, SCALE)
|
||||
local orientation = randomorientation()
|
||||
|
||||
return obj.affinetransform(
|
||||
return util.transform(
|
||||
obj.intersection(
|
||||
obj.cylinder(pos, radius),
|
||||
obj.cuboid(pos, vec3.new(radius, height, radius))
|
||||
),
|
||||
orientation,
|
||||
vec3.O
|
||||
orientation
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
-- Scene developed by TSM71
|
||||
-- Also this took 30 hours to render
|
||||
|
||||
local COLOR_BLACK = colorvec.new(0, 0, 0, 0)
|
||||
|
||||
local GRAY = material.newfromdiagonal(
|
||||
COLOR_BLACK,
|
||||
colorvec.new(0.5, 0.5, 0.5, 0.5),
|
||||
surfacetype.DIFFUSE
|
||||
)
|
||||
local CYAN = material.newfromdiagonal(
|
||||
COLOR_BLACK,
|
||||
colorvec.new(0, 1, 1, 0),
|
||||
surfacetype.DIFFUSE
|
||||
)
|
||||
local PINK = material.newfromdiagonal(
|
||||
COLOR_BLACK,
|
||||
colorvec.new(1, .5, .5, 0),
|
||||
surfacetype.DIFFUSE
|
||||
)
|
||||
local RED = material.newfromdiagonal(
|
||||
COLOR_BLACK,
|
||||
colorvec.new(1, 0, 0, 0),
|
||||
surfacetype.DIFFUSE
|
||||
)
|
||||
local MAGENTA = material.newfromdiagonal(
|
||||
COLOR_BLACK,
|
||||
colorvec.new(1, 0, 1, 0),
|
||||
surfacetype.DIFFUSE
|
||||
)
|
||||
local MIRROR = material.newfromdiagonal(
|
||||
COLOR_BLACK,
|
||||
colorvec.new(1, 1, 1, 1),
|
||||
surfacetype.REFLECTIVE
|
||||
)
|
||||
local FLUORESCENT = material.new(
|
||||
COLOR_BLACK,
|
||||
colormat.new(
|
||||
.25, 0, 0, .25,
|
||||
0, .25, 0, .75,
|
||||
0, 0, .25, 0,
|
||||
0, 0, 0, 0
|
||||
),
|
||||
surfacetype.DIFFUSE
|
||||
)
|
||||
|
||||
--[[
|
||||
obj.transformaround = function(a, b, c)
|
||||
return util.translate(
|
||||
util.transform(
|
||||
util.translate(
|
||||
a,
|
||||
-c
|
||||
),
|
||||
b
|
||||
),
|
||||
c
|
||||
)
|
||||
end
|
||||
--]]
|
||||
--obj.transformaround = function(a, _b, _c) return a end
|
||||
--obj.affinetransform = function(a, _b, _c) return a end
|
||||
--obj.smoothunion = function(a, b, _r) return obj.union(a, b) end
|
||||
---[[
|
||||
util.stacktransforms = function(list)
|
||||
--do return list[1] end
|
||||
--do return list[#list] end
|
||||
local n = #list
|
||||
local a = mat3.I
|
||||
--for i=n, 1, -1 do
|
||||
for i=1, n do
|
||||
a = list[i] * a
|
||||
--a = a * list[i]
|
||||
end
|
||||
return a
|
||||
end
|
||||
--]]
|
||||
|
||||
return obj.withlights(
|
||||
obj.transformaround(
|
||||
obj.withlights(
|
||||
util.union({
|
||||
util.intersection({
|
||||
util.union({
|
||||
obj.withmaterial(
|
||||
obj.negation(
|
||||
util.union({
|
||||
obj.cuboid(vec3.new(0, 0, 0), vec3.new(.5, 1, 4)),
|
||||
obj.cuboid(vec3.new(0, 0, 0), vec3.new(4, 1, .5))
|
||||
})
|
||||
),
|
||||
GRAY
|
||||
),
|
||||
obj.withmaterial(
|
||||
util.intersection({
|
||||
util.union({
|
||||
obj.cuboid(vec3.new(0, 1, 0), vec3.new(.4, .1, 3.9)),
|
||||
obj.cuboid(vec3.new(0, 1, 0), vec3.new(3.9, .1, .4))
|
||||
}),
|
||||
obj.negation(
|
||||
util.union({
|
||||
obj.cuboid(vec3.new(0, 1, 0), vec3.new(.3, 1, 3.8)),
|
||||
obj.cuboid(vec3.new(0, 1, 0), vec3.new(3.8, 1, .3))
|
||||
})
|
||||
)
|
||||
}),
|
||||
FLUORESCENT
|
||||
),
|
||||
obj.smoothunion(
|
||||
obj.withmaterial(
|
||||
obj.sphere(vec3.new(0, .75, 0), .25),
|
||||
CYAN
|
||||
),
|
||||
obj.withmaterial( -- withdynamicmaterial
|
||||
obj.sphere(vec3.new(-.5, .5, 0), .25),
|
||||
MAGENTA --dynamicmaterial.missingtexture(vec3.new(-.5, .5, 0))
|
||||
),
|
||||
.5
|
||||
)
|
||||
}),
|
||||
obj.withmaterial(
|
||||
obj.negation(
|
||||
obj.cuboid(vec3.new(0, 0, 0), vec3.new(2, .25, 2))
|
||||
),
|
||||
PINK
|
||||
)
|
||||
}),
|
||||
obj.withmaterial(
|
||||
obj.cylinder(vec3.new(1, 0, 0), .375),
|
||||
RED
|
||||
),
|
||||
util.transform(
|
||||
obj.withmaterial(
|
||||
obj.torus(vec3.new(0, 0, -1), .375, .125),
|
||||
MIRROR
|
||||
),
|
||||
transform.SWAPYZ
|
||||
)
|
||||
}),
|
||||
{
|
||||
light.new(vec3.new(.45, 1-.2, -.45), colorvec.new(0, 0, 0, .1)),
|
||||
--light.new(vec3.new(.45, 1-.2, -.45), colorvec.new(0, 0, 0, 1)),
|
||||
}
|
||||
),
|
||||
util.stacktransforms({
|
||||
transform.scalexyz(1, -1, 1),
|
||||
transform.rotatez(10*math.pi/180),
|
||||
}),
|
||||
vec3.new(0, 0, -1.5)
|
||||
),
|
||||
{
|
||||
light.new(vec3.new(0, .9375, 0), colorvec.new(.5, .25, 0, 0)),
|
||||
light.new(vec3.new(0, .9375, -.625), colorvec.new(0, 0, 1, 0)),
|
||||
--light.new(vec3.new(0, .9375, 0), colorvec.new(5, 2.5, 0, 0)),
|
||||
--light.new(vec3.new(0, .9375, -.625), colorvec.new(0, 0, 10, 0)),
|
||||
}
|
||||
)
|
||||
+8
-8
@@ -20,21 +20,21 @@ pub const ANGLE_POWER: f64 = 2.;
|
||||
//pub const IMG_WIDTH: usize = 480;
|
||||
//pub const IMG_WIDTH: usize = 1280;
|
||||
//pub const IMG_WIDTH: usize = 1080;
|
||||
//pub const IMG_WIDTH: usize = 1920;
|
||||
pub const IMG_WIDTH: usize = 4961;
|
||||
pub const IMG_WIDTH: usize = 1920;
|
||||
//pub const IMG_WIDTH: usize = 4961;
|
||||
//pub const IMG_HEIGHT: usize = 480;
|
||||
//pub const IMG_HEIGHT: usize = 720;
|
||||
//pub const IMG_HEIGHT: usize = 1080;
|
||||
pub const IMG_HEIGHT: usize = 3508;
|
||||
pub const IMG_HEIGHT: usize = 1080;
|
||||
//pub const IMG_HEIGHT: usize = 3508;
|
||||
pub const IMG_DIM: usize = if IMG_HEIGHT > IMG_WIDTH { IMG_HEIGHT } else { IMG_WIDTH };
|
||||
pub const IMG_SIZE: usize = IMG_WIDTH * IMG_HEIGHT;
|
||||
pub const IMG_BYTE_SIZE: usize = IMG_SIZE * 3;
|
||||
|
||||
pub const SUPERSAMPLING: usize = 1;
|
||||
//pub const SUPERSAMPLING: usize = 2;
|
||||
pub const RAYS_PER_PIXEL: usize = 1;
|
||||
//pub const SUPERSAMPLING: usize = 1;
|
||||
pub const SUPERSAMPLING: usize = 2;
|
||||
//pub const RAYS_PER_PIXEL: usize = 1;
|
||||
//pub const RAYS_PER_PIXEL: usize = 50;
|
||||
//pub const RAYS_PER_PIXEL: usize = 500;
|
||||
pub const RAYS_PER_PIXEL: usize = 500;
|
||||
//pub const MAX_BOUNCES: u32 = 1;
|
||||
//pub const MAX_BOUNCES: u32 = 4;
|
||||
//pub const MAX_BOUNCES: u32 = 8;
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ impl UserData for Mat3 {
|
||||
methods.add_meta_method(MetaMethod::Sub, |ctx, a: &Self, b: Self| Ok(*a-b));
|
||||
methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: Self| Ok(*a*b));
|
||||
methods.add_meta_method(MetaMethod::Unm, |ctx, a: &Self, b: ()| Ok(-*a));
|
||||
methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: f64| Ok(*a*b));
|
||||
//methods.add_meta_method(MetaMethod::Mul, |ctx, a: &Self, b: f64| Ok(*a*b)); //TODO find a way to make it cohabit
|
||||
methods.add_meta_method(MetaMethod::Div, |ctx, a: &Self, b: f64| Ok(*a/b));
|
||||
|
||||
methods.add_method("a", |ctx, x, ()| Ok(x.a()));
|
||||
|
||||
@@ -54,6 +54,10 @@ pub fn obj<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'l
|
||||
|ctx, (normal, offset): (Vec3, f64)| LuaObject::new(Plane::new(normal, offset))
|
||||
)?)?;
|
||||
|
||||
module.set("smoothunion", ctx.create_function(
|
||||
|ctx, (a, b, r): (LuaObject, LuaObject, f64)| LuaObject::new(SmoothUnion::new(a.get(), b.get(), r))
|
||||
)?)?;
|
||||
|
||||
module.set("sphere", ctx.create_function(
|
||||
|ctx, (pos, radius): (Vec3, f64)| LuaObject::new(Sphere::new(pos, radius))
|
||||
)?)?;
|
||||
@@ -66,6 +70,10 @@ pub fn obj<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'l
|
||||
|ctx, (obj, trans, disp): (LuaObject, Mat3, Vec3)| LuaObject::new(AffineTransform::new(obj.get(), trans, disp))
|
||||
)?)?;
|
||||
|
||||
module.set("transformaround", ctx.create_function(
|
||||
|ctx, (obj, trans, center): (LuaObject, Mat3, Vec3)| LuaObject::new(TransformAround::new(obj.get(), trans, center))
|
||||
)?)?;
|
||||
|
||||
module.set("union", ctx.create_function(
|
||||
|ctx, (a, b): (LuaObject, LuaObject)| LuaObject::new(Union::new(a.get(), b.get()))
|
||||
)?)?;
|
||||
|
||||
+17
-3
@@ -1,5 +1,5 @@
|
||||
use rlua::{Context, Table, Error};
|
||||
use crate::object::{SWAP_XY, SWAP_YZ, SWAP_XZ, scale_xyz, scale, scale_x, scale_y, scale_z};
|
||||
use rlua::{Context, Table};
|
||||
use crate::object::{SWAP_XY, SWAP_YZ, SWAP_XZ, scale_xyz, scale, scale_x, scale_y, scale_z, rotate_xyz, rotate_x, rotate_z, rotate_y};
|
||||
use crate::structs::{Mat3, I3};
|
||||
|
||||
pub fn transform<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Table<'lua>> {
|
||||
@@ -26,11 +26,25 @@ pub fn transform<'lua>(ctx: Context<'lua>, _env: Table<'lua>) -> rlua::Result<Ta
|
||||
|ctx, k| Ok(scale_z(k))
|
||||
)?)?;
|
||||
|
||||
module.set("rotatexyz", ctx.create_function(
|
||||
|ctx, (x, y, z)| Ok(rotate_xyz(x, y, z))
|
||||
)?)?;
|
||||
|
||||
module.set("rotatex", ctx.create_function(
|
||||
|ctx, a| Ok(rotate_x(a))
|
||||
)?)?;
|
||||
module.set("rotatey", ctx.create_function(
|
||||
|ctx, a| Ok(rotate_y(a))
|
||||
)?)?;
|
||||
module.set("rotatez", ctx.create_function(
|
||||
|ctx, a| Ok(rotate_z(a))
|
||||
)?)?;
|
||||
|
||||
module.set("stack", ctx.create_function(
|
||||
|ctx, transforms: Vec<Mat3>| {
|
||||
let mut acc = I3;
|
||||
for trans in transforms.iter().rev().cloned() {
|
||||
acc = trans * I3;
|
||||
acc = acc * trans;
|
||||
}
|
||||
Ok(acc)
|
||||
}
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ function M.transform(object, mat)
|
||||
return obj.affinetransform(object, mat, vec3.O)
|
||||
end
|
||||
function M.translate(object, vec)
|
||||
return obj.affinetransform(object, mat3.O, vec)
|
||||
return obj.affinetransform(object, mat3.I, vec)
|
||||
end
|
||||
|
||||
return M
|
||||
+3
-2
@@ -85,9 +85,10 @@ fn default_scene3() -> Scene {
|
||||
|
||||
fn main() {
|
||||
// get scene and camera
|
||||
let scene = scene_from_file("scenes/randomspheres.lua".to_owned()).unwrap();
|
||||
let scene = scene_from_file("scenes/tsm.lua".to_owned()).unwrap();
|
||||
//let scene = default_scene3();
|
||||
let cam = default_cam();
|
||||
let cam = Cam::new(Z * -1.5, Z, f64::sqrt(2.));
|
||||
//let cam = default_cam();
|
||||
|
||||
// get stats on the scene we're about to render
|
||||
let total_rpp = (RAYS_PER_PIXEL * SUPERSAMPLING * SUPERSAMPLING) as u64;
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::vec::Vec;
|
||||
mod sphere;
|
||||
mod plane;
|
||||
mod union;
|
||||
mod smoothunion;
|
||||
mod intersection;
|
||||
mod exclusion;
|
||||
mod negation;
|
||||
@@ -64,6 +65,7 @@ impl<T: 'static + Obj + Clone> ObjClone for T {
|
||||
pub use sphere::Sphere;
|
||||
pub use plane::Plane;
|
||||
pub use union::Union;
|
||||
pub use smoothunion::SmoothUnion;
|
||||
pub use intersection::Intersection;
|
||||
pub use exclusion::Exclusion;
|
||||
pub use negation::Negation;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
use crate::object::Obj;
|
||||
use crate::light::Light;
|
||||
use crate::structs::Vec3;
|
||||
use std::vec;
|
||||
use crate::material::Material;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct SmoothUnion<A: Obj, B: Obj> {
|
||||
a: A,
|
||||
b: B,
|
||||
r: f64
|
||||
}
|
||||
|
||||
impl<A: Obj, B: Obj> SmoothUnion<A, B> {
|
||||
pub fn new(a: A, b: B, r: f64) -> SmoothUnion<A, B> {
|
||||
SmoothUnion { a, b, r }
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Obj, B: Obj> Obj for SmoothUnion<A, B> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
let d1 = self.a.distance_to(point);
|
||||
let d2 = self.b.distance_to(point);
|
||||
let h = f64::max(self.r - f64::abs(d1-d2),0.);
|
||||
d1.min(d2) - h*h*0.25 / self.r
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
if self.a.distance_to(point) < self.b.distance_to(point) {
|
||||
self.a.material_at(point)
|
||||
} else {
|
||||
self.b.material_at(point)
|
||||
}
|
||||
}
|
||||
fn get_lights(&self) -> vec::Vec<Light> {
|
||||
let mut l = self.a.get_lights();
|
||||
l.extend(self.b.get_lights());
|
||||
l
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.a.node_count() + self.b.node_count() + 1
|
||||
}
|
||||
}
|
||||
+80
-3
@@ -14,10 +14,10 @@ pub struct AffineTransform<T: Obj + Clone> {
|
||||
|
||||
impl<T: Obj + Clone> AffineTransform<T> {
|
||||
pub fn new(obj: T, transform: Mat3, translate: Vec3) -> AffineTransform<T> {
|
||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate, scale: transform.det().cbrt() }
|
||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate, scale: transform.det().abs().cbrt() }
|
||||
}
|
||||
pub fn new_linear(obj: T, transform: Mat3) -> AffineTransform<T> {
|
||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O, scale: transform.det().cbrt() }
|
||||
AffineTransform { obj, transform, transform_inv: transform.invert(), translate: O, scale: transform.det().abs().cbrt() }
|
||||
}
|
||||
pub fn new_translate(obj: T, translate: Vec3) -> AffineTransform<T> {
|
||||
AffineTransform { obj, transform: I3, transform_inv: I3, translate, scale: 1. }
|
||||
@@ -59,6 +59,37 @@ pub const fn scale_x(k: f64) -> Mat3 { scale_xyz(k, 1., 1.) }
|
||||
pub const fn scale_y(k: f64) -> Mat3 { scale_xyz(1., k, 1.) }
|
||||
pub const fn scale_z(k: f64) -> Mat3 { scale_xyz(1., 1., k) }
|
||||
|
||||
pub fn rotate_x(a: f64) -> Mat3 {
|
||||
let c = a.cos();
|
||||
let s = a.sin();
|
||||
Mat3::new(
|
||||
1., 0., 0.,
|
||||
0., c, -s,
|
||||
0., s, c
|
||||
)
|
||||
}
|
||||
pub fn rotate_y(a: f64) -> Mat3 {
|
||||
let c = a.cos();
|
||||
let s = a.sin();
|
||||
Mat3::new(
|
||||
c, 0., s,
|
||||
0., 1., 0.,
|
||||
-s, 0., c
|
||||
)
|
||||
}
|
||||
pub fn rotate_z(a: f64) -> Mat3 {
|
||||
let c = a.cos();
|
||||
let s = a.sin();
|
||||
Mat3::new(
|
||||
c, -s, 0.,
|
||||
s, c, 0.,
|
||||
0., 0., 1.
|
||||
)
|
||||
}
|
||||
pub fn rotate_xyz(x: f64, y: f64, z: f64) -> Mat3 {
|
||||
rotate_z(z) * rotate_y(y) * rotate_x(x)
|
||||
}
|
||||
|
||||
impl<T: Obj + Clone> Obj for AffineTransform<T> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.obj.distance_to(self.apply_rev(point)) * self.scale
|
||||
@@ -81,4 +112,50 @@ impl<T: Obj + Clone> Obj for AffineTransform<T> {
|
||||
fn node_count(&self) -> u32 {
|
||||
self.obj.node_count() + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct TransformAround<T: Obj + Clone> {
|
||||
obj: T,
|
||||
transform: Mat3,
|
||||
transform_inv: Mat3,
|
||||
center: Vec3,
|
||||
scale: f64
|
||||
}
|
||||
|
||||
impl<T: Obj + Clone> TransformAround<T> {
|
||||
pub fn new(obj: T, transform: Mat3, center: Vec3) -> TransformAround<T> {
|
||||
TransformAround { obj, transform, transform_inv: transform.invert(), center, scale: transform.det().abs().cbrt() }
|
||||
}
|
||||
|
||||
fn apply_rev(&self, point: Vec3) -> Vec3 {
|
||||
self.transform_inv * (point + self.center) - self.center
|
||||
}
|
||||
fn apply_fwd(&self, point: Vec3) -> Vec3 {
|
||||
self.transform * (point - self.center) + self.center
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Obj + Clone> Obj for TransformAround<T> {
|
||||
fn distance_to(&self, point: Vec3) -> f64 {
|
||||
self.obj.distance_to(self.apply_rev(point)) * self.scale
|
||||
}
|
||||
fn normal_at(&self, point: Vec3) -> Vec3 {
|
||||
self.apply_fwd(self.obj.normal_at(self.apply_rev(point))).unit()
|
||||
}
|
||||
fn material_at(&self, point: Vec3) -> Material {
|
||||
self.obj.material_at(self.apply_rev(point))
|
||||
}
|
||||
fn get_lights(&self) -> Vec<Light> {
|
||||
self.obj
|
||||
.get_lights()
|
||||
.into_iter()
|
||||
.map(|light| {
|
||||
Light::new(self.apply_fwd(light.pos()), light.color())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
fn node_count(&self) -> u32 {
|
||||
self.obj.node_count() + 1
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -137,7 +137,7 @@ impl Mul<Mat3> for Mat3 {
|
||||
|
||||
d: self.d*other.a + self.e*other.d + self.f*other.g,
|
||||
e: self.d*other.b + self.e*other.e + self.f*other.h,
|
||||
f: self.d*other.c + self.e*other.f + self.e*other.i,
|
||||
f: self.d*other.c + self.e*other.f + self.f*other.i,
|
||||
|
||||
g: self.g*other.a + self.h*other.d + self.i*other.g,
|
||||
h: self.g*other.b + self.h*other.e + self.i*other.h,
|
||||
|
||||
Reference in New Issue
Block a user