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
|
management, etc. presents a much richer and more challenging problem space to
|
||||||
explore than just writing a basic path tracer.
|
explore than just writing a basic path tracer.
|
||||||
|
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
Psychopath is written in [Rust](https://www.rust-lang.org), and is pretty
|
Psychopath is written in [Rust](https://www.rust-lang.org), and is pretty
|
||||||
straightforward to build except for its OpenEXR dependency.
|
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
|
Once those environment variables are set, then you should be able to build using
|
||||||
the same simple cargo command above.
|
the same simple cargo command above.
|
||||||
|
|
||||||
|
|
||||||
# PsychoBlend
|
# PsychoBlend
|
||||||
|
|
||||||
Included in the repository is an add-on for [Blender](http://www.blender.org)
|
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
|
- Exports dupligroups with full hierarchical instancing
|
||||||
- Limited auto-detection of instanced meshes
|
- 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
|
# 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).
|
* 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.
|
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::{
|
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