Replace some custom math functions with stdlib functions.
Some of these didn't exist in stable Rust before, and some of them used to be slower than the custom ones.
This commit is contained in:
parent
89d2831dc8
commit
c5965ec874
|
@ -7,7 +7,7 @@ use std::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lerp::{lerp, lerp_slice, Lerp},
|
lerp::{lerp, lerp_slice, Lerp},
|
||||||
math::{fast_minf32, Point, Transform, Vector},
|
math::{Point, Transform, Vector},
|
||||||
};
|
};
|
||||||
|
|
||||||
const BBOX_MAXT_ADJUST: f32 = 1.000_000_24;
|
const BBOX_MAXT_ADJUST: f32 = 1.000_000_24;
|
||||||
|
@ -47,7 +47,7 @@ impl BBox {
|
||||||
// Find the far and near intersection
|
// Find the far and near intersection
|
||||||
let far_t = t1.max(t2).extend(std::f32::INFINITY);
|
let far_t = t1.max(t2).extend(std::f32::INFINITY);
|
||||||
let near_t = t1.min(t2).extend(0.0);
|
let near_t = t1.min(t2).extend(0.0);
|
||||||
let far_hit_t = fast_minf32(far_t.min_element() * BBOX_MAXT_ADJUST, max_t);
|
let far_hit_t = (far_t.min_element() * BBOX_MAXT_ADJUST).min(max_t);
|
||||||
let near_hit_t = near_t.max_element();
|
let near_hit_t = near_t.max_element();
|
||||||
|
|
||||||
// Did we hit?
|
// Did we hit?
|
||||||
|
|
71
src/math.rs
71
src/math.rs
|
@ -4,73 +4,16 @@ use std::f32;
|
||||||
|
|
||||||
pub use math3d::{cross, dot, CrossProduct, DotProduct, Normal, Point, Transform, Vector};
|
pub use math3d::{cross, dot, CrossProduct, DotProduct, Normal, Point, Transform, Vector};
|
||||||
|
|
||||||
/// Clamps a value between a min and max.
|
|
||||||
pub fn clamp<T: PartialOrd>(v: T, lower: T, upper: T) -> T {
|
|
||||||
if v < lower {
|
|
||||||
lower
|
|
||||||
} else if v > upper {
|
|
||||||
upper
|
|
||||||
} else {
|
|
||||||
v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The stdlib min function is slower than a simple if statement for some reason.
|
|
||||||
pub fn fast_minf32(a: f32, b: f32) -> f32 {
|
|
||||||
if a < b {
|
|
||||||
a
|
|
||||||
} else {
|
|
||||||
b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The stdlib max function is slower than a simple if statement for some reason.
|
|
||||||
pub fn fast_maxf32(a: f32, b: f32) -> f32 {
|
|
||||||
if a > b {
|
|
||||||
a
|
|
||||||
} else {
|
|
||||||
b
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Rounds an integer up to the next power of two.
|
|
||||||
pub fn upper_power_of_two(mut v: u32) -> u32 {
|
|
||||||
v -= 1;
|
|
||||||
v |= v >> 1;
|
|
||||||
v |= v >> 2;
|
|
||||||
v |= v >> 4;
|
|
||||||
v |= v >> 8;
|
|
||||||
v |= v >> 16;
|
|
||||||
v + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the log base 2 of the given integer
|
/// Gets the log base 2 of the given integer
|
||||||
pub fn log2_64(mut value: u64) -> u64 {
|
pub fn log2_64(n: u64) -> u64 {
|
||||||
// This works by doing a binary search for the largest non-zero binary
|
// This works by finding the largest non-zero binary digit in the
|
||||||
// digit in the number. Its bit position is then the log2 of the integer.
|
// number. Its bit position is then the log2 of the integer.
|
||||||
|
|
||||||
let mut log = 0;
|
if n == 0 {
|
||||||
|
0
|
||||||
const POWERS: [(u64, u64); 6] = [
|
} else {
|
||||||
(32, (1 << 32) - 1),
|
(63 - n.leading_zeros()) as u64
|
||||||
(16, (1 << 16) - 1),
|
|
||||||
(8, (1 << 8) - 1),
|
|
||||||
(4, (1 << 4) - 1),
|
|
||||||
(2, (1 << 2) - 1),
|
|
||||||
(1, (1 << 1) - 1),
|
|
||||||
];
|
|
||||||
|
|
||||||
for &(i, j) in &POWERS {
|
|
||||||
let tmp = value >> i;
|
|
||||||
if tmp != 0 {
|
|
||||||
log += i;
|
|
||||||
value = tmp;
|
|
||||||
} else {
|
|
||||||
value &= j;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a coordinate system from a single vector.
|
/// Creates a coordinate system from a single vector.
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crate::{
|
||||||
hash::hash_u32,
|
hash::hash_u32,
|
||||||
hilbert,
|
hilbert,
|
||||||
image::Image,
|
image::Image,
|
||||||
math::{probit, upper_power_of_two},
|
math::probit,
|
||||||
mis::power_heuristic,
|
mis::power_heuristic,
|
||||||
ray::{Ray, RayBatch},
|
ray::{Ray, RayBatch},
|
||||||
scene::{Scene, SceneLightSample},
|
scene::{Scene, SceneLightSample},
|
||||||
|
@ -151,7 +151,7 @@ impl<'a> Renderer<'a> {
|
||||||
let bucket_count_x = ((width / bucket_w) + 1) as u32;
|
let bucket_count_x = ((width / bucket_w) + 1) as u32;
|
||||||
let bucket_count_y = ((height / bucket_h) + 1) as u32;
|
let bucket_count_y = ((height / bucket_h) + 1) as u32;
|
||||||
let larger = cmp::max(bucket_count_x, bucket_count_y);
|
let larger = cmp::max(bucket_count_x, bucket_count_y);
|
||||||
let pow2 = upper_power_of_two(larger);
|
let pow2 = larger.next_power_of_two();
|
||||||
pow2 * pow2
|
pow2 * pow2
|
||||||
};
|
};
|
||||||
for hilbert_d in 0..bucket_n {
|
for hilbert_d in 0..bucket_n {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use glam::Vec4;
|
||||||
use crate::{
|
use crate::{
|
||||||
color::{Color, SpectralSample},
|
color::{Color, SpectralSample},
|
||||||
lerp::{lerp, Lerp},
|
lerp::{lerp, Lerp},
|
||||||
math::{clamp, dot, zup_to_vec, Normal, Vector},
|
math::{dot, zup_to_vec, Normal, Vector},
|
||||||
sampling::cosine_sample_hemisphere,
|
sampling::cosine_sample_hemisphere,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -481,11 +481,11 @@ mod ggx_closure {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate needed dot products
|
// Calculate needed dot products
|
||||||
let na = clamp(dot(nn, aa), -1.0, 1.0);
|
let na = dot(nn, aa).clamp(-1.0, 1.0);
|
||||||
let nb = clamp(dot(nn, bb), -1.0, 1.0);
|
let nb = dot(nn, bb).clamp(-1.0, 1.0);
|
||||||
let ha = clamp(dot(hh, aa), -1.0, 1.0);
|
let ha = dot(hh, aa).clamp(-1.0, 1.0);
|
||||||
let hb = clamp(dot(hh, bb), -1.0, 1.0);
|
let hb = dot(hh, bb).clamp(-1.0, 1.0);
|
||||||
let nh = clamp(dot(nn, hh), -1.0, 1.0);
|
let nh = dot(nn, hh).clamp(-1.0, 1.0);
|
||||||
|
|
||||||
// Calculate F - Fresnel
|
// Calculate F - Fresnel
|
||||||
let col_f = {
|
let col_f = {
|
||||||
|
@ -584,7 +584,7 @@ mod ggx_closure {
|
||||||
// Approximate method
|
// Approximate method
|
||||||
let theta = cos_theta_max.acos();
|
let theta = cos_theta_max.acos();
|
||||||
let hh = (aa + bb).normalized();
|
let hh = (aa + bb).normalized();
|
||||||
let nh = clamp(dot(nn, hh), -1.0, 1.0);
|
let nh = dot(nn, hh).clamp(-1.0, 1.0);
|
||||||
let fac = ggx_d(nh, (1.0f32).min(roughness.sqrt() + (2.0 * theta / PI_32)));
|
let fac = ggx_d(nh, (1.0f32).min(roughness.sqrt() + (2.0 * theta / PI_32)));
|
||||||
|
|
||||||
fac * (1.0f32).min(1.0 - cos_theta_max) * INV_PI
|
fac * (1.0f32).min(1.0 - cos_theta_max) * INV_PI
|
||||||
|
|
Loading…
Reference in New Issue
Block a user