compute reflections #2
186
src/lib.rs
186
src/lib.rs
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
use std::{convert::identity, error::Error, f32::consts::PI};
|
use std::{convert::identity, error::Error, f32::consts::PI};
|
||||||
|
|
||||||
use glam::{Mat4, UVec2, Vec3, vec3};
|
use glam::{Mat4, UVec2, Vec2, Vec3, vec3};
|
||||||
|
use rand_distr::Distribution as _;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
camera::OrbitalCamera,
|
camera::OrbitalCamera,
|
||||||
|
ray::Ray,
|
||||||
render::lines::{LookParams, Mesh, Pipeline, Vertex},
|
render::lines::{LookParams, Mesh, Pipeline, Vertex},
|
||||||
trace::{Scene, Source, Sphere},
|
trace::{Hit, Lambertian, Reflector, Scene, Source, Sphere},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod camera;
|
mod camera;
|
||||||
|
|
@ -32,6 +34,16 @@ pub struct RedrawArgs {
|
||||||
pub light_position: SphericalPosition,
|
pub light_position: SphericalPosition,
|
||||||
pub light_radius: f32,
|
pub light_radius: f32,
|
||||||
pub light_spread: f32,
|
pub light_spread: f32,
|
||||||
|
pub accum_sigma: f32,
|
||||||
|
pub accum_scale: f32,
|
||||||
|
pub reflections: u32,
|
||||||
|
pub show_axes: bool,
|
||||||
|
pub show_shapes: bool,
|
||||||
|
pub show_hit_emission: bool,
|
||||||
|
pub show_miss_emission: bool,
|
||||||
|
pub show_direct_hit: bool,
|
||||||
|
pub show_indirect_hit: bool,
|
||||||
|
pub show_light: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Gpu {
|
pub struct Gpu {
|
||||||
|
|
@ -84,6 +96,22 @@ fn loop_list_ex<T: Clone, U>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OrbitalCamera {
|
||||||
|
fn make_ray(&self, rng: &mut impl rand::Rng) -> Ray {
|
||||||
|
let off: f32 = rand_distr::StandardUniform.sample(rng);
|
||||||
|
let side: Vec2 = rand_distr::UnitCircle.sample(rng).into();
|
||||||
|
|
||||||
|
let m = self.transform().inverse();
|
||||||
|
let fwd = 1. - 0.1 * off;
|
||||||
|
let side_scale = (1. - fwd.powi(2)).sqrt();
|
||||||
|
let dir = Vec3::from((side_scale * side, fwd));
|
||||||
|
Ray {
|
||||||
|
base: self.position(),
|
||||||
|
dir: m.transform_vector3(dir),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Core {
|
impl Core {
|
||||||
pub fn new(gpu: Gpu) -> Self {
|
pub fn new(gpu: Gpu) -> Self {
|
||||||
let Gpu {
|
let Gpu {
|
||||||
|
|
@ -136,19 +164,16 @@ impl Core {
|
||||||
depth_slice: None,
|
depth_slice: None,
|
||||||
resolve_target: None,
|
resolve_target: None,
|
||||||
ops: wgpu::Operations {
|
ops: wgpu::Operations {
|
||||||
load: wgpu::LoadOp::Clear(wgpu::Color {
|
load: wgpu::LoadOp::Clear(wgpu::Color::BLACK),
|
||||||
r: 0.1,
|
|
||||||
g: 0.2,
|
|
||||||
b: 0.8,
|
|
||||||
a: 1.0,
|
|
||||||
}),
|
|
||||||
store: wgpu::StoreOp::Store,
|
store: wgpu::StoreOp::Store,
|
||||||
},
|
},
|
||||||
})],
|
})],
|
||||||
depth_stencil_attachment: None,
|
depth_stencil_attachment: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
self.pipeline.render(&mut pass, [&self.tripod]);
|
if args.show_axes {
|
||||||
|
self.pipeline.render(&mut pass, [&self.tripod]);
|
||||||
|
}
|
||||||
|
|
||||||
let source = Source {
|
let source = Source {
|
||||||
position_yaw: args.light_position.yaw,
|
position_yaw: args.light_position.yaw,
|
||||||
|
|
@ -158,14 +183,16 @@ impl Core {
|
||||||
spread: args.light_spread,
|
spread: args.light_spread,
|
||||||
};
|
};
|
||||||
|
|
||||||
let contour: Vec<Vertex> = loop_list(source.contour(17))
|
if args.show_shapes {
|
||||||
.map(|pos| Vertex {
|
let contour: Vec<Vertex> = loop_list(source.contour(17))
|
||||||
pos,
|
.map(|pos| Vertex {
|
||||||
color: vec3(1., 1., 1.),
|
pos,
|
||||||
})
|
color: vec3(1., 1., 1.),
|
||||||
.collect();
|
})
|
||||||
self.pipeline
|
.collect();
|
||||||
.render(&mut pass, [&Mesh::new(&self.device, &contour)]);
|
self.pipeline
|
||||||
|
.render(&mut pass, [&Mesh::new(&self.device, &contour)]);
|
||||||
|
}
|
||||||
|
|
||||||
const BASE_R: f32 = 2.;
|
const BASE_R: f32 = 2.;
|
||||||
const BASE_POS: Vec3 = vec3(0., 0., -BASE_R);
|
const BASE_POS: Vec3 = vec3(0., 0., -BASE_R);
|
||||||
|
|
@ -189,22 +216,40 @@ impl Core {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut prng = rand_pcg::Pcg64::new(42, 0);
|
let mut prng = rand_pcg::Pcg64::new(42, 0);
|
||||||
let rays: Vec<Vertex> = (0..10000)
|
let source_rays: Vec<Ray> = (0..10240).map(|_| source.make_ray(&mut prng)).collect();
|
||||||
.flat_map(|_| {
|
let camera_rays: Vec<Ray> = (0..10240).map(|_| camera.make_ray(&mut prng)).collect();
|
||||||
let ray = source.make_ray(&mut prng);
|
let mut source_ray_display: Vec<Vertex> = Vec::with_capacity(source_rays.len());
|
||||||
if let Some(ray) = scene.trace_ray(ray) {
|
let mut hits: Vec<Hit> = Vec::with_capacity(source_rays.len());
|
||||||
[
|
for ray in source_rays {
|
||||||
|
if let Some(hit) = scene.trace_ray(ray) {
|
||||||
|
hits.push(hit);
|
||||||
|
if args.show_hit_emission {
|
||||||
|
source_ray_display.extend([
|
||||||
Vertex {
|
Vertex {
|
||||||
pos: ray.base - 0.02 * ray.dir,
|
pos: ray.base,
|
||||||
color: vec3(1., 1., 1.),
|
color: vec3(1., 1., 1.),
|
||||||
},
|
},
|
||||||
Vertex {
|
Vertex {
|
||||||
pos: ray.base,
|
pos: ray.base + 0.1 * ray.dir,
|
||||||
color: vec3(0., 1., 0.),
|
color: vec3(0., 1., 0.),
|
||||||
},
|
},
|
||||||
]
|
]);
|
||||||
} else {
|
}
|
||||||
[
|
if args.show_direct_hit {
|
||||||
|
source_ray_display.extend([
|
||||||
|
Vertex {
|
||||||
|
pos: hit.incident.base - 0.02 * hit.incident.dir,
|
||||||
|
color: vec3(0., 0., 1.),
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
pos: hit.incident.base,
|
||||||
|
color: vec3(1., 1., 1.),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if args.show_miss_emission {
|
||||||
|
source_ray_display.extend([
|
||||||
Vertex {
|
Vertex {
|
||||||
pos: ray.base,
|
pos: ray.base,
|
||||||
color: vec3(1., 1., 1.),
|
color: vec3(1., 1., 1.),
|
||||||
|
|
@ -213,12 +258,89 @@ impl Core {
|
||||||
pos: ray.base + 0.1 * ray.dir,
|
pos: ray.base + 0.1 * ray.dir,
|
||||||
color: vec3(1., 0., 0.),
|
color: vec3(1., 0., 0.),
|
||||||
},
|
},
|
||||||
]
|
]);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
.collect();
|
}
|
||||||
self.pipeline
|
if args.reflections > 0 {
|
||||||
.render(&mut pass, [&Mesh::new(&self.device, &rays)]);
|
let mut hits1 = hits.clone();
|
||||||
|
for _ in 0..args.reflections {
|
||||||
|
let mut hits2: Vec<Hit> = Vec::with_capacity(hits1.len());
|
||||||
|
for hit in &hits1 {
|
||||||
|
let reflector = Lambertian;
|
||||||
|
let reflected = reflector.reflect(&mut prng, hit.normal, hit.incident.dir);
|
||||||
|
let ray = Ray::new(hit.incident.base, reflected);
|
||||||
|
let Some(hit2) = scene.trace_ray(ray) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
hits2.push(hit2);
|
||||||
|
if args.show_indirect_hit {
|
||||||
|
source_ray_display.extend([
|
||||||
|
Vertex {
|
||||||
|
pos: hit2.incident.base - 0.02 * hit2.incident.dir,
|
||||||
|
color: vec3(1., 0., 1.),
|
||||||
|
},
|
||||||
|
Vertex {
|
||||||
|
pos: hit2.incident.base,
|
||||||
|
color: vec3(1., 1., 1.),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hits.extend(&hits2);
|
||||||
|
hits1 = hits2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut camera_ray_display: Vec<Vertex> = Vec::with_capacity(camera_rays.len());
|
||||||
|
if args.show_light {
|
||||||
|
let sigma2 = args.accum_sigma.powi(2);
|
||||||
|
let accum_normalizator = (2. * PI * sigma2).sqrt().recip();
|
||||||
|
for ray in camera_rays {
|
||||||
|
let Some(hit) = scene.trace_ray(ray) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let mut total_cd = 0.0f32;
|
||||||
|
for light_hit in &hits {
|
||||||
|
let d2 = hit.incident.base.distance_squared(light_hit.incident.base);
|
||||||
|
if d2 > 9. * sigma2 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert!(hit.normal.is_normalized());
|
||||||
|
assert!(hit.incident.dir.is_normalized());
|
||||||
|
let reflector = Lambertian;
|
||||||
|
let in_lm = 1.0;
|
||||||
|
let out_cd = in_lm
|
||||||
|
* hit.normal.dot(-hit.incident.dir)
|
||||||
|
* reflector.brdf(hit.normal, hit.incident.dir, -ray.dir);
|
||||||
|
let weight = accum_normalizator * (-0.5 * d2 / sigma2).exp();
|
||||||
|
total_cd += weight * out_cd;
|
||||||
|
}
|
||||||
|
let brightness = 3. * (1. - (1. + total_cd * args.accum_scale).recip());
|
||||||
|
let r = args.accum_sigma;
|
||||||
|
let color = vec3(brightness, brightness - 1., brightness - 2.)
|
||||||
|
.clamp(Vec3::splat(0.), Vec3::splat(1.));
|
||||||
|
let vertex = |off: Vec3| Vertex {
|
||||||
|
pos: hit.incident.base + r * off,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
camera_ray_display.extend([
|
||||||
|
vertex(-Vec3::X),
|
||||||
|
vertex(Vec3::X),
|
||||||
|
vertex(-Vec3::Y),
|
||||||
|
vertex(Vec3::Y),
|
||||||
|
vertex(-Vec3::Z),
|
||||||
|
vertex(Vec3::Z),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !source_ray_display.is_empty() {
|
||||||
|
self.pipeline
|
||||||
|
.render(&mut pass, [&Mesh::new(&self.device, &source_ray_display)]);
|
||||||
|
}
|
||||||
|
if !camera_ray_display.is_empty() {
|
||||||
|
self.pipeline
|
||||||
|
.render(&mut pass, [&Mesh::new(&self.device, &camera_ray_display)]);
|
||||||
|
}
|
||||||
|
|
||||||
drop(pass);
|
drop(pass);
|
||||||
self.queue.submit(std::iter::once(encoder.finish()));
|
self.queue.submit(std::iter::once(encoder.finish()));
|
||||||
|
|
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -50,6 +50,16 @@ impl MainWindow {
|
||||||
},
|
},
|
||||||
light_radius: 0.125,
|
light_radius: 0.125,
|
||||||
light_spread: 0.125,
|
light_spread: 0.125,
|
||||||
|
accum_sigma: 0.025,
|
||||||
|
accum_scale: 0.01,
|
||||||
|
reflections: 2,
|
||||||
|
show_axes: true,
|
||||||
|
show_shapes: true,
|
||||||
|
show_hit_emission: false,
|
||||||
|
show_miss_emission: false,
|
||||||
|
show_direct_hit: false,
|
||||||
|
show_indirect_hit: false,
|
||||||
|
show_light: true,
|
||||||
}),
|
}),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
61
src/trace.rs
61
src/trace.rs
|
|
@ -1,7 +1,7 @@
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
use glam::{Mat4, Vec2, Vec3, vec3};
|
use glam::{Mat4, Vec2, Vec3, vec3};
|
||||||
use rand_distr::Distribution;
|
use rand_distr::{Distribution, UnitSphere};
|
||||||
|
|
||||||
use crate::{camera::OrbitalCamera, ray::Ray};
|
use crate::{camera::OrbitalCamera, ray::Ray};
|
||||||
|
|
||||||
|
|
@ -78,8 +78,14 @@ pub struct Sphere {
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Hit1 {
|
||||||
|
pos: Vec3,
|
||||||
|
dist: f32,
|
||||||
|
normal: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
impl Sphere {
|
impl Sphere {
|
||||||
fn trace_ray(&self, ray: Ray) -> Option<f32> {
|
fn trace_ray(&self, ray: Ray) -> Option<Hit1> {
|
||||||
// let t: f32;
|
// let t: f32;
|
||||||
// let hit = ray.base + t * ray.dir;
|
// let hit = ray.base + t * ray.dir;
|
||||||
// (hit - self.position).length() == self.radius;
|
// (hit - self.position).length() == self.radius;
|
||||||
|
|
@ -94,7 +100,10 @@ impl Sphere {
|
||||||
if d4 < 0. {
|
if d4 < 0. {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Some((-b2 - d4.sqrt()) / a)
|
let dist = (-b2 - d4.sqrt()) / a;
|
||||||
|
let pos = ray.advance(dist).base;
|
||||||
|
let normal = (pos - self.position).normalize();
|
||||||
|
Some(Hit1 { pos, dist, normal })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,13 +112,51 @@ pub struct Scene {
|
||||||
pub objects: Vec<Sphere>,
|
pub objects: Vec<Sphere>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Hit {
|
||||||
|
pub incident: Ray,
|
||||||
|
pub normal: Vec3,
|
||||||
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
pub fn trace_ray(&self, ray: Ray) -> Option<Ray> {
|
pub fn trace_ray(&self, ray: Ray) -> Option<Hit> {
|
||||||
let dist = self
|
const EPS: f32 = -1e-3;
|
||||||
|
let hit = self
|
||||||
.objects
|
.objects
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|obj| obj.trace_ray(ray))
|
.filter_map(|obj| obj.trace_ray(ray))
|
||||||
.min_by(f32::total_cmp);
|
.filter(|h| h.dist >= EPS)
|
||||||
Some(ray.advance(dist?))
|
.min_by(|a, b| f32::total_cmp(&a.dist, &b.dist))?;
|
||||||
|
Some(Hit {
|
||||||
|
incident: Ray {
|
||||||
|
base: hit.pos,
|
||||||
|
dir: ray.dir,
|
||||||
|
},
|
||||||
|
normal: hit.normal,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Reflector {
|
||||||
|
fn brdf(&self, normal: Vec3, incident: Vec3, reflected: Vec3) -> f32 /* 1/sr */;
|
||||||
|
fn reflect(&self, rgen: &mut impl rand::Rng, normal: Vec3, incident: Vec3) -> Vec3;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Lambertian;
|
||||||
|
|
||||||
|
impl Reflector for Lambertian {
|
||||||
|
fn brdf(&self, _normal: Vec3, _incident: Vec3, _reflected: Vec3) -> f32 {
|
||||||
|
1. / PI
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reflect(&self, rgen: &mut impl rand::Rng, normal: Vec3, _incident: Vec3) -> Vec3 {
|
||||||
|
let sphere: Vec3 = UnitSphere.sample(rgen).into();
|
||||||
|
let sphere_n = normal.dot(sphere); // uniform on [-1, 1]!
|
||||||
|
let sphere_t = sphere - sphere_n * normal;
|
||||||
|
|
||||||
|
let out_n_len2 = sphere_n.abs();
|
||||||
|
let out_t = (1. + out_n_len2).recip().sqrt() * sphere_t;
|
||||||
|
let out_n = out_n_len2.sqrt() * normal;
|
||||||
|
out_t + out_n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,26 @@ namespace ffi {
|
||||||
struct Core;
|
struct Core;
|
||||||
|
|
||||||
struct SphericalPosition {
|
struct SphericalPosition {
|
||||||
float yaw;
|
float yaw = 0.;
|
||||||
float pitch;
|
float pitch = 0.;
|
||||||
float distance;
|
float distance = 1.;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RedrawArgs {
|
struct RedrawArgs {
|
||||||
SphericalPosition camera_position;
|
SphericalPosition camera_position;
|
||||||
SphericalPosition light_position;
|
SphericalPosition light_position;
|
||||||
float light_radius;
|
float light_radius = 1.;
|
||||||
float light_spread;
|
float light_spread = 0.;
|
||||||
|
float accum_sigma = 1.;
|
||||||
|
float accum_scale = 1.;
|
||||||
|
std::uint32_t reflections = 0;
|
||||||
|
bool show_axes = true;
|
||||||
|
bool show_shapes = true;
|
||||||
|
bool show_hit_emission = true;
|
||||||
|
bool show_miss_emission = true;
|
||||||
|
bool show_direct_hit = true;
|
||||||
|
bool show_indirect_hit = true;
|
||||||
|
bool show_light = true;
|
||||||
};
|
};
|
||||||
} // namespace ffi
|
} // namespace ffi
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,39 @@ float deg_to_rad(float val) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhotonLight::updateView() {
|
void PhotonLight::updateView() {
|
||||||
m_ui->viewport->setView(RedrawArgs{
|
RedrawArgs args{
|
||||||
.camera_position = SphericalPosition{
|
.camera_position = SphericalPosition{
|
||||||
.yaw = deg_to_rad(m_ui->cameraYaw->value()),
|
.yaw = deg_to_rad(m_ui->cameraYaw->value()),
|
||||||
.pitch = deg_to_rad(m_ui->cameraPitch->value()),
|
.pitch = deg_to_rad(m_ui->cameraPitch->value()),
|
||||||
.distance = 3.0,
|
.distance = m_ui->cameraDistance->value() / 10.0f,
|
||||||
},
|
},
|
||||||
.light_position = SphericalPosition{
|
.light_position = SphericalPosition{
|
||||||
.yaw = deg_to_rad(m_ui->lightYaw->value()),
|
.yaw = deg_to_rad(m_ui->lightYaw->value()),
|
||||||
.pitch = deg_to_rad(m_ui->lightPitch->value()),
|
.pitch = deg_to_rad(m_ui->lightPitch->value()),
|
||||||
.distance = 1.0,
|
.distance = m_ui->lightDistance->value() / 10.0f,
|
||||||
},
|
},
|
||||||
.light_radius = 0.125,
|
.light_radius = 0.125,
|
||||||
.light_spread = 0.125,
|
.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()),
|
||||||
|
.show_axes = m_ui->displayAxes->isChecked(),
|
||||||
|
.show_shapes = m_ui->displayShapes->isChecked(),
|
||||||
|
.show_hit_emission = m_ui->displayEmitted->isChecked(),
|
||||||
|
.show_miss_emission = m_ui->displayEmitted->isChecked(),
|
||||||
|
.show_direct_hit = m_ui->displayDirectHits->isChecked(),
|
||||||
|
.show_indirect_hit = m_ui->displayIndirectHits->isChecked(),
|
||||||
|
.show_light = m_ui->displayResult->isChecked(),
|
||||||
|
};
|
||||||
|
m_ui->cameraYawLabel->setText(tr("Yaw: %1 deg").arg(QString::number(qRadiansToDegrees(args.camera_position.yaw))));
|
||||||
|
m_ui->cameraPitchLabel->setText(tr("Pitch: %1 deg").arg(QString::number(qRadiansToDegrees(args.camera_position.pitch))));
|
||||||
|
m_ui->cameraDistanceLabel->setText(tr("Distance: %1").arg(QString::number(args.camera_position.distance)));
|
||||||
|
m_ui->lightYawLabel->setText(tr("Yaw: %1 deg").arg(QString::number(qRadiansToDegrees(args.light_position.yaw))));
|
||||||
|
m_ui->lightPitchLabel->setText(tr("Pitch: %1 deg").arg(QString::number(qRadiansToDegrees(args.light_position.pitch))));
|
||||||
|
m_ui->lightDistanceLabel->setText(tr("Distance: %1").arg(QString::number(args.light_position.distance)));
|
||||||
|
m_ui->accumSigmaLabel->setText(tr("Averaging radius: %1").arg(QString::number(args.accum_sigma, 'f', 3)));
|
||||||
|
m_ui->accumScaleLabel->setText(tr("Brightness: %1").arg(QString::number(args.accum_scale, 'f', 3)));
|
||||||
|
m_ui->viewport->setView(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "moc_main_window.cpp"
|
#include "moc_main_window.cpp"
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>1600</width>
|
||||||
<height>600</height>
|
<height>1200</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>1600</width>
|
||||||
<height>38</height>
|
<height>38</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
|
@ -47,10 +47,13 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="cameraYawLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Yaw</string>
|
<string>Yaw</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>cameraYaw</cstring>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -73,10 +76,13 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="cameraPitchLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Pitch</string>
|
<string>Pitch</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>cameraPitch</cstring>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -98,6 +104,29 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="cameraDistanceLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Distance</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>cameraDistance</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="cameraDistance">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -108,10 +137,13 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="lightYawLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Yaw</string>
|
<string>Yaw</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>lightYaw</cstring>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -131,10 +163,13 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="lightPitchLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Pitch</string>
|
<string>Pitch</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>lightPitch</cstring>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -159,6 +194,179 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="lightDistanceLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Distance</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>lightDistance</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="lightDistance">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Lighting</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="accumSigmaLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Averaging radius</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>accumSigma</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="accumSigma">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>-40</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="accumScaleLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Brightness</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>accumScale</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSlider" name="accumScale">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>-100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>-50</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reflections</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>reflections</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="reflections">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Show</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="displayAxes">
|
||||||
|
<property name="text">
|
||||||
|
<string>Axes</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="displayShapes">
|
||||||
|
<property name="text">
|
||||||
|
<string>Shapes</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="displayEmitted">
|
||||||
|
<property name="text">
|
||||||
|
<string>Emitted rays</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="displayDirectHits">
|
||||||
|
<property name="text">
|
||||||
|
<string>Direct incident rays</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="displayIndirectHits">
|
||||||
|
<property name="text">
|
||||||
|
<string>Indirect incident rays</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="displayResult">
|
||||||
|
<property name="text">
|
||||||
|
<string>Average light</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
@ -196,8 +404,8 @@
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>688</x>
|
<x>1585</x>
|
||||||
<y>159</y>
|
<y>169</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>403</x>
|
<x>403</x>
|
||||||
|
|
@ -212,8 +420,8 @@
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>688</x>
|
<x>1585</x>
|
||||||
<y>215</y>
|
<y>225</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>403</x>
|
<x>403</x>
|
||||||
|
|
@ -228,8 +436,8 @@
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>688</x>
|
<x>1585</x>
|
||||||
<y>319</y>
|
<y>385</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>403</x>
|
<x>403</x>
|
||||||
|
|
@ -244,8 +452,8 @@
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel">
|
<hint type="sourcelabel">
|
||||||
<x>688</x>
|
<x>1585</x>
|
||||||
<y>375</y>
|
<y>441</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel">
|
<hint type="destinationlabel">
|
||||||
<x>403</x>
|
<x>403</x>
|
||||||
|
|
@ -253,6 +461,182 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>accumSigma</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1585</x>
|
||||||
|
<y>601</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>accumScale</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1585</x>
|
||||||
|
<y>657</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>399</x>
|
||||||
|
<y>299</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>cameraDistance</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>271</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>lightDistance</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>487</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>displayAxes</sender>
|
||||||
|
<signal>stateChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>799</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>displayDirectHits</sender>
|
||||||
|
<signal>stateChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>901</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>displayEmitted</sender>
|
||||||
|
<signal>stateChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>867</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>displayIndirectHits</sender>
|
||||||
|
<signal>stateChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>935</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>displayResult</sender>
|
||||||
|
<signal>stateChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>969</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>displayShapes</sender>
|
||||||
|
<signal>stateChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>833</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>reflections</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>updateView()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>1489</x>
|
||||||
|
<y>712</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>799</x>
|
||||||
|
<y>599</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<slots>
|
<slots>
|
||||||
<slot>updateView()</slot>
|
<slot>updateView()</slot>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user