Add Oren-Nayar and fix bugs

This commit is contained in:
hal8174 2024-12-27 19:11:02 +01:00
parent 3a37a72f56
commit 745b7d2602
7 changed files with 137 additions and 28 deletions

View file

@ -2,34 +2,57 @@ use ray_tracing_core::{material::Material, prelude::*};
use std::fmt::Debug;
#[derive(Debug)]
struct Microfacet<D: MicrofacetDistribution + Debug> {
pub struct Microfacet<D: MicrofacetDistribution + Debug> {
dist: D,
color: Color,
}
fn fresnel(w_in: Dir3, n: Dir3, nu_rel: Float) -> Float {
todo!()
}
impl<R: Rng, D: MicrofacetDistribution + Debug + Sync> Material<R> for Microfacet<D> {
fn eval(
&self,
w_in: ray_tracing_core::prelude::Dir3,
w_out: ray_tracing_core::prelude::Dir3,
_rng: &mut R,
) -> ray_tracing_core::prelude::Color {
let w_h = (w_in + w_out).normalize();
let g = self.dist.g1(w_in, w_h) * self.dist.g1(w_out, w_h);
self.color * fresnel(w_in, w_h, 1.0) * g * self.dist.d(w_h) / (4.0 * w_in.y() * w_out.y())
impl<D: MicrofacetDistribution + Debug> Microfacet<D> {
pub fn new(dist: D, color: Color) -> Self {
Self { dist, color }
}
}
struct BeckmannDistribution {
fn fresnel_real(cos_theta_in: Float, nu1: Float, nu2: Float) -> Float {
let nu_rel = nu1 / nu2;
let cos_theta_tr = Float::sqrt(1.0 - nu_rel * nu_rel * (1.0 - cos_theta_in * cos_theta_in));
let rs = ((nu1 * cos_theta_in - nu2 * cos_theta_tr)
/ (nu1 * cos_theta_in + nu2 * cos_theta_tr))
.powi(2);
let rp = ((nu1 * cos_theta_tr - nu2 * cos_theta_in)
/ (nu1 * cos_theta_tr + nu2 * cos_theta_in))
.powi(2);
0.5 * (rs + rp)
}
impl<R: Rng, D: MicrofacetDistribution + Debug + Sync> Material<R> for Microfacet<D> {
fn eval(&self, w_in: Dir3, w_out: Dir3, _rng: &mut R) -> ray_tracing_core::prelude::Color {
if w_out.y() > 0.0 {
let w_h = (w_in + w_out).normalize();
let g = self.dist.g1(w_in, w_h) * self.dist.g1(w_out, w_h);
self.color * fresnel_real(Dir3::dot(w_in, w_h), 1.0, 1.3) * g * self.dist.d(w_h)
/ (4.0 * w_in.y() * w_out.y()).max(0.0)
} else {
Color::black()
}
}
}
#[derive(Debug)]
pub struct BeckmannDistribution {
alpha: Float,
}
impl BeckmannDistribution {
pub fn new(alpha: Float) -> Self {
Self { alpha }
}
}
impl MicrofacetDistribution for BeckmannDistribution {
fn g1(&self, w: Dir3, w_h: Dir3) -> Float {
if w.y() > 0.0 && Dir3::dot(w, w_h) > 0.0 {
@ -55,7 +78,7 @@ impl MicrofacetDistribution for BeckmannDistribution {
}
}
trait MicrofacetDistribution {
pub trait MicrofacetDistribution {
fn g1(&self, w: Dir3, w_h: Dir3) -> Float;
fn d(&self, w_h: Dir3) -> Float;