Fix bugs for pbrt bilinear patch
This commit is contained in:
parent
bb2089477e
commit
0480e041cd
6 changed files with 85 additions and 33 deletions
|
|
@ -224,6 +224,23 @@ impl AffineTransform {
|
||||||
+ self.mat[2][3],
|
+ self.mat[2][3],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inverse_transform_pos(&self, pos: Pos3) -> Pos3 {
|
||||||
|
Pos3::new(
|
||||||
|
self.inv[0][0] * pos.x()
|
||||||
|
+ self.inv[0][1] * pos.y()
|
||||||
|
+ self.inv[0][2] * pos.z()
|
||||||
|
+ self.inv[0][3],
|
||||||
|
self.inv[1][0] * pos.x()
|
||||||
|
+ self.inv[1][1] * pos.y()
|
||||||
|
+ self.inv[1][2] * pos.z()
|
||||||
|
+ self.inv[1][3],
|
||||||
|
self.inv[2][0] * pos.x()
|
||||||
|
+ self.inv[2][1] * pos.y()
|
||||||
|
+ self.inv[2][2] * pos.z()
|
||||||
|
+ self.inv[2][3],
|
||||||
|
)
|
||||||
|
}
|
||||||
pub fn transform_dir(&self, dir: Dir3) -> Dir3 {
|
pub fn transform_dir(&self, dir: Dir3) -> Dir3 {
|
||||||
Dir3::new(
|
Dir3::new(
|
||||||
self.mat[0][0] * dir.x() + self.mat[0][1] * dir.y() + self.mat[0][2] * dir.z(),
|
self.mat[0][0] * dir.x() + self.mat[0][1] * dir.y() + self.mat[0][2] * dir.z(),
|
||||||
|
|
@ -231,13 +248,27 @@ impl AffineTransform {
|
||||||
self.mat[2][0] * dir.x() + self.mat[2][1] * dir.y() + self.mat[2][2] * dir.z(),
|
self.mat[2][0] * dir.x() + self.mat[2][1] * dir.y() + self.mat[2][2] * dir.z(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
pub fn transform_normal(&self, pos: Pos3) -> Pos3 {
|
pub fn inverse_transform_dir(&self, dir: Dir3) -> Dir3 {
|
||||||
Pos3::new(
|
Dir3::new(
|
||||||
|
self.inv[0][0] * dir.x() + self.inv[0][1] * dir.y() + self.inv[0][2] * dir.z(),
|
||||||
|
self.inv[1][0] * dir.x() + self.inv[1][1] * dir.y() + self.inv[1][2] * dir.z(),
|
||||||
|
self.inv[2][0] * dir.x() + self.inv[2][1] * dir.y() + self.inv[2][2] * dir.z(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn transform_normal(&self, pos: Dir3) -> Dir3 {
|
||||||
|
Dir3::new(
|
||||||
self.inv[0][0] * pos.x() + self.inv[0][1] * pos.y() + self.inv[0][2] * pos.z(),
|
self.inv[0][0] * pos.x() + self.inv[0][1] * pos.y() + self.inv[0][2] * pos.z(),
|
||||||
self.inv[1][0] * pos.x() + self.inv[1][1] * pos.y() + self.inv[1][2] * pos.z(),
|
self.inv[1][0] * pos.x() + self.inv[1][1] * pos.y() + self.inv[1][2] * pos.z(),
|
||||||
self.inv[2][0] * pos.x() + self.inv[2][1] * pos.y() + self.inv[2][2] * pos.z(),
|
self.inv[2][0] * pos.x() + self.inv[2][1] * pos.y() + self.inv[2][2] * pos.z(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
pub fn inverse_transform_normal(&self, pos: Dir3) -> Dir3 {
|
||||||
|
Dir3::new(
|
||||||
|
self.mat[0][0] * pos.x() + self.mat[0][1] * pos.y() + self.mat[0][2] * pos.z(),
|
||||||
|
self.mat[1][0] * pos.x() + self.mat[1][1] * pos.y() + self.mat[1][2] * pos.z(),
|
||||||
|
self.mat[2][0] * pos.x() + self.mat[2][1] * pos.y() + self.mat[2][2] * pos.z(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn transform_ray(&self, ray: Ray) -> Ray {
|
pub fn transform_ray(&self, ray: Ray) -> Ray {
|
||||||
Ray::new(
|
Ray::new(
|
||||||
|
|
@ -302,7 +333,7 @@ impl Mul<AffineTransform> for AffineTransform {
|
||||||
self.mat[2][0] * rhs.mat[0][2]
|
self.mat[2][0] * rhs.mat[0][2]
|
||||||
+ self.mat[2][1] * rhs.mat[1][2]
|
+ self.mat[2][1] * rhs.mat[1][2]
|
||||||
+ self.mat[2][2] * rhs.mat[2][2]
|
+ self.mat[2][2] * rhs.mat[2][2]
|
||||||
+ self.mat[2][3] * rhs.mat[3][3],
|
+ self.mat[2][3] * rhs.mat[3][2],
|
||||||
self.mat[2][0] * rhs.mat[0][3]
|
self.mat[2][0] * rhs.mat[0][3]
|
||||||
+ self.mat[2][1] * rhs.mat[1][3]
|
+ self.mat[2][1] * rhs.mat[1][3]
|
||||||
+ self.mat[2][2] * rhs.mat[2][3]
|
+ self.mat[2][2] * rhs.mat[2][3]
|
||||||
|
|
@ -376,7 +407,7 @@ impl Mul<AffineTransform> for AffineTransform {
|
||||||
rhs.inv[2][0] * self.inv[0][2]
|
rhs.inv[2][0] * self.inv[0][2]
|
||||||
+ rhs.inv[2][1] * self.inv[1][2]
|
+ rhs.inv[2][1] * self.inv[1][2]
|
||||||
+ rhs.inv[2][2] * self.inv[2][2]
|
+ rhs.inv[2][2] * self.inv[2][2]
|
||||||
+ rhs.inv[2][3] * self.inv[3][3],
|
+ rhs.inv[2][3] * self.inv[3][2],
|
||||||
rhs.inv[2][0] * self.inv[0][3]
|
rhs.inv[2][0] * self.inv[0][3]
|
||||||
+ rhs.inv[2][1] * self.inv[1][3]
|
+ rhs.inv[2][1] * self.inv[1][3]
|
||||||
+ rhs.inv[2][2] * self.inv[2][3]
|
+ rhs.inv[2][2] * self.inv[2][3]
|
||||||
|
|
|
||||||
|
|
@ -483,7 +483,11 @@ fn parse_transform(input: &mut Tokenizer) -> Result<AffineTransform> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_translate<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
fn parse_translate<R>(iter: &mut Tokenizer) -> Result<Statement<R>> {
|
||||||
let pos = Pos3::new(iter.parse_next()?, iter.parse_next()?, iter.parse_next()?);
|
let pos = Pos3::new(
|
||||||
|
-iter.parse_next()?,
|
||||||
|
-iter.parse_next()?,
|
||||||
|
-iter.parse_next()?,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(Statement::ConcatTransform(AffineTransform::translation(
|
Ok(Statement::ConcatTransform(AffineTransform::translation(
|
||||||
pos,
|
pos,
|
||||||
|
|
@ -592,7 +596,7 @@ impl<R: Rng> Pbrt<R> {
|
||||||
scene: PbrtScene {
|
scene: PbrtScene {
|
||||||
shapes: Vec::new(),
|
shapes: Vec::new(),
|
||||||
infinite_light: Some(scene::PbrtInfiniteLight {
|
infinite_light: Some(scene::PbrtInfiniteLight {
|
||||||
color: Color::white(),
|
color: Color::new(0.4, 0.45, 0.5),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,34 @@ impl<R: Rng> PbrtMaterial<R> for PbrtDielectricMaterial {
|
||||||
let _ = u;
|
let _ = u;
|
||||||
Color::black()
|
Color::black()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sample(&self, u: Float, v: Float, w_in: Dir3, rng: &mut R) -> SampleResult {
|
||||||
|
let _ = rng;
|
||||||
|
let _ = v;
|
||||||
|
let _ = u;
|
||||||
|
let _ = match self.eta {
|
||||||
|
Either::A(Either::A(eta)) => eta,
|
||||||
|
_ => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// let c = w_in.y();
|
||||||
|
// let w_out = -w_in * eta
|
||||||
|
// + (eta * c - Float::sqrt(1.0 - eta * eta * (1.0 - c * c))) * Dir3::new(0.0, -1.0, 1.0);
|
||||||
|
|
||||||
|
SampleResult::new(
|
||||||
|
Dir3::new(0.0, 2.0 * w_in.y(), 0.0) - w_in,
|
||||||
|
Color::white(),
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pdf(&self, u: Float, v: Float, w_in: Dir3, w_out: Dir3) -> Float {
|
||||||
|
let _ = w_in;
|
||||||
|
let _ = v;
|
||||||
|
let _ = u;
|
||||||
|
let _ = w_out;
|
||||||
|
0.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
||||||
|
|
@ -77,11 +77,7 @@ fn quadratic(a: Float, b: Float, c: Float) -> (Option<Float>, Option<Float>) {
|
||||||
|
|
||||||
let root_discrim = Float::sqrt(discrim);
|
let root_discrim = Float::sqrt(discrim);
|
||||||
|
|
||||||
let q = if b < 0.0 {
|
let q = -0.5 * (b + Float::copysign(root_discrim, b));
|
||||||
-0.5 * (b - root_discrim)
|
|
||||||
} else {
|
|
||||||
-0.5 * (b + root_discrim)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut t0 = q / a;
|
let mut t0 = q / a;
|
||||||
let mut t1 = c / q;
|
let mut t1 = c / q;
|
||||||
|
|
@ -124,8 +120,10 @@ fn bilinear_intersection(
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
.filter_map(|u| {
|
.filter_map(|u| {
|
||||||
let uo = patch[0].as_dir() * u + patch[2].as_dir() * (1.0 - u);
|
// dbg!(a, b, c, u, a * u * u + b * u + c);
|
||||||
let ud = patch[1].as_dir() * u + patch[3].as_dir() * (1.0 - u) - uo;
|
|
||||||
|
let uo = patch[0].as_dir() * (1.0 - u) + patch[2].as_dir() * u;
|
||||||
|
let ud = patch[1].as_dir() * (1.0 - u) + patch[3].as_dir() * u - uo;
|
||||||
|
|
||||||
let deltao = uo - ray.start().as_dir();
|
let deltao = uo - ray.start().as_dir();
|
||||||
|
|
||||||
|
|
@ -133,23 +131,22 @@ fn bilinear_intersection(
|
||||||
|
|
||||||
let p2 = perp.length_squared();
|
let p2 = perp.length_squared();
|
||||||
|
|
||||||
let v1 = deltao.x() * ray.dir().y()
|
let v1 = deltao.x() * ray.dir().y() * perp.z()
|
||||||
+ perp.z()
|
|
||||||
+ ray.dir().x() * perp.y() * deltao.z()
|
+ ray.dir().x() * perp.y() * deltao.z()
|
||||||
+ perp.x() * deltao.y() * ray.dir().z()
|
+ perp.x() * deltao.y() * ray.dir().z()
|
||||||
- deltao.x() * perp.y() * deltao.z()
|
- deltao.x() * perp.y() * ray.dir().z()
|
||||||
- ray.dir().x() * deltao.y() * perp.z()
|
- ray.dir().x() * deltao.y() * perp.z()
|
||||||
- perp.x() * ray.dir().y() * deltao.z();
|
- perp.x() * ray.dir().y() * deltao.z();
|
||||||
|
|
||||||
let t1 = deltao.x() * ud.y()
|
let t1 = deltao.x() * ud.y() * perp.z()
|
||||||
+ perp.z()
|
|
||||||
+ ud.x() * perp.y() * deltao.z()
|
+ ud.x() * perp.y() * deltao.z()
|
||||||
+ perp.x() * deltao.y() * ud.z()
|
+ perp.x() * deltao.y() * ud.z()
|
||||||
- deltao.x() * perp.y() * deltao.z()
|
- deltao.x() * perp.y() * ud.z()
|
||||||
- ud.x() * deltao.y() * perp.z()
|
- ud.x() * deltao.y() * perp.z()
|
||||||
- perp.x() * ud.y() * deltao.z();
|
- perp.x() * ud.y() * deltao.z();
|
||||||
|
|
||||||
if t1 >= min && t1 <= max && 0.0 < v1 && v1 <= p2 {
|
// dbg!(t1 / p2, v1 / p2);
|
||||||
|
if min * p2 <= t1 && t1 <= max * p2 && 0.0 <= v1 && v1 <= p2 {
|
||||||
Some((t1 / p2, u, v1 / p2))
|
Some((t1 / p2, u, v1 / p2))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -220,7 +217,8 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
|
||||||
}
|
}
|
||||||
return Some(Intersection::new(
|
return Some(Intersection::new(
|
||||||
t,
|
t,
|
||||||
(ray.at(t) - Pos3::zero()).normalize(),
|
self.ctm
|
||||||
|
.inverse_transform_normal((ray.at(t).as_dir()).normalize()),
|
||||||
Some(UVMaterial {
|
Some(UVMaterial {
|
||||||
u: phi,
|
u: phi,
|
||||||
v: Float::acos(p.z() / radius),
|
v: Float::acos(p.z() / radius),
|
||||||
|
|
@ -245,7 +243,7 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
|
||||||
{
|
{
|
||||||
return Some(Intersection::new(
|
return Some(Intersection::new(
|
||||||
t,
|
t,
|
||||||
Dir3::up(),
|
Dir3::new(0.0, 0.0, 1.0),
|
||||||
Some(UVMaterial {
|
Some(UVMaterial {
|
||||||
u,
|
u,
|
||||||
v,
|
v,
|
||||||
|
|
|
||||||
|
|
@ -49,16 +49,7 @@ pub(super) struct SpectrumCheckerboardTexture2d {
|
||||||
impl Pbrt2dSpectrumTexture for SpectrumCheckerboardTexture2d {
|
impl Pbrt2dSpectrumTexture for SpectrumCheckerboardTexture2d {
|
||||||
fn get(&self, u: Float, v: Float) -> Color {
|
fn get(&self, u: Float, v: Float) -> Color {
|
||||||
let (u, v) = self.mapping.map(u, v);
|
let (u, v) = self.mapping.map(u, v);
|
||||||
|
let even = (u.floor() as i64 + v.floor() as i64) % 2 == 0;
|
||||||
let even = if u >= 0.0 {
|
|
||||||
u.fract() >= 0.5
|
|
||||||
} else {
|
|
||||||
u.fract() >= -0.5
|
|
||||||
} ^ if v >= 0.0 {
|
|
||||||
v.fract() >= 0.5
|
|
||||||
} else {
|
|
||||||
v.fract() >= -0.5
|
|
||||||
};
|
|
||||||
|
|
||||||
match &self.tex[even as usize] {
|
match &self.tex[even as usize] {
|
||||||
Either::A(v) => *v,
|
Either::A(v) => *v,
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ fn main() {
|
||||||
Pos3::new(3.0, 4.0, 1.5),
|
Pos3::new(3.0, 4.0, 1.5),
|
||||||
Pos3::new(0.5, 0.5, 0.0),
|
Pos3::new(0.5, 0.5, 0.0),
|
||||||
Dir3::new(0.0, 0.0, 1.0),
|
Dir3::new(0.0, 0.0, 1.0),
|
||||||
Float::to_radians(45.0),
|
Float::to_radians(90.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
let s = &pbrt.scene;
|
let s = &pbrt.scene;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue