small refactor

This commit is contained in:
2025-07-04 18:52:19 +01:00
parent 92c16558a3
commit ce78812dd3
6 changed files with 462 additions and 337 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ layout(set = 0, binding = 0) uniform Lights {
layout(set = 0, binding = 1) uniform Camera {
mat4 view;
mat4 proj;
vec3 campos;
vec4 campos_and_time;
} camera_uniforms;
#endif
+10 -2
View File
@@ -113,7 +113,7 @@ impl<'csg> PointInterpreter<'csg> {
// cargo asm "erroccfisuvsc::interpreter::PointInterpreter::scene" --no-color
// --rust > scene.asm
pub(crate) fn scene(&mut self, px: Value, py: Value, pz: Value) -> Value {
pub(crate) fn scene(&mut self, px: Value, py: Value, pz: Value, time: Value) -> Value {
self.clear_stacks();
for instruction in &self.csg.parts.tape {
@@ -126,6 +126,7 @@ impl<'csg> PointInterpreter<'csg> {
self.store(instruction.outputs[0], px);
self.store(instruction.outputs[1], py);
self.store(instruction.outputs[2], pz);
self.store(instruction.outputs[3], time);
},
SSAAdd => {
self.param_two(instruction, |val_a, val_b| val_a + val_b);
@@ -523,7 +524,13 @@ impl<'csg> IntervalInterpreter<'csg> {
// cargo asm "erroccfisuvsc::interpreter::IntervalInterpreter::scene" --no-color
// --rust > scene.asm
pub(crate) fn scene(&mut self, px: Interval, py: Interval, pz: Interval) -> Interval {
pub(crate) fn scene(
&mut self,
px: Interval,
py: Interval,
pz: Interval,
time: Interval,
) -> Interval {
self.clear_stacks();
for instruction in &self.csg.parts.tape {
@@ -536,6 +543,7 @@ impl<'csg> IntervalInterpreter<'csg> {
self.store(instruction.outputs[0], px);
self.store(instruction.outputs[1], py);
self.store(instruction.outputs[2], pz);
self.store(instruction.outputs[3], time);
},
SSAAdd => {
self.param_two(instruction, |val_a, val_b| val_a + val_b);
+427 -313
View File
@@ -15,7 +15,7 @@ use std::{
io::{Cursor, Read, Write},
path::{Path, PathBuf},
simd::{StdFloat, cmp::SimdPartialOrd},
sync::Arc,
sync::{Arc, Mutex},
time::Instant,
};
@@ -35,8 +35,8 @@ use vulkano::{
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
},
command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, CopyBufferInfo, PrimaryCommandBufferAbstract,
RenderPassBeginInfo, SubpassBeginInfo, SubpassContents,
AutoCommandBufferBuilder, CommandBufferUsage, CopyBufferInfo, PrimaryAutoCommandBuffer,
PrimaryCommandBufferAbstract, RenderPassBeginInfo, SubpassBeginInfo, SubpassContents,
allocator::StandardCommandBufferAllocator,
},
descriptor_set::{
@@ -47,10 +47,7 @@ use vulkano::{
QueueCreateInfo, QueueFlags, physical::PhysicalDeviceType,
},
format::{ClearValue, Format},
image::{
Image, ImageCreateInfo, ImageType, ImageUsage, SampleCount,
view::ImageView,
},
image::{Image, ImageCreateInfo, ImageType, ImageUsage, SampleCount, view::ImageView},
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
memory::allocator::{
AllocationCreateInfo, MemoryAllocatePreference, MemoryTypeFilter, StandardMemoryAllocator,
@@ -81,6 +78,7 @@ use vulkano::{
};
use winit::{
application::ApplicationHandler,
dpi::PhysicalSize,
event::{DeviceEvent, ElementState, MouseButton, WindowEvent},
event_loop::{ActiveEventLoop, EventLoop},
keyboard::{KeyCode, PhysicalKey},
@@ -89,7 +87,11 @@ use winit::{
};
mod gui;
use crate::{gui::*, implicit_vs::PushConstantData, types::Interval};
use crate::{
gui::*,
implicit_vs::{Camera, Lights, PushConstantData},
types::Interval,
};
mod objects;
use crate::objects::*;
@@ -194,10 +196,11 @@ struct App {
csg_count: usize,
previous_debug: PreviousDebug,
cstate: CState,
time: f32,
vertex_buffer: Subbuffer<[IVertex; VERTEX_COUNT]>,
trace_module: Module,
normals_module: Module,
rcx: Option<RenderContext>,
rcx: Arc<Mutex<Option<RenderContext>>>,
}
struct ShaderModules {
@@ -217,6 +220,8 @@ struct RenderContext {
material_buffer: Arc<ImageView>,
normal_buffer: Arc<ImageView>,
depth_buffer: Arc<ImageView>,
camera_buffers: Vec<Subbuffer<Camera>>,
lights_buffers: Vec<Subbuffer<Lights>>,
shader_modules: ShaderModules,
implicit_pipelines: Vec<Arc<GraphicsPipeline>>,
normals_pipelines: Vec<Arc<GraphicsPipeline>>,
@@ -305,7 +310,7 @@ fn create_csg() -> SSATape {
tape
}
fn interval_check(csg: &CSG, push_constants: &mut PushConstantData) {
fn interval_check(csg: &CSG, push_constants: &mut PushConstantData, time: f32) {
const INTERPRET_INPUT_X: interpreter::Value =
interpreter::Value::from_array([10000.0, 0.0, 0.0, -10000.0, 0.0, 0.0, 0.0, 0.0]);
const INTERPRET_INPUT_Y: interpreter::Value =
@@ -320,7 +325,12 @@ fn interval_check(csg: &CSG, push_constants: &mut PushConstantData) {
let mut interpreter = PointInterpreter::new(csg);
let interpreter_out = interpreter
.scene(INTERPRET_INPUT_X, INTERPRET_INPUT_Y, INTERPRET_INPUT_Z)
.scene(
INTERPRET_INPUT_X,
INTERPRET_INPUT_Y,
INTERPRET_INPUT_Z,
interpreter::Value::splat(time),
)
.mul_add(INTERPRET_MUL, INTERPRET_ADD)
.to_array();
@@ -372,6 +382,7 @@ fn interval_check(csg: &CSG, push_constants: &mut PushConstantData) {
+ push_constants.lowest_corner[1],
),
interval_input_z,
Interval::const_splat(time),
);
let output = ((output.lower().simd_le(VALUE_0) & output.upper().simd_ge(VALUE_0))
@@ -615,10 +626,11 @@ impl App {
gstate,
previous_debug: PreviousDebug::default(),
cstate,
time: 0.0,
vertex_buffer,
trace_module,
normals_module,
rcx: None,
rcx: Arc::new(Mutex::new(None)),
}
}
}
@@ -851,6 +863,13 @@ impl ApplicationHandler for App {
if DYNAMIC_STATE { None } else { Some(&viewport) },
);
let camera_buffers: Vec<Subbuffer<Camera>> = (0..swapchain.image_count())
.map(|_| self.uniform_buffer_allocator.allocate_sized().unwrap())
.collect();
let lights_buffers: Vec<Subbuffer<Lights>> = (0..swapchain.image_count())
.map(|_| self.uniform_buffer_allocator.allocate_sized().unwrap())
.collect();
let previous_frame_end = Some(sync::now(self.device.clone()).boxed());
// Create an egui GUI
@@ -867,7 +886,7 @@ impl ApplicationHandler for App {
},
);
self.rcx = Some(RenderContext {
*self.rcx.lock().unwrap() = Some(RenderContext {
window,
swapchain,
render_pass,
@@ -876,6 +895,8 @@ impl ApplicationHandler for App {
material_buffer,
normal_buffer,
depth_buffer,
camera_buffers,
lights_buffers,
shader_modules,
implicit_pipelines: vec![],
normals_pipelines: vec![],
@@ -914,7 +935,9 @@ impl ApplicationHandler for App {
_window_id: winit::window::WindowId,
event: WindowEvent,
) {
let rcx = self.rcx.as_mut().unwrap();
let rcx_clone = self.rcx.clone();
let mut rcx_lock = rcx_clone.lock().unwrap();
let rcx = rcx_lock.as_mut().unwrap();
if !rcx.gui.update(&event) {
match &event {
WindowEvent::CloseRequested => {
@@ -976,13 +999,12 @@ impl ApplicationHandler for App {
rot: Vec3::ZERO,
scale: Vec3::ONE,
};
let rcx = self.rcx.as_mut().unwrap();
rcx.recreate_shaders = true;
},
_ => {},
},
WindowEvent::RedrawRequested => {
self.redraw();
self.redraw(rcx);
},
_ => {},
}
@@ -990,15 +1012,369 @@ impl ApplicationHandler for App {
}
fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) {
let rcx = self.rcx.as_mut().unwrap();
let rcx_clone = self.rcx.clone();
let mut rcx_lock = rcx_clone.lock().unwrap();
let rcx = rcx_lock.as_mut().unwrap();
rcx.window.request_redraw();
}
}
impl App {
fn redraw(&mut self) {
let rcx = self.rcx.as_mut().unwrap();
fn move_camera(&mut self) {
if self.cstate.looking {
if self.cstate.keys.w {
self.cstate.position -=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::Z
* 0.01
* self.gstate.move_speed;
}
if self.cstate.keys.s {
self.cstate.position +=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::Z
* 0.01
* self.gstate.move_speed;
}
if self.cstate.keys.a {
self.cstate.position -=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::X
* 0.01
* self.gstate.move_speed;
}
if self.cstate.keys.d {
self.cstate.position +=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::X
* 0.01
* self.gstate.move_speed;
}
} else {
self.cstate.keys.w = false;
self.cstate.keys.s = false;
self.cstate.keys.a = false;
self.cstate.keys.d = false;
}
}
fn update_camera_uniform(&self, rcx: &mut RenderContext, index: usize) {
let near = 0.01;
let far = 100.0;
let aspect_ratio =
rcx.swapchain.image_extent()[0] as f32 / rcx.swapchain.image_extent()[1] as f32;
let proj = Mat4::perspective_rh_gl(std::f32::consts::FRAC_PI_2, aspect_ratio, near, far);
let view = Mat4::from_euler(EulerRot::XYZ, self.cstate.forward.x.to_radians(), self.cstate.forward.y.to_radians(), self.cstate.forward.z.to_radians())
//* Mat4::from_rotation_z(std::f32::consts::PI)
* Mat4::from_translation(Vec3::ZERO - self.cstate.position);
let uniform_data = implicit_vs::Camera {
view: view.to_cols_array_2d(),
proj: proj.to_cols_array_2d(),
campos_and_time: [
self.cstate.position.x,
self.cstate.position.y,
self.cstate.position.z,
self.time,
],
};
*rcx.camera_buffers[index].write().unwrap() = uniform_data;
if self.cstate.looking {
trace!(
"campos: {:?} camforward: {:?}",
self.cstate.position, self.cstate.forward
);
}
}
fn get_push_constants(&self) -> PushConstantData {
let pc = implicit_vs::PushConstantData {
world: Mat4::IDENTITY.to_cols_array_2d(),
dimensions: Vec3::ONE.to_array().into(),
lowest_corner: Vec3::ZERO.into(),
enable: [0; 16],
material: 0,
};
pc
}
fn update_lights_uniform(&self, rcx: &mut RenderContext, index: usize) {
let mut pos = [[0f32; 4]; 32];
let mut col = [[0f32; 4]; 32];
for (i, light) in self.gstate.lights.iter().enumerate() {
pos[i][0] = light.pos.x;
pos[i][1] = light.pos.y;
pos[i][2] = light.pos.z;
col[i][0] = light.colour.x;
col[i][1] = light.colour.y;
col[i][2] = light.colour.z;
}
let uniform_data = implicit_vs::Lights {
pos,
col,
light_count: self.gstate.lights.len() as u32,
};
*rcx.lights_buffers[index].write().unwrap() = uniform_data;
}
fn get_descriptor_sets(
&self,
rcx: &mut RenderContext,
index: usize,
) -> (
Option<Arc<DescriptorSet>>,
Option<Arc<DescriptorSet>>,
Option<Arc<DescriptorSet>>,
Arc<DescriptorSet>,
Arc<DescriptorSet>,
) {
let implicit_set = if rcx.implicit_pipelines.len() > 0 {
let implicit_layout = &rcx.implicit_pipelines[0].layout().set_layouts()[0];
let implicit_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
implicit_layout.clone(),
[WriteDescriptorSet::buffer(
1,
rcx.camera_buffers[index].clone(),
)],
[],
)
.unwrap();
Some(implicit_set)
} else {
None
};
let normals_set1 = if rcx.normals_pipelines.len() > 0 {
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[0];
let normals_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
normals_layout.clone(),
[WriteDescriptorSet::buffer(
1,
rcx.camera_buffers[index].clone(),
)],
[],
)
.unwrap();
Some(normals_set)
} else {
None
};
let normals_set2 = if rcx.normals_pipelines.len() > 0 {
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[1];
let normals_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
normals_layout.clone(),
[
WriteDescriptorSet::image_view(0, rcx.material_buffer.clone()),
WriteDescriptorSet::image_view(1, rcx.depth_buffer.clone()),
],
[],
)
.unwrap();
Some(normals_set)
} else {
None
};
let lighting_layout1 = &rcx.lighting_pipeline.layout().set_layouts()[0];
let lighting_set1 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
lighting_layout1.clone(),
[
WriteDescriptorSet::buffer(0, rcx.lights_buffers[index].clone()),
WriteDescriptorSet::buffer(1, rcx.camera_buffers[index].clone()),
],
[],
)
.unwrap();
let lighting_layout2 = &rcx.lighting_pipeline.layout().set_layouts()[1];
let lighting_set2 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
lighting_layout2.clone(),
[
WriteDescriptorSet::image_view(0, rcx.color_buffer.clone()),
WriteDescriptorSet::image_view(1, rcx.normal_buffer.clone()),
WriteDescriptorSet::image_view(2, rcx.depth_buffer.clone()),
],
[],
)
.unwrap();
(
implicit_set,
normals_set1,
normals_set2,
lighting_set1,
lighting_set2,
)
}
fn add_commands_primary_subpass(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
) {
builder
.next_subpass(
Default::default(),
SubpassBeginInfo {
contents: SubpassContents::Inline,
..Default::default()
},
)
.unwrap();
}
fn add_commands_secondary_subpass(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
) {
builder
.next_subpass(
Default::default(),
SubpassBeginInfo {
contents: SubpassContents::SecondaryCommandBuffers,
..Default::default()
},
)
.unwrap();
}
fn add_commands_depth_pass(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
rcx: &mut RenderContext,
mut push_constants: PushConstantData,
implicit_set: Arc<DescriptorSet>,
) {
for (i, csg) in self.gstate.csg.iter().enumerate() {
builder
.bind_pipeline_graphics(rcx.implicit_pipelines[i].clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
rcx.implicit_pipelines[i].layout().clone(),
0,
implicit_set.clone(),
)
.unwrap()
.bind_vertex_buffers(0, self.vertex_buffer.clone())
.unwrap();
push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler(
EulerRot::XYZ,
csg.rot.x.to_radians(),
csg.rot.y.to_radians(),
csg.rot.z.to_radians(),
)
* Mat4::from_scale(csg.scale * 2.0))
.to_cols_array_2d();
interval_check(csg, &mut push_constants, self.time);
push_constants.material = i as _;
builder
.push_constants(
rcx.implicit_pipelines[i].layout().clone(),
0,
push_constants,
)
.unwrap();
for i in 0..(8 * 8 * 8) {
unsafe { builder.draw(VERTEX_COUNT as u32, 1, 0, i) }.unwrap();
}
}
}
fn add_commands_normal_pass(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
rcx: &mut RenderContext,
mut push_constants: PushConstantData,
normals_set1: Arc<DescriptorSet>,
normals_set2: Arc<DescriptorSet>,
) {
for (i, csg) in self.gstate.csg.iter().enumerate() {
builder
.bind_pipeline_graphics(rcx.normals_pipelines[i].clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
rcx.normals_pipelines[i].layout().clone(),
0,
vec![normals_set1.clone(), normals_set2.clone()],
)
.unwrap();
push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler(
EulerRot::XYZ,
csg.rot.x.to_radians(),
csg.rot.y.to_radians(),
csg.rot.z.to_radians(),
)
* Mat4::from_scale(csg.scale * 2.0))
.to_cols_array_2d();
push_constants.material = i as _;
builder
.push_constants(rcx.normals_pipelines[i].layout().clone(), 0, push_constants)
.unwrap();
unsafe { builder.draw(3, 1, 0, 0) }.unwrap();
}
}
fn add_commands_lighting_pass(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
rcx: &mut RenderContext,
lighting_set1: Arc<DescriptorSet>,
lighting_set2: Arc<DescriptorSet>,
) {
builder
.bind_pipeline_graphics(rcx.lighting_pipeline.clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
rcx.lighting_pipeline.layout().clone(),
0,
vec![lighting_set1, lighting_set2],
)
.unwrap();
unsafe { builder.draw(3, 1, 0, 0) }.unwrap();
}
fn add_commands_gui(
&self,
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
rcx: &mut RenderContext,
window_size: PhysicalSize<u32>,
) {
let guicb = rcx.gui.draw_on_subpass_image(window_size.into());
builder.execute_commands(guicb).unwrap();
}
fn redraw(&mut self, rcx: &mut RenderContext) {
let window_size = rcx.window.inner_size();
if window_size.width == 0 || window_size.height == 0 {
rcx.render_start = Instant::now();
@@ -1130,178 +1506,7 @@ impl App {
rcx.recreate_pipelines = false;
}
let (mut push_constants, cam_set) = {
if self.cstate.looking {
if self.cstate.keys.w {
self.cstate.position -=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::Z
* 0.01
* self.gstate.move_speed;
}
if self.cstate.keys.s {
self.cstate.position +=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::Z
* 0.01
* self.gstate.move_speed;
}
if self.cstate.keys.a {
self.cstate.position -=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::X
* 0.01
* self.gstate.move_speed;
}
if self.cstate.keys.d {
self.cstate.position +=
Mat3::from_rotation_y(self.cstate.forward.y.to_radians() * -1.)
* Mat3::from_rotation_x(self.cstate.forward.x.to_radians() * -1.)
* Vec3::X
* 0.01
* self.gstate.move_speed;
}
} else {
self.cstate.keys.w = false;
self.cstate.keys.s = false;
self.cstate.keys.a = false;
self.cstate.keys.d = false;
}
let near = 0.01;
let far = 100.0;
let aspect_ratio =
rcx.swapchain.image_extent()[0] as f32 / rcx.swapchain.image_extent()[1] as f32;
let proj =
Mat4::perspective_rh_gl(std::f32::consts::FRAC_PI_2, aspect_ratio, near, far);
let view = Mat4::from_euler(EulerRot::XYZ, self.cstate.forward.x.to_radians(), self.cstate.forward.y.to_radians(), self.cstate.forward.z.to_radians())
//* Mat4::from_rotation_z(std::f32::consts::PI)
* Mat4::from_translation(Vec3::ZERO - self.cstate.position);
let pc = implicit_vs::PushConstantData {
world: Mat4::IDENTITY.to_cols_array_2d(),
dimensions: Vec3::ONE.to_array().into(),
lowest_corner: Vec3::ZERO.into(),
enable: [0; 16],
material: 0,
};
let uniform_data = implicit_vs::Camera {
view: view.to_cols_array_2d(),
proj: proj.to_cols_array_2d(),
campos: self.cstate.position.to_array(),
};
let sub = self.uniform_buffer_allocator.allocate_sized().unwrap();
*sub.write().unwrap() = uniform_data;
if self.cstate.looking {
trace!(
"campos: {:?} camforward: {:?}",
self.cstate.position, self.cstate.forward
);
}
(pc, sub)
};
let uniform_buffer_subbuffer = {
let mut pos = [[0f32; 4]; 32];
let mut col = [[0f32; 4]; 32];
for (i, light) in self.gstate.lights.iter().enumerate() {
pos[i][0] = light.pos.x;
pos[i][1] = light.pos.y;
pos[i][2] = light.pos.z;
col[i][0] = light.colour.x;
col[i][1] = light.colour.y;
col[i][2] = light.colour.z;
}
let uniform_data = implicit_vs::Lights {
pos,
col,
light_count: self.gstate.lights.len() as u32,
};
let sub = self.uniform_buffer_allocator.allocate_sized().unwrap();
*sub.write().unwrap() = uniform_data;
sub
};
let implicit_set = if rcx.implicit_pipelines.len() > 0 {
let implicit_layout = &rcx.implicit_pipelines[0].layout().set_layouts()[0];
let implicit_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
implicit_layout.clone(),
[WriteDescriptorSet::buffer(1, cam_set.clone())],
[],
)
.unwrap();
Some(implicit_set)
} else {
None
};
let normals_set1 = if rcx.normals_pipelines.len() > 0 {
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[0];
let normals_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
normals_layout.clone(),
[WriteDescriptorSet::buffer(1, cam_set.clone())],
[],
)
.unwrap();
Some(normals_set)
} else {
None
};
let normals_set2 = if rcx.normals_pipelines.len() > 0 {
let normals_layout = &rcx.normals_pipelines[0].layout().set_layouts()[1];
let normals_set = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
normals_layout.clone(),
[
WriteDescriptorSet::image_view(0, rcx.material_buffer.clone()),
WriteDescriptorSet::image_view(1, rcx.depth_buffer.clone()),
],
[],
)
.unwrap();
Some(normals_set)
} else {
None
};
let lighting_layout1 = &rcx.lighting_pipeline.layout().set_layouts()[0];
let lighting_set1 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
lighting_layout1.clone(),
[
WriteDescriptorSet::buffer(0, uniform_buffer_subbuffer.clone()),
WriteDescriptorSet::buffer(1, cam_set.clone()),
],
[],
)
.unwrap();
let lighting_layout2 = &rcx.lighting_pipeline.layout().set_layouts()[1];
let lighting_set2 = DescriptorSet::new(
self.descriptor_set_allocator.clone(),
lighting_layout2.clone(),
[
WriteDescriptorSet::image_view(0, rcx.color_buffer.clone()),
WriteDescriptorSet::image_view(1, rcx.normal_buffer.clone()),
WriteDescriptorSet::image_view(2, rcx.depth_buffer.clone()),
],
[],
)
.unwrap();
self.move_camera();
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(rcx.swapchain.clone(), None).map_err(Validated::unwrap) {
@@ -1325,6 +1530,16 @@ impl App {
}
}
let image_index = image_index as usize;
self.update_camera_uniform(rcx, image_index);
self.update_lights_uniform(rcx, image_index);
let push_constants = self.get_push_constants();
let (implicit_set, normals_set1, normals_set2, lighting_set1, lighting_set2) =
self.get_descriptor_sets(rcx, image_index);
let mut builder = AutoCommandBufferBuilder::primary(
self.command_buffer_allocator.clone(),
self.graphics_queue.queue_family_index(),
@@ -1332,8 +1547,6 @@ impl App {
)
.unwrap();
let guicb = rcx.gui.draw_on_subpass_image(window_size.into());
builder
.begin_render_pass(
RenderPassBeginInfo {
@@ -1344,9 +1557,7 @@ impl App {
Some([0.0, 0.0, 0.0, 1.0].into()),
Some(1.0.into()),
],
..RenderPassBeginInfo::framebuffer(
rcx.framebuffers[image_index as usize].clone(),
)
..RenderPassBeginInfo::framebuffer(rcx.framebuffers[image_index].clone())
},
SubpassBeginInfo {
contents: SubpassContents::Inline,
@@ -1361,125 +1572,25 @@ impl App {
.unwrap();
}
for (i, csg) in self.gstate.csg.iter().enumerate() {
builder
.bind_pipeline_graphics(rcx.implicit_pipelines[i].clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
rcx.implicit_pipelines[i].layout().clone(),
0,
implicit_set.clone().unwrap(),
)
.unwrap()
.bind_vertex_buffers(0, self.vertex_buffer.clone())
.unwrap();
push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler(
EulerRot::XYZ,
csg.rot.x.to_radians(),
csg.rot.y.to_radians(),
csg.rot.z.to_radians(),
)
* Mat4::from_scale(csg.scale * 2.0))
.to_cols_array_2d();
interval_check(csg, &mut push_constants);
push_constants.material = i as _;
builder
.push_constants(
rcx.implicit_pipelines[i].layout().clone(),
0,
push_constants,
)
.unwrap();
for i in 0..(8 * 8 * 8) {
unsafe { builder.draw(VERTEX_COUNT as u32, 1, 0, i) }.unwrap();
}
if self.gstate.csg.len() > 0 {
self.add_commands_depth_pass(&mut builder, rcx, push_constants, implicit_set.unwrap());
}
builder
.next_subpass(
Default::default(),
SubpassBeginInfo {
contents: SubpassContents::Inline,
..Default::default()
},
)
.unwrap();
for (i, csg) in self.gstate.csg.iter().enumerate() {
builder
.bind_pipeline_graphics(rcx.normals_pipelines[i].clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
rcx.normals_pipelines[i].layout().clone(),
0,
vec![normals_set1.clone().unwrap(), normals_set2.clone().unwrap()],
)
.unwrap();
push_constants.world = (Mat4::from_translation(csg.pos * 0.01)
* Mat4::from_euler(
EulerRot::XYZ,
csg.rot.x.to_radians(),
csg.rot.y.to_radians(),
csg.rot.z.to_radians(),
)
* Mat4::from_scale(csg.scale * 2.0))
.to_cols_array_2d();
push_constants.material = i as _;
builder
.push_constants(rcx.normals_pipelines[i].layout().clone(), 0, push_constants)
.unwrap();
unsafe { builder.draw(3, 1, 0, 0) }.unwrap();
self.add_commands_primary_subpass(&mut builder);
if self.gstate.csg.len() > 0 {
self.add_commands_normal_pass(
&mut builder,
rcx,
push_constants,
normals_set1.unwrap(),
normals_set2.unwrap(),
);
}
self.add_commands_primary_subpass(&mut builder);
self.add_commands_lighting_pass(&mut builder, rcx, lighting_set1, lighting_set2);
self.add_commands_secondary_subpass(&mut builder);
self.add_commands_gui(&mut builder, rcx, window_size);
builder
.next_subpass(
Default::default(),
SubpassBeginInfo {
contents: SubpassContents::Inline,
..Default::default()
},
)
.unwrap();
builder
.bind_pipeline_graphics(rcx.lighting_pipeline.clone())
.unwrap()
.bind_descriptor_sets(
PipelineBindPoint::Graphics,
rcx.lighting_pipeline.layout().clone(),
0,
vec![lighting_set1, lighting_set2],
)
.unwrap();
unsafe { builder.draw(3, 1, 0, 0) }.unwrap();
builder
.next_subpass(
Default::default(),
SubpassBeginInfo {
contents: SubpassContents::SecondaryCommandBuffers,
..Default::default()
},
)
.unwrap()
.execute_commands(guicb)
.unwrap()
.end_render_pass(Default::default())
.unwrap();
builder.end_render_pass(Default::default()).unwrap();
let command_buffer = builder.build().unwrap();
let future = rcx
@@ -1491,7 +1602,10 @@ impl App {
.unwrap()
.then_swapchain_present(
self.graphics_queue.clone(),
SwapchainPresentInfo::swapchain_image_index(rcx.swapchain.clone(), image_index),
SwapchainPresentInfo::swapchain_image_index(
rcx.swapchain.clone(),
image_index as u32,
),
)
.then_signal_fence_and_flush();
+6 -6
View File
@@ -12,8 +12,8 @@ layout(input_attachment_index = 1, set = 1, binding = 1) uniform subpassInput u_
layout(location = 0) out vec4 f_color;
layout(location = 1) out vec4 f_normal;
float scene(vec3 p) {
return length(p) - 1.0;
float scene(vec4 p) {
return length(p.xyz) - 1.0;
}
vec3 WorldPosFromDepth(float depth) {
@@ -28,10 +28,10 @@ const float EPSILON = .0001;
vec3 getNormal(vec3 p) {
vec3 n;
n.x = scene(vec3(p.x + EPSILON, p.y, p.z)).x;
n.y = scene(vec3(p.x, p.y + EPSILON, p.z)).x;
n.z = scene(vec3(p.x, p.y, p.z + EPSILON)).x;
return normalize(n - (scene(p)));
n.x = scene(vec4(p.x + EPSILON, p.y, p.z, camera_uniforms.campos_and_time.w));
n.y = scene(vec4(p.x, p.y + EPSILON, p.z, camera_uniforms.campos_and_time.w));
n.z = scene(vec4(p.x, p.y, p.z + EPSILON, camera_uniforms.campos_and_time.w));
return normalize(n - (scene(vec4(p, camera_uniforms.campos_and_time.w))));
}
//Implicit Surface Entrypoint
+13 -10
View File
@@ -106,7 +106,7 @@ impl SSAOpcodeSized {
match self.opcode {
SSAStop => 0,
SSAReturn => 0,
SSAPosition => 3,
SSAPosition => 4,
SSAMinMaterial => 1,
SSAMaxMaterial => 1,
SSASmoothMinMaterial => 1,
@@ -474,15 +474,14 @@ impl SSATape {
let void = b.type_void();
let float = b.type_float(32);
let bool = b.type_bool();
let vec1 = float; // b.type_vector(float, 1);
let vec2 = b.type_vector(float, 2);
let vec3 = b.type_vector(float, 3);
let vec4 = b.type_vector(float, 4);
let vec3p = b.type_pointer(None, spirv::StorageClass::Function, vec3);
let vec4p = b.type_pointer(None, spirv::StorageClass::Function, vec4);
let scene_fn_type = if with_module {
9
} else {
b.type_function(float, vec![vec3p])
b.type_function(float, vec![vec4p])
};
let jit_string = b.string("JIT");
@@ -496,11 +495,11 @@ impl SSATape {
scene_fn_type,
)
.unwrap();
let pos_p = b.function_parameter(vec3p).unwrap();
let pos_p = b.function_parameter(vec4p).unwrap();
b.begin_block(None).unwrap();
let pos = b.load(vec3, None, pos_p, None, []).unwrap();
let pos = b.load(vec4, None, pos_p, None, []).unwrap();
let mut mapping = HashMap::<u32, u32>::new();
@@ -632,6 +631,10 @@ impl SSATape {
instruction.outputs[2],
b.composite_extract(float, None, pos, [2]).unwrap(),
);
mapping.insert(
instruction.outputs[3],
b.composite_extract(float, None, pos, [3]).unwrap(),
);
},
SSAAdd => {
param_two(
@@ -780,7 +783,7 @@ impl SSATape {
b.f_mul(float, None, val_a[0], val_b[1]).unwrap()
} else {
let vector =
[void, vec1, vec2, vec3, vec4][instruction.opcode.size as usize];
[void, float, vec2, vec3, vec4][instruction.opcode.size as usize];
let val_a = b.composite_construct(vector, None, val_a).unwrap();
let val_b = b.composite_construct(vector, None, val_b).unwrap();
b.dot(float, None, val_a, val_b).unwrap()
@@ -797,7 +800,7 @@ impl SSATape {
val_a[0]
} else {
let vector =
[void, vec1, vec2, vec3, vec4][instruction.opcode.size as usize];
[void, float, vec2, vec3, vec4][instruction.opcode.size as usize];
let val_a = b.composite_construct(vector, None, val_a).unwrap();
b.ext_inst(
float,
@@ -825,7 +828,7 @@ impl SSATape {
b.f_sub(float, None, val_b[0], val_a[0]).unwrap()
} else {
let vector =
[void, vec1, vec2, vec3, vec4][instruction.opcode.size as usize];
[void, float, vec2, vec3, vec4][instruction.opcode.size as usize];
let val_a = b.composite_construct(vector, None, val_a).unwrap();
let val_b = b.composite_construct(vector, None, val_b).unwrap();
b.ext_inst(
@@ -855,7 +858,7 @@ impl SSATape {
mapping.insert(instruction.outputs[0], normal);
} else {
let vector =
[void, vec1, vec2, vec3, vec4][instruction.opcode.size as usize];
[void, float, vec2, vec3, vec4][instruction.opcode.size as usize];
let val_a = b.composite_construct(vector, None, val_a).unwrap();
let val_b = b.composite_construct(vector, None, val_b).unwrap();
let normal = b
+5 -5
View File
@@ -10,8 +10,8 @@ layout(depth_greater) out float gl_FragDepth;
layout(location = 0) out uint material;
float scene(vec3 p) {
return length(p) - 1.0;
float scene(vec4 p) {
return length(p.xyz) - 1.0;
}
const float EPSILON = .0001;
@@ -22,11 +22,11 @@ float FARPLANE = length(pc.dimensions / 8.);
vec2 spheretracing(vec3 ori, vec3 dir, out vec3 p) {
vec2 td = vec2(NEARPLANE, 1.);
p = ori;
td.y = scene(p).x * .9;
td.y = scene(vec4(p, camera_uniforms.campos_and_time.w)) * .9;
td.x += td.y;
p = ori + dir * td.x;
for (int i = 0; i < MAX_STEPS && td.y > EPSILON && td.x < FARPLANE; i++) {
td.y = scene(p).x * .9;
td.y = scene(vec4(p, camera_uniforms.campos_and_time.w)) * .9;
td.x += td.y;
p = ori + dir * td.x;
}
@@ -38,7 +38,7 @@ void main() {
vec3 raypos = pos.xyz;
vec3 p;
vec3 raydir = normalize(raypos - (inverse(pc.world) * vec4(camera_uniforms.campos, 1)).xyz);
vec3 raydir = normalize(raypos - (inverse(pc.world) * vec4(camera_uniforms.campos_and_time.xyz, 1)).xyz);
vec2 td = spheretracing(raypos, raydir, p);