directional light
This commit is contained in:
parent
da773cad56
commit
b559bd5e08
8 changed files with 273 additions and 55 deletions
shaders
src
Binary file not shown.
|
@ -149,11 +149,11 @@ uvec4 sample_color_from_scene_info(uint volume_start, uvec2 raster_pos, uint f)
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_light_position(uint light_index) {
|
vec3 get_light_position(uint light_index) {
|
||||||
return vec3(uintBitsToFloat(scene_info.infos[light_index]), uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]));
|
return vec3(uintBitsToFloat(scene_info.infos[light_index + 1]), uintBitsToFloat(scene_info.infos[light_index + 2]), uintBitsToFloat(scene_info.infos[light_index + 3]));
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_light_color(uint light_index) {
|
vec3 get_light_color(uint light_index) {
|
||||||
return vec3(float(scene_info.infos[light_index + 3]) / 255.0, float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0);
|
return vec3(float(scene_info.infos[light_index + 4]) / 255.0, float(scene_info.infos[light_index + 5]) / 255.0, float(scene_info.infos[light_index + 6]) / 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 normal_for_facing(uint facing) {
|
vec3 normal_for_facing(uint facing) {
|
||||||
|
@ -377,7 +377,7 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
|
||||||
uint light_num = 0;
|
uint light_num = 0;
|
||||||
|
|
||||||
// initialize color
|
// initialize color
|
||||||
vec3 color_sum = vec3(0.0, 0.0, 0.0) + (orig_color_sample.xyz * 0.01);
|
vec3 color_sum = vec3(0.0, 0.0, 0.0);// + (orig_color_sample.xyz * 0.01);
|
||||||
|
|
||||||
uint max_iterations = max_num_lights * max_iterations_per_light;
|
uint max_iterations = max_num_lights * max_iterations_per_light;
|
||||||
uint iteration = 0;
|
uint iteration = 0;
|
||||||
|
@ -388,10 +388,20 @@ vec3 get_lighting_color(uint volume_start, vec3 starting_pos, vec4 orig_color_sa
|
||||||
// abort if there is no new light
|
// abort if there is no new light
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vec3 light_direction = get_light_position(light_index) - starting_pos;
|
vec3 light_direction;
|
||||||
|
float max_factor;
|
||||||
|
if (scene_info.infos[light_index] == 0) {
|
||||||
|
//point light
|
||||||
|
light_direction = get_light_position(light_index) - starting_pos;
|
||||||
|
max_factor = 1.0;
|
||||||
|
} else if (scene_info.infos[light_index] == 1) {
|
||||||
|
// directional light
|
||||||
|
light_direction = -normalize(get_light_position(light_index));
|
||||||
|
max_factor = pos_infinity;
|
||||||
|
}
|
||||||
vec3 light_color = get_light_color(light_index);
|
vec3 light_color = get_light_color(light_index);
|
||||||
|
|
||||||
Tracing result = trace_ray(volume_start, starting_pos, light_direction, 1.0, iteration, max_iterations, false);
|
Tracing result = trace_ray(volume_start, starting_pos, light_direction, max_factor, iteration, max_iterations, false);
|
||||||
// add result, if there is a hit the null vector will be added
|
// add result, if there is a hit the null vector will be added
|
||||||
color_sum += float(!result.has_hit) * result.color_mul * max(dot(normal, normalize(light_direction)), 0.0) * (orig_color_sample.xyz * light_color) / (length(light_direction) * length(light_direction));
|
color_sum += float(!result.has_hit) * result.color_mul * max(dot(normal, normalize(light_direction)), 0.0) * (orig_color_sample.xyz * light_color) / (length(light_direction) * length(light_direction));
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ impl App {
|
||||||
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
|
let entry = Entry::new(loader).map_err(|b| anyhow!("{}", b))?;
|
||||||
let mut data = app_data::AppData::default();
|
let mut data = app_data::AppData::default();
|
||||||
data.use_geometry_shader = false;
|
data.use_geometry_shader = false;
|
||||||
data.num_lights_per_volume = 2;
|
data.num_lights_per_volume = 5;
|
||||||
data.max_iterations_per_light = 20;
|
data.max_iterations_per_light = 20;
|
||||||
data.diffuse_raster_steps = 0;
|
data.diffuse_raster_steps = 0;
|
||||||
data.diffuse_raster_size = 0.01;
|
data.diffuse_raster_size = 0.01;
|
||||||
|
@ -218,9 +218,9 @@ impl App {
|
||||||
create_framebuffers(&device, &mut data)?;
|
create_framebuffers(&device, &mut data)?;
|
||||||
|
|
||||||
|
|
||||||
//image::create_texture_image(&instance, &device, &mut data)?;
|
image::create_texture_image(&instance, &device, &mut data)?;
|
||||||
//image::create_texture_image_view(&device, &mut data)?;
|
image::create_texture_image_view(&device, &mut data)?;
|
||||||
//image::create_texture_sampler(&device, &mut data)?;
|
image::create_texture_sampler(&device, &mut data)?;
|
||||||
|
|
||||||
scene_handler.prepare_data(&instance, &device, &mut data)?;
|
scene_handler.prepare_data(&instance, &device, &mut data)?;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,12 @@ use crate::primitives::cube::Cube;
|
||||||
use crate::primitives::quad::Quad;
|
use crate::primitives::quad::Quad;
|
||||||
use crate::scene::oct_tree::OctTree;
|
use crate::scene::oct_tree::OctTree;
|
||||||
|
|
||||||
|
use super::memorizable::Memorizable;
|
||||||
|
use super::light::LightSource;
|
||||||
use super::light::PointLight;
|
use super::light::PointLight;
|
||||||
|
use super::AppData;
|
||||||
|
use super::LightsIter;
|
||||||
|
use super::Scene;
|
||||||
|
|
||||||
pub struct EmptyVolume {
|
pub struct EmptyVolume {
|
||||||
pub memory_start: usize,
|
pub memory_start: usize,
|
||||||
|
@ -863,12 +868,37 @@ impl EmptyVolume {
|
||||||
}
|
}
|
||||||
quads
|
quads
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn select_lights(&self, lights: LightsIter, light_number: u32) -> Vec<u32> {
|
||||||
|
let center = self.position + Vector3{x: self.size_x / 2, y: self.size_y / 2, z: self.size_z / 2};
|
||||||
|
let mut weighted_indices = vec![];
|
||||||
|
for light in lights {
|
||||||
|
let weight = light.borrow().weighted_distance(center);
|
||||||
|
weighted_indices.push((weight, light.borrow().get_memory_start()));
|
||||||
|
}
|
||||||
|
weighted_indices.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
|
||||||
|
|
||||||
|
let mut out_index = vec![];
|
||||||
|
for index in 0..weighted_indices.len() {
|
||||||
|
out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32);
|
||||||
|
if out_index.len() == light_number as usize {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while out_index.len() < light_number as usize {
|
||||||
|
out_index.push(0);
|
||||||
|
}
|
||||||
|
out_index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Memorizable for EmptyVolume {
|
||||||
// MARK: Get Buffer Mem Size
|
// MARK: Get Buffer Mem Size
|
||||||
pub fn get_buffer_mem_size(&self, light_number: u32) -> u32 {
|
fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
|
||||||
let mut mem_size: u32 = 0;
|
let mut mem_size: u32 = 0;
|
||||||
mem_size += 3; //pos
|
mem_size += 3; //pos
|
||||||
mem_size += 3; //max sizes
|
mem_size += 3; //max sizes
|
||||||
mem_size += light_number; // light references
|
mem_size += data.num_lights_per_volume; // light references
|
||||||
mem_size += 12; //color/roughness buffer sizes, 2 values each
|
mem_size += 12; //color/roughness buffer sizes, 2 values each
|
||||||
mem_size += 12; //neighbor buffer sizes, 2 values each
|
mem_size += 12; //neighbor buffer sizes, 2 values each
|
||||||
|
|
||||||
|
@ -890,7 +920,7 @@ impl EmptyVolume {
|
||||||
mem_size
|
mem_size
|
||||||
}
|
}
|
||||||
// MARK: insert into Memory
|
// MARK: insert into Memory
|
||||||
pub fn insert_into_memory(&self, mut v: Vec<u32>, light_number: u32, lights: &Vec<PointLight>) -> Vec<u32> {
|
fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||||
let mut mem_index = self.memory_start;
|
let mut mem_index = self.memory_start;
|
||||||
//pos
|
//pos
|
||||||
v[mem_index] = self.position.x as u32;
|
v[mem_index] = self.position.x as u32;
|
||||||
|
@ -907,7 +937,7 @@ impl EmptyVolume {
|
||||||
v[mem_index] = self.size_z as u32;
|
v[mem_index] = self.size_z as u32;
|
||||||
mem_index += 1;
|
mem_index += 1;
|
||||||
//Todo: insert lights
|
//Todo: insert lights
|
||||||
let selected_lights = self.select_lights(lights, light_number);
|
let selected_lights = self.select_lights(scene.get_light_iter(), data.num_lights_per_volume);
|
||||||
for light in selected_lights {
|
for light in selected_lights {
|
||||||
v[mem_index] = light;
|
v[mem_index] = light;
|
||||||
mem_index += 1;
|
mem_index += 1;
|
||||||
|
@ -1207,26 +1237,12 @@ impl EmptyVolume {
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_lights(&self, lights: &Vec<PointLight>, light_number: u32) -> Vec<u32> {
|
fn get_memory_start(&self) -> usize {
|
||||||
let center = self.position + Vector3{x: self.size_x / 2, y: self.size_y / 2, z: self.size_z / 2};
|
self.memory_start
|
||||||
let mut weighted_indices = vec![];
|
}
|
||||||
for light in lights {
|
|
||||||
let weight = light.weighted_distance(center);
|
|
||||||
weighted_indices.push((weight, light.memory_start));
|
|
||||||
}
|
|
||||||
weighted_indices.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap());
|
|
||||||
|
|
||||||
let mut out_index = vec![];
|
fn set_memory_start(&mut self, memory_start: usize) {
|
||||||
for index in 0..weighted_indices.len() {
|
self.memory_start = memory_start;
|
||||||
out_index.push(weighted_indices[weighted_indices.len() - (index + 1)].1 as u32);
|
|
||||||
if out_index.len() == light_number as usize {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while out_index.len() < light_number as usize {
|
|
||||||
out_index.push(0);
|
|
||||||
}
|
|
||||||
out_index
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
use cgmath::{InnerSpace, MetricSpace, Vector3};
|
use cgmath::{InnerSpace, MetricSpace, Vector3};
|
||||||
|
|
||||||
use crate::vertex;
|
use crate::vertex;
|
||||||
|
use super::memorizable::Memorizable;
|
||||||
|
use super::AppData;
|
||||||
|
use super::Scene;
|
||||||
|
|
||||||
|
pub enum LightType {
|
||||||
|
POINT,
|
||||||
|
DIRECTION
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Light {
|
||||||
|
fn get_light_type(&self) -> LightType;
|
||||||
|
fn weighted_distance(&self, center: Vector3<usize>) -> f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LightSource: Light + Memorizable {}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct PointLight{
|
pub struct PointLight{
|
||||||
|
@ -9,26 +25,151 @@ pub struct PointLight{
|
||||||
pub memory_start: usize,
|
pub memory_start: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PointLight {
|
impl Memorizable for PointLight {
|
||||||
pub fn get_buffer_mem_size(&self) -> u32 {
|
fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
|
||||||
3 + 3
|
1 + 3 + 3
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_into_memory(&self, mut v: Vec<u32>) -> Vec<u32> {
|
fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||||
v[self.memory_start] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
|
v[self.memory_start] = LightType::POINT as u32;
|
||||||
v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.y.to_ne_bytes());
|
|
||||||
v[self.memory_start + 2] = u32::from_ne_bytes(self.pos.z.to_ne_bytes());
|
|
||||||
|
|
||||||
v[self.memory_start + 3] = (self.color.x * 255.0) as u32;
|
v[self.memory_start + 1] = u32::from_ne_bytes(self.pos.x.to_ne_bytes());
|
||||||
v[self.memory_start + 4] = (self.color.y * 255.0) as u32;
|
v[self.memory_start + 2] = u32::from_ne_bytes(self.pos.y.to_ne_bytes());
|
||||||
v[self.memory_start + 5] = (self.color.z * 255.0) as u32;
|
v[self.memory_start + 3] = u32::from_ne_bytes(self.pos.z.to_ne_bytes());
|
||||||
|
|
||||||
|
v[self.memory_start + 4] = (self.color.x * 255.0) as u32;
|
||||||
|
v[self.memory_start + 5] = (self.color.y * 255.0) as u32;
|
||||||
|
v[self.memory_start + 6] = (self.color.z * 255.0) as u32;
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
|
fn get_memory_start(&self) -> usize {
|
||||||
|
self.memory_start
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_memory_start(&mut self, memory_start: usize) {
|
||||||
|
self.memory_start = memory_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Light for PointLight {
|
||||||
|
fn get_light_type(&self) -> LightType {
|
||||||
|
LightType::POINT
|
||||||
|
}
|
||||||
|
|
||||||
|
fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
|
||||||
let distance = self.pos.distance(vertex::Vec3{x: center.x as f32, y: center.y as f32, z: center.z as f32});
|
let distance = self.pos.distance(vertex::Vec3{x: center.x as f32, y: center.y as f32, z: center.z as f32});
|
||||||
let light_intensity = self.color.magnitude();
|
let light_intensity = self.color.magnitude();
|
||||||
|
|
||||||
light_intensity / distance.powf(2.0)
|
light_intensity / distance.powf(2.0)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LightSource for PointLight {}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub struct DirectionalLight{
|
||||||
|
pub direction: vertex::Vec3,
|
||||||
|
pub color: vertex::Vec3,
|
||||||
|
pub memory_start: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Memorizable for DirectionalLight {
|
||||||
|
fn get_buffer_mem_size(&self, data: &AppData) -> u32 {
|
||||||
|
1 + 3 + 3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert_into_memory(&self, mut v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32> {
|
||||||
|
v[self.memory_start] = LightType::DIRECTION as u32;
|
||||||
|
|
||||||
|
v[self.memory_start + 1] = u32::from_ne_bytes(self.direction.x.to_ne_bytes());
|
||||||
|
v[self.memory_start + 2] = u32::from_ne_bytes(self.direction.y.to_ne_bytes());
|
||||||
|
v[self.memory_start + 3] = u32::from_ne_bytes(self.direction.z.to_ne_bytes());
|
||||||
|
|
||||||
|
v[self.memory_start + 4] = (self.color.x * 255.0) as u32;
|
||||||
|
v[self.memory_start + 5] = (self.color.y * 255.0) as u32;
|
||||||
|
v[self.memory_start + 6] = (self.color.z * 255.0) as u32;
|
||||||
|
v
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_memory_start(&self) -> usize {
|
||||||
|
self.memory_start
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_memory_start(&mut self, memory_start: usize) {
|
||||||
|
self.memory_start = memory_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Light for DirectionalLight {
|
||||||
|
fn get_light_type(&self) -> LightType {
|
||||||
|
LightType::DIRECTION
|
||||||
|
}
|
||||||
|
|
||||||
|
fn weighted_distance(&self, center: Vector3<usize>) -> f32 {
|
||||||
|
let light_intensity = self.color.magnitude();
|
||||||
|
|
||||||
|
light_intensity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LightSource for DirectionalLight {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_memorizable() {
|
||||||
|
let p = PointLight {pos: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||||
|
let data= AppData::default();
|
||||||
|
let scene = Scene::default();
|
||||||
|
|
||||||
|
let mem_size = p.get_buffer_mem_size(&data);
|
||||||
|
assert!(mem_size == 7);
|
||||||
|
|
||||||
|
let mut memory = vec![0; 7];
|
||||||
|
p.insert_into_memory(memory, &data, &scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_mem_size() {
|
||||||
|
let p = PointLight {pos: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||||
|
let data= AppData::default();
|
||||||
|
let scene = Scene::default();
|
||||||
|
|
||||||
|
let mem_size = p.get_buffer_mem_size(&data);
|
||||||
|
assert!(mem_size == 7);
|
||||||
|
|
||||||
|
let mut memory = vec![0; 6];
|
||||||
|
p.insert_into_memory(memory, &data, &scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_memorizable_directional_light() {
|
||||||
|
let p = DirectionalLight {direction: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||||
|
let data= AppData::default();
|
||||||
|
let scene = Scene::default();
|
||||||
|
|
||||||
|
let mem_size = p.get_buffer_mem_size(&data);
|
||||||
|
assert!(mem_size == 7);
|
||||||
|
|
||||||
|
let mut memory = vec![0; 7];
|
||||||
|
p.insert_into_memory(memory, &data, &scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn test_mem_size_directional_light() {
|
||||||
|
let p = DirectionalLight {direction: vertex::Vec3 { x: 1.0, y: 2.0, z: 3.0}, color: vertex::Vec3 { x: 0.0, y: 1.0, z: 0.0}, memory_start: 0};
|
||||||
|
let data= AppData::default();
|
||||||
|
let scene = Scene::default();
|
||||||
|
|
||||||
|
let mem_size = p.get_buffer_mem_size(&data);
|
||||||
|
assert!(mem_size == 7);
|
||||||
|
|
||||||
|
let mut memory = vec![0; 6];
|
||||||
|
p.insert_into_memory(memory, &data, &scene);
|
||||||
|
}
|
||||||
}
|
}
|
10
src/scene/memorizable.rs
Normal file
10
src/scene/memorizable.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use super::light::LightSource;
|
||||||
|
use super::AppData;
|
||||||
|
use super::Scene;
|
||||||
|
|
||||||
|
pub trait Memorizable {
|
||||||
|
fn get_buffer_mem_size(&self, data: &AppData) -> u32;
|
||||||
|
fn insert_into_memory(&self, v: Vec<u32>, data: &AppData, scene: &Scene) -> Vec<u32>;
|
||||||
|
fn get_memory_start(&self) -> usize;
|
||||||
|
fn set_memory_start(&mut self, memory_start: usize);
|
||||||
|
}
|
|
@ -1,8 +1,10 @@
|
||||||
mod oct_tree;
|
mod oct_tree;
|
||||||
mod empty_volume;
|
mod empty_volume;
|
||||||
mod light;
|
mod light;
|
||||||
|
mod memorizable;
|
||||||
|
|
||||||
use anyhow::Ok;
|
use anyhow::Ok;
|
||||||
|
use light::{DirectionalLight, LightSource};
|
||||||
use vulkanalia::prelude::v1_0::*;
|
use vulkanalia::prelude::v1_0::*;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
@ -11,6 +13,7 @@ use cgmath::{vec2, vec3, Vector3};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::scene::memorizable::Memorizable;
|
||||||
use crate::app_data::AppData;
|
use crate::app_data::AppData;
|
||||||
use crate::buffer;
|
use crate::buffer;
|
||||||
use crate::primitives::rec_cuboid::Cuboid;
|
use crate::primitives::rec_cuboid::Cuboid;
|
||||||
|
@ -54,7 +57,8 @@ pub struct Scene {
|
||||||
|
|
||||||
pub rt_memory: Vec<u32>,
|
pub rt_memory: Vec<u32>,
|
||||||
|
|
||||||
pub point_lights: Vec<PointLight>,
|
point_lights: Vec<Rc<RefCell<PointLight>>>,
|
||||||
|
directional_lights: Vec<Rc<RefCell<DirectionalLight>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene {
|
impl Scene {
|
||||||
|
@ -99,8 +103,9 @@ impl Scene {
|
||||||
};
|
};
|
||||||
oct_tree.set_cube(cube.clone());
|
oct_tree.set_cube(cube.clone());
|
||||||
|
|
||||||
self.point_lights.push(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(1.0, 1.0, 1.0), memory_start: 0 });
|
self.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(11.0, 11.0, 11.0), color: vec3(1.0, 1.0, 1.0), memory_start: 0 })));
|
||||||
self.point_lights.push(PointLight { pos: vec3(9.0, 9.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 });
|
self.point_lights.push(Rc::new(RefCell::new(PointLight { pos: vec3(9.0, 9.0, 11.0), color: vec3(0.5, 0.5, 0.5), memory_start: 0 })));
|
||||||
|
self.directional_lights.push(Rc::new(RefCell::new(DirectionalLight { direction: vec3(1.0, 1.0, -1.0), color: vec3(0.1, 0.1, 0.1), memory_start: 0 })));
|
||||||
|
|
||||||
let empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
|
let empty_volumes: Vec<Rc<RefCell<EmptyVolume>>>;
|
||||||
(empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree);
|
(empty_volumes, _) = EmptyVolume::from_oct_tree(&oct_tree);
|
||||||
|
@ -156,14 +161,14 @@ impl Scene {
|
||||||
// 3 - diffuse raster size
|
// 3 - diffuse raster size
|
||||||
// 4 - max recursive rays
|
// 4 - max recursive rays
|
||||||
// 5 - diffuse rays per hit
|
// 5 - diffuse rays per hit
|
||||||
for light in &mut self.point_lights {
|
for light in LightsIter::new(self) {
|
||||||
light.memory_start = memory_index;
|
light.borrow_mut().set_memory_start(memory_index);
|
||||||
memory_index += light.get_buffer_mem_size() as usize;
|
memory_index += light.borrow_mut().get_buffer_mem_size(data) as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
for volume in &empty_volumes {
|
for volume in &empty_volumes {
|
||||||
volume.borrow_mut().memory_start = memory_index;
|
volume.borrow_mut().set_memory_start(memory_index);
|
||||||
memory_index += volume.borrow().get_buffer_mem_size(data.num_lights_per_volume) as usize;
|
memory_index += volume.borrow().get_buffer_mem_size(data) as usize;
|
||||||
|
|
||||||
}
|
}
|
||||||
for volume in &empty_volumes {
|
for volume in &empty_volumes {
|
||||||
|
@ -181,10 +186,10 @@ impl Scene {
|
||||||
volume_vec[5] = data.diffuse_rays_per_hit;
|
volume_vec[5] = data.diffuse_rays_per_hit;
|
||||||
|
|
||||||
for volume in &empty_volumes {
|
for volume in &empty_volumes {
|
||||||
volume_vec = volume.borrow().insert_into_memory(volume_vec, data.num_lights_per_volume, &self.point_lights);
|
volume_vec = volume.borrow().insert_into_memory(volume_vec, data, &self);
|
||||||
}
|
}
|
||||||
for light in &self.point_lights {
|
for light in LightsIter::new(self) {
|
||||||
volume_vec = light.insert_into_memory(volume_vec);
|
volume_vec = light.borrow().insert_into_memory(volume_vec, data, &self);
|
||||||
}
|
}
|
||||||
//println!("volume_vec print {:?}", volume_vec);
|
//println!("volume_vec print {:?}", volume_vec);
|
||||||
|
|
||||||
|
@ -229,4 +234,40 @@ impl Scene {
|
||||||
device.destroy_buffer(self.vertex_buffer_quad, None);
|
device.destroy_buffer(self.vertex_buffer_quad, None);
|
||||||
device.free_memory(self.vertex_buffer_memory_quad, None);
|
device.free_memory(self.vertex_buffer_memory_quad, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_light_iter(&self) -> LightsIter {
|
||||||
|
LightsIter::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct LightsIter<'a> {
|
||||||
|
light_index: usize,
|
||||||
|
scene: &'a Scene,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> LightsIter<'a> {
|
||||||
|
fn new(scene: &'a Scene) -> Self {
|
||||||
|
LightsIter {light_index: 0, scene: scene}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for LightsIter<'a> {
|
||||||
|
type Item = Rc<RefCell<dyn LightSource>>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.light_index >= self.scene.point_lights.len() {
|
||||||
|
if self.light_index - self.scene.point_lights.len() >= self.scene.directional_lights.len() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let result = self.scene.directional_lights[self.light_index - self.scene.point_lights.len()].clone();
|
||||||
|
self.light_index += 1;
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let result = self.scene.point_lights[self.light_index].clone();
|
||||||
|
self.light_index += 1;
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -601,7 +601,7 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_oct_tree(){
|
fn test_oct_tree(){
|
||||||
let mut test_tree: OctTree<Cube> = OctTree::create(512).unwrap();
|
let mut test_tree: OctTree<Cube> = OctTree::create(512).unwrap();
|
||||||
let test_cube = Cube{color: Vector3 { x: 1.0, y: 0.0, z: 0.0 }, pos: Vector3 { x: 5.0, y: 2.0, z: 10.0 }, tex_coord: Vector2{x: 0.0, y: 0.0}, transparent: false};
|
let test_cube = Cube{color: Vector3 { x: 1.0, y: 0.0, z: 0.0 }, pos: Vector3 { x: 5.0, y: 2.0, z: 10.0 }, tex_coord: Vector2{x: 0.0, y: 0.0}, transparent: false, roughness: 128};
|
||||||
|
|
||||||
test_tree.set_cube(test_cube.clone());
|
test_tree.set_cube(test_cube.clone());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue