allow choosing which normals to use

This commit is contained in:
numzero 2025-11-24 00:21:06 +03:00
parent a51f46a038
commit 4b138deb34
6 changed files with 95 additions and 7 deletions

View File

@ -27,6 +27,13 @@ pub struct SphericalPosition {
pub distance: f32,
}
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum UseNormal {
Light,
Camera,
}
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct RedrawArgs {
@ -36,7 +43,8 @@ pub struct RedrawArgs {
pub light_spread: f32,
pub accum_sigma: f32,
pub accum_scale: f32,
pub reflections: u32,
pub reflections: u8,
pub use_normal: UseNormal,
pub show_axes: bool,
pub show_shapes: bool,
pub show_hit_emission: bool,
@ -305,12 +313,15 @@ impl Core {
if d2 > 9. * sigma2 {
continue;
}
assert!(hit.normal.is_normalized());
let normal = match args.use_normal {
UseNormal::Light => light_hit.normal,
UseNormal::Camera => hit.normal,
};
assert!(normal.is_normalized());
assert!(hit.incident.dir.is_normalized());
let reflector = Lambertian;
let in_lm = 1.0;
let out_cd =
in_lm * reflector.brdf(light_hit.normal, light_hit.incident.dir, -ray.dir);
let out_cd = in_lm * reflector.brdf(normal, light_hit.incident.dir, -ray.dir);
let weight = accum_normalizator * (-0.5 * d2 / sigma2).exp();
total_cd += weight * out_cd;
}

View File

@ -1,7 +1,7 @@
use std::{f32::consts::PI, sync::Arc};
use glam::uvec2;
use photon_light::{Core, RedrawArgs, SphericalPosition, init_gpu_inner};
use photon_light::{Core, RedrawArgs, SphericalPosition, UseNormal, init_gpu_inner};
use winit::{
application::ApplicationHandler,
event::WindowEvent,
@ -53,6 +53,7 @@ impl MainWindow {
accum_sigma: 0.025,
accum_scale: 0.01,
reflections: 2,
use_normal: UseNormal::Light,
show_axes: true,
show_shapes: true,
show_hit_emission: false,

View File

@ -13,6 +13,11 @@ struct SphericalPosition {
float distance = 1.;
};
enum class UseNormal: std::uint8_t {
Light,
Camera,
};
struct RedrawArgs {
SphericalPosition camera_position;
SphericalPosition light_position;
@ -20,7 +25,8 @@ struct RedrawArgs {
float light_spread = 0.;
float accum_sigma = 1.;
float accum_scale = 1.;
std::uint32_t reflections = 0;
std::uint8_t reflections = 0;
UseNormal use_normal = UseNormal::Light;
bool show_axes = true;
bool show_shapes = true;
bool show_hit_emission = true;
@ -31,6 +37,7 @@ struct RedrawArgs {
};
} // namespace ffi
using ffi::UseNormal;
using ffi::RedrawArgs;
using ffi::SphericalPosition;

View File

@ -16,6 +16,11 @@ float deg_to_rad(float val) {
}
void PhotonLight::updateView() {
UseNormal use_normal = {};
if (m_ui->normalFromLight->isChecked())
use_normal = UseNormal::Light;
else if (m_ui->normalFromCamera->isChecked())
use_normal = UseNormal::Camera;
RedrawArgs args{
.camera_position = SphericalPosition{
.yaw = deg_to_rad(m_ui->cameraYaw->value()),
@ -31,7 +36,8 @@ void PhotonLight::updateView() {
.light_spread = 0.125,
.accum_sigma = exp10f(m_ui->accumSigma->value() / 25.0),
.accum_scale = exp10f(m_ui->accumScale->value() / 25.0),
.reflections = std::uint32_t(m_ui->reflections->value()),
.reflections = std::uint8_t(m_ui->reflections->value()),
.use_normal = use_normal,
.show_axes = m_ui->displayAxes->isChecked(),
.show_shapes = m_ui->displayShapes->isChecked(),
.show_hit_emission = m_ui->displayEmitted->isChecked(),
@ -51,4 +57,9 @@ void PhotonLight::updateView() {
m_ui->viewport->setView(args);
}
void PhotonLight::updateViewIf(bool update) {
if (update)
updateView();
}
#include "moc_main_window.cpp"

View File

@ -16,6 +16,7 @@ public:
public slots:
void updateView();
void updateViewIf(bool update); // for radio buttons
private:
const std::unique_ptr<Ui::MainWindow> m_ui;

View File

@ -298,6 +298,30 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Use normal at</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="normalFromLight">
<property name="text">
<string>Hit position</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="normalFromCamera">
<property name="text">
<string>Show position</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -637,8 +661,41 @@
</hint>
</hints>
</connection>
<connection>
<sender>normalFromLight</sender>
<signal>toggled(bool)</signal>
<receiver>MainWindow</receiver>
<slot>updateViewIf(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>1429</x>
<y>787</y>
</hint>
<hint type="destinationlabel">
<x>1381</x>
<y>783</y>
</hint>
</hints>
</connection>
<connection>
<sender>normalFromCamera</sender>
<signal>toggled(bool)</signal>
<receiver>MainWindow</receiver>
<slot>updateViewIf(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>1932</x>
<y>816</y>
</hint>
<hint type="destinationlabel">
<x>1600</x>
<y>874</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>updateView()</slot>
<slot>updateViewIf(bool)</slot>
</slots>
</ui>