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],
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
Dir3::new(
|
||||
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(),
|
||||
)
|
||||
}
|
||||
pub fn transform_normal(&self, pos: Pos3) -> Pos3 {
|
||||
Pos3::new(
|
||||
pub fn inverse_transform_dir(&self, dir: Dir3) -> Dir3 {
|
||||
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[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(),
|
||||
)
|
||||
}
|
||||
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 {
|
||||
Ray::new(
|
||||
|
|
@ -302,7 +333,7 @@ impl Mul<AffineTransform> for AffineTransform {
|
|||
self.mat[2][0] * rhs.mat[0][2]
|
||||
+ self.mat[2][1] * rhs.mat[1][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][1] * rhs.mat[1][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][1] * self.inv[1][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][1] * self.inv[1][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>> {
|
||||
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(
|
||||
pos,
|
||||
|
|
@ -592,7 +596,7 @@ impl<R: Rng> Pbrt<R> {
|
|||
scene: PbrtScene {
|
||||
shapes: Vec::new(),
|
||||
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;
|
||||
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)]
|
||||
|
|
|
|||
|
|
@ -77,11 +77,7 @@ fn quadratic(a: Float, b: Float, c: Float) -> (Option<Float>, Option<Float>) {
|
|||
|
||||
let root_discrim = Float::sqrt(discrim);
|
||||
|
||||
let q = if b < 0.0 {
|
||||
-0.5 * (b - root_discrim)
|
||||
} else {
|
||||
-0.5 * (b + root_discrim)
|
||||
};
|
||||
let q = -0.5 * (b + Float::copysign(root_discrim, b));
|
||||
|
||||
let mut t0 = q / a;
|
||||
let mut t1 = c / q;
|
||||
|
|
@ -124,8 +120,10 @@ fn bilinear_intersection(
|
|||
false
|
||||
})
|
||||
.filter_map(|u| {
|
||||
let uo = patch[0].as_dir() * u + patch[2].as_dir() * (1.0 - u);
|
||||
let ud = patch[1].as_dir() * u + patch[3].as_dir() * (1.0 - u) - uo;
|
||||
// dbg!(a, b, c, u, a * u * u + b * u + c);
|
||||
|
||||
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();
|
||||
|
||||
|
|
@ -133,23 +131,22 @@ fn bilinear_intersection(
|
|||
|
||||
let p2 = perp.length_squared();
|
||||
|
||||
let v1 = deltao.x() * ray.dir().y()
|
||||
+ perp.z()
|
||||
let v1 = deltao.x() * ray.dir().y() * perp.z()
|
||||
+ ray.dir().x() * perp.y() * deltao.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()
|
||||
- perp.x() * ray.dir().y() * deltao.z();
|
||||
|
||||
let t1 = deltao.x() * ud.y()
|
||||
+ perp.z()
|
||||
let t1 = deltao.x() * ud.y() * perp.z()
|
||||
+ ud.x() * perp.y() * deltao.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()
|
||||
- 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))
|
||||
} else {
|
||||
None
|
||||
|
|
@ -220,7 +217,8 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
|
|||
}
|
||||
return Some(Intersection::new(
|
||||
t,
|
||||
(ray.at(t) - Pos3::zero()).normalize(),
|
||||
self.ctm
|
||||
.inverse_transform_normal((ray.at(t).as_dir()).normalize()),
|
||||
Some(UVMaterial {
|
||||
u: phi,
|
||||
v: Float::acos(p.z() / radius),
|
||||
|
|
@ -245,7 +243,7 @@ impl<R: Rng + std::fmt::Debug> Shape<R> {
|
|||
{
|
||||
return Some(Intersection::new(
|
||||
t,
|
||||
Dir3::up(),
|
||||
Dir3::new(0.0, 0.0, 1.0),
|
||||
Some(UVMaterial {
|
||||
u,
|
||||
v,
|
||||
|
|
|
|||
|
|
@ -49,16 +49,7 @@ pub(super) struct SpectrumCheckerboardTexture2d {
|
|||
impl Pbrt2dSpectrumTexture for SpectrumCheckerboardTexture2d {
|
||||
fn get(&self, u: Float, v: Float) -> Color {
|
||||
let (u, v) = self.mapping.map(u, v);
|
||||
|
||||
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
|
||||
};
|
||||
let even = (u.floor() as i64 + v.floor() as i64) % 2 == 0;
|
||||
|
||||
match &self.tex[even as usize] {
|
||||
Either::A(v) => *v,
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ fn main() {
|
|||
Pos3::new(3.0, 4.0, 1.5),
|
||||
Pos3::new(0.5, 0.5, 0.0),
|
||||
Dir3::new(0.0, 0.0, 1.0),
|
||||
Float::to_radians(45.0),
|
||||
Float::to_radians(90.0),
|
||||
);
|
||||
|
||||
let s = &pbrt.scene;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue