Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
c5965ec874 | |||
89d2831dc8 |
22
README.md
22
README.md
|
@ -13,7 +13,9 @@ efficiently handle very large data sets, complex shading, motion blur, color
|
|||
management, etc. presents a much richer and more challenging problem space to
|
||||
explore than just writing a basic path tracer.
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
Psychopath is written in [Rust](https://www.rust-lang.org), and is pretty
|
||||
straightforward to build except for its OpenEXR dependency.
|
||||
|
||||
|
@ -34,6 +36,7 @@ documented in the [OpenEXR-rs readme](https://github.com/cessen/openexr-rs/blob/
|
|||
Once those environment variables are set, then you should be able to build using
|
||||
the same simple cargo command above.
|
||||
|
||||
|
||||
# PsychoBlend
|
||||
|
||||
Included in the repository is an add-on for [Blender](http://www.blender.org)
|
||||
|
@ -50,15 +53,6 @@ doesn't support them yet.
|
|||
- Exports dupligroups with full hierarchical instancing
|
||||
- Limited auto-detection of instanced meshes
|
||||
|
||||
# Contributing
|
||||
|
||||
I'm not looking for contributions right now, and I'm likely to reject pull
|
||||
requests. This is currently a solo project and I like it that way.
|
||||
|
||||
However, if you're looking for projects _related_ to Psychopath to contribute to,
|
||||
[OpenEXR-rs](https://github.com/cessen/openexr-rs) is definitely a
|
||||
collaborative project that I would love more help with! And I fully expect more
|
||||
such projects to come out of Psychopath in the future.
|
||||
|
||||
# License
|
||||
|
||||
|
@ -69,3 +63,13 @@ See LICENSE.md for details. But the gist is:
|
|||
* Most crates under the `sub_crates` directory are dual-licensed under MIT and Apache 2.0 (but with some exceptions--see each crate for its respective licenses).
|
||||
|
||||
The intent of this scheme is to keep Psychopath itself copyleft, while allowing smaller reusable components to be licensed more liberally.
|
||||
|
||||
|
||||
# Contributing
|
||||
|
||||
This is a personal, experimental, for-fun project, and I am specifically
|
||||
not looking for contributions of any kind. All PRs will be rejected
|
||||
without review.
|
||||
|
||||
However, feel free to fork this into an entirely new project, or examine
|
||||
the code for ideas for a project of your own.
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::{
|
|||
|
||||
use crate::{
|
||||
lerp::{lerp, lerp_slice, Lerp},
|
||||
math::{fast_minf32, Point, Transform, Vector},
|
||||
math::{Point, Transform, Vector},
|
||||
};
|
||||
|
||||
const BBOX_MAXT_ADJUST: f32 = 1.000_000_24;
|
||||
|
@ -47,7 +47,7 @@ impl BBox {
|
|||
// Find the far and near intersection
|
||||
let far_t = t1.max(t2).extend(std::f32::INFINITY);
|
||||
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();
|
||||
|
||||
// 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};
|
||||
|
||||
/// 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
|
||||
pub fn log2_64(mut value: u64) -> u64 {
|
||||
// This works by doing a binary search for the largest non-zero binary
|
||||
// digit in the number. Its bit position is then the log2 of the integer.
|
||||
pub fn log2_64(n: u64) -> u64 {
|
||||
// This works by finding the largest non-zero binary digit in the
|
||||
// number. Its bit position is then the log2 of the integer.
|
||||
|
||||
let mut log = 0;
|
||||
|
||||
const POWERS: [(u64, u64); 6] = [
|
||||
(32, (1 << 32) - 1),
|
||||
(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;
|
||||
}
|
||||
if n == 0 {
|
||||
0
|
||||
} else {
|
||||
(63 - n.leading_zeros()) as u64
|
||||
}
|
||||
|
||||
log
|
||||
}
|
||||
|
||||
/// Creates a coordinate system from a single vector.
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::{
|
|||
hash::hash_u32,
|
||||
hilbert,
|
||||
image::Image,
|
||||
math::{probit, upper_power_of_two},
|
||||
math::probit,
|
||||
mis::power_heuristic,
|
||||
ray::{Ray, RayBatch},
|
||||
scene::{Scene, SceneLightSample},
|
||||
|
@ -151,7 +151,7 @@ impl<'a> Renderer<'a> {
|
|||
let bucket_count_x = ((width / bucket_w) + 1) as u32;
|
||||
let bucket_count_y = ((height / bucket_h) + 1) as u32;
|
||||
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
|
||||
};
|
||||
for hilbert_d in 0..bucket_n {
|
||||
|
|
|
@ -7,7 +7,7 @@ use glam::Vec4;
|
|||
use crate::{
|
||||
color::{Color, SpectralSample},
|
||||
lerp::{lerp, Lerp},
|
||||
math::{clamp, dot, zup_to_vec, Normal, Vector},
|
||||
math::{dot, zup_to_vec, Normal, Vector},
|
||||
sampling::cosine_sample_hemisphere,
|
||||
};
|
||||
|
||||
|
@ -481,11 +481,11 @@ mod ggx_closure {
|
|||
}
|
||||
|
||||
// Calculate needed dot products
|
||||
let na = clamp(dot(nn, aa), -1.0, 1.0);
|
||||
let nb = clamp(dot(nn, bb), -1.0, 1.0);
|
||||
let ha = clamp(dot(hh, aa), -1.0, 1.0);
|
||||
let hb = clamp(dot(hh, bb), -1.0, 1.0);
|
||||
let nh = clamp(dot(nn, hh), -1.0, 1.0);
|
||||
let na = dot(nn, aa).clamp(-1.0, 1.0);
|
||||
let nb = dot(nn, bb).clamp(-1.0, 1.0);
|
||||
let ha = dot(hh, aa).clamp(-1.0, 1.0);
|
||||
let hb = dot(hh, bb).clamp(-1.0, 1.0);
|
||||
let nh = dot(nn, hh).clamp(-1.0, 1.0);
|
||||
|
||||
// Calculate F - Fresnel
|
||||
let col_f = {
|
||||
|
@ -584,7 +584,7 @@ mod ggx_closure {
|
|||
// Approximate method
|
||||
let theta = cos_theta_max.acos();
|
||||
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)));
|
||||
|
||||
fac * (1.0f32).min(1.0 - cos_theta_max) * INV_PI
|
||||
|
|
Loading…
Reference in New Issue
Block a user