Add dielectric pbrt material

This commit is contained in:
hal8174 2025-08-28 00:22:58 +02:00
parent 0480e041cd
commit 2269bd102d
Signed by: hal8174
SSH key fingerprint: SHA256:NN98ZYwnrreQLSOV/g+amY7C3yL/mS1heD7bi5t6PPw
5 changed files with 43 additions and 27 deletions

View file

@ -0,0 +1,15 @@
use crate::prelude::*;
pub 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)
}

View file

@ -1,6 +1,7 @@
pub mod dir3; pub mod dir3;
pub mod frame; pub mod frame;
pub mod mat3; pub mod mat3;
pub mod material;
pub mod pos3; pub mod pos3;
pub mod sampling; pub mod sampling;

View file

@ -1,6 +1,5 @@
use plotters::prelude::*; use plotters::prelude::*;
use ray_tracing_core::prelude::*; use ray_tracing_core::{math::material::fresnel_real, prelude::*};
use ray_tracing_material::microfacet::fresnel_real;
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let root = BitMapBackend::new("fresnel.png", (640, 480)).into_drawing_area(); let root = BitMapBackend::new("fresnel.png", (640, 480)).into_drawing_area();

View file

@ -1,5 +1,5 @@
use rand_distr::{Distribution, Normal}; use rand_distr::{Distribution, Normal};
use ray_tracing_core::{material::Material, prelude::*}; use ray_tracing_core::{material::Material, math::material::fresnel_real, prelude::*};
use std::fmt::Debug; use std::fmt::Debug;
#[derive(Debug)] #[derive(Debug)]
@ -14,20 +14,6 @@ impl<D: MicrofacetDistribution + Debug> Microfacet<D> {
} }
} }
pub 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 + Send> Material<R> for Microfacet<D> { impl<R: Rng, D: MicrofacetDistribution + Debug + Sync + Send> Material<R> for Microfacet<D> {
fn eval(&self, w_in: Dir3, w_out: Dir3, _rng: &mut R) -> ray_tracing_core::prelude::Color { fn eval(&self, w_in: Dir3, w_out: Dir3, _rng: &mut R) -> ray_tracing_core::prelude::Color {
if w_out.y() > 0.0 && w_in.y() > 0.0 { if w_out.y() > 0.0 && w_in.y() > 0.0 {

View file

@ -1,4 +1,6 @@
use ray_tracing_core::{color::Color, material::SampleResult, prelude::*}; use ray_tracing_core::{
color::Color, material::SampleResult, math::material::fresnel_real, prelude::*,
};
use crate::{ use crate::{
either::Either, either::Either,
@ -103,20 +105,33 @@ impl<R: Rng> PbrtMaterial<R> for PbrtDielectricMaterial {
let _ = rng; let _ = rng;
let _ = v; let _ = v;
let _ = u; let _ = u;
let _ = match self.eta { let eta = match self.eta {
Either::A(Either::A(eta)) => eta, Either::A(Either::A(eta)) => eta,
_ => todo!(), _ => todo!(),
}; };
// let c = w_in.y(); let (n1, n2) = if w_in.y() >= 0.0 {
// let w_out = -w_in * eta (1.0, eta)
// + (eta * c - Float::sqrt(1.0 - eta * eta * (1.0 - c * c))) * Dir3::new(0.0, -1.0, 1.0); } else {
(eta, 1.0)
};
SampleResult::new( let r = fresnel_real(w_in.y().abs(), n1, n2);
Dir3::new(0.0, 2.0 * w_in.y(), 0.0) - w_in,
Color::white(), if r >= rng.r#gen() {
true, SampleResult::new(
) Dir3::new(0.0, 2.0 * w_in.y(), 0.0) - w_in,
Color::white(),
true,
)
} else {
let r = n1 / n2;
let w_out = -w_in * r
+ (r * w_in.y().abs() - Float::sqrt(1.0 - r * r * (1.0 - w_in.y() * w_in.y())))
* Dir3::new(0.0, if w_in.y() > 0.0 { 1.0 } else { -1.0 }, 0.0);
SampleResult::new(w_out, Color::white(), true)
}
} }
fn pdf(&self, u: Float, v: Float, w_in: Dir3, w_out: Dir3) -> Float { fn pdf(&self, u: Float, v: Float, w_in: Dir3, w_out: Dir3) -> Float {