add color changing

This commit is contained in:
zack 2024-12-29 12:00:32 -05:00
parent 94432b0c0d
commit 210d5078c6
No known key found for this signature in database
GPG key ID: 5F873416BCF59F35
7 changed files with 129 additions and 54 deletions

View file

@ -1,6 +1,6 @@
#![cfg_attr(target_arch = "spirv", no_std)] #![cfg_attr(target_arch = "spirv", no_std)]
use glam::Mat4; use glam::{Mat4, Vec3};
#[repr(C)] #[repr(C)]
#[derive(Clone)] #[derive(Clone)]
@ -8,4 +8,5 @@ pub struct UniformBufferObject {
pub model: Mat4, pub model: Mat4,
pub view: Mat4, pub view: Mat4,
pub proj: Mat4, pub proj: Mat4,
pub model_color: Vec3,
} }

View file

@ -32,8 +32,13 @@ pub fn main_vs(
} }
#[spirv(fragment)] #[spirv(fragment)]
pub fn main_fs(frag_world_position: Vec3, frag_world_normal: Vec3, out_color: &mut Vec4) { pub fn main_fs(
let base_color = Vec3::new(1.0, 0.5, 0.5); frag_world_position: Vec3,
frag_world_normal: Vec3,
out_color: &mut Vec4,
#[spirv(uniform, descriptor_set = 0, binding = 0)] ubo: &UniformBufferObject,
) {
let base_color = ubo.model_color;
let light_pos = Vec3::new(2.0, 2.0, -2.0); let light_pos = Vec3::new(2.0, 2.0, -2.0);
// Calculate light direction // Calculate light direction

View file

@ -6,6 +6,10 @@ use std::{
use spirv_builder::{MetadataPrintout, SpirvBuilder}; use spirv_builder::{MetadataPrintout, SpirvBuilder};
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
// Tell Cargo to rerun this script if the shaders crate or its contents change
println!("cargo:rerun-if-changed=../shaders/src");
println!("cargo:rerun-if-changed=../shaders/Cargo.toml");
SpirvBuilder::new("../shaders/", "spirv-unknown-vulkan1.2") SpirvBuilder::new("../shaders/", "spirv-unknown-vulkan1.2")
.print_metadata(MetadataPrintout::None) .print_metadata(MetadataPrintout::None)
.multimodule(true) .multimodule(true)

Binary file not shown.

Binary file not shown.

View file

@ -13,6 +13,7 @@ use ash::{
vk::{self, KhrAccelerationStructureFn, KhrDeferredHostOperationsFn, KhrRayTracingPipelineFn}, vk::{self, KhrAccelerationStructureFn, KhrDeferredHostOperationsFn, KhrRayTracingPipelineFn},
Device, Entry, Instance, Device, Entry, Instance,
}; };
use egui::widgets;
use egui_ash::{ use egui_ash::{
raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}, raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle},
winit, App, AppCreator, AshRenderState, CreationContext, HandleRedraw, RunOption, Theme, winit, App, AppCreator, AshRenderState, CreationContext, HandleRedraw, RunOption, Theme,
@ -53,6 +54,9 @@ struct Game {
frame_count_since_last_update: i32, frame_count_since_last_update: i32,
current_fps: f32, current_fps: f32,
bg_color: [f32; 3],
model_color: [f32; 3],
show_profiler: bool, show_profiler: bool,
} }
@ -112,6 +116,12 @@ impl App for Game {
10.0..=150.0, 10.0..=150.0,
)); ));
ui.separator(); ui.separator();
ui.color_edit_button_rgb(&mut self.bg_color);
ui.color_edit_button_rgb(&mut self.model_color);
ui.separator();
if ui.button("Show Profiler").clicked() { if ui.button("Show Profiler").clicked() {
self.show_profiler = !self.show_profiler; self.show_profiler = !self.show_profiler;
} }
@ -220,9 +230,13 @@ impl App for Game {
let camera_yaw = self.camera_yaw; let camera_yaw = self.camera_yaw;
let camera_pitch = self.camera_pitch; let camera_pitch = self.camera_pitch;
let camera_fov = self.camera_fov; let camera_fov = self.camera_fov;
let bg_color = self.bg_color;
let model_color = self.model_color;
move |size, egui_cmd| { move |size, egui_cmd| {
let mut renderer = renderer.inner.lock().unwrap(); let mut renderer = renderer.inner.lock().unwrap();
renderer.update_camera(camera_position, camera_yaw, camera_pitch, camera_fov); renderer.update_camera(camera_position, camera_yaw, camera_pitch, camera_fov);
renderer.update_colors(bg_color.into(), model_color.into());
renderer.render(size.width, size.height, egui_cmd, rotate_y) renderer.render(size.width, size.height, egui_cmd, rotate_y)
} }
})) }))
@ -626,6 +640,8 @@ impl AppCreator<Arc<Mutex<Allocator>>> for MyAppCreator {
camera_pitch: 0., camera_pitch: 0.,
camera_yaw: 0., camera_yaw: 0.,
camera_fov: 45., camera_fov: 45.,
bg_color: Vec3::splat(0.1).into(),
model_color: Vec3::splat(0.8).into(),
last_mouse_pos: None, last_mouse_pos: None,
right_mouse_pressed: false, right_mouse_pressed: false,
last_fps_update: std::time::Instant::now(), last_fps_update: std::time::Instant::now(),

View file

@ -3,6 +3,7 @@ use ash::{
vk::{self, Buffer}, vk::{self, Buffer},
Device, Device,
}; };
use color_eyre::owo_colors::Color;
use egui_ash::EguiCommand; use egui_ash::EguiCommand;
use glam::{Mat4, Vec3}; use glam::{Mat4, Vec3};
use gpu_allocator::vulkan::{Allocation, Allocator}; use gpu_allocator::vulkan::{Allocation, Allocator};
@ -104,6 +105,8 @@ pub struct RendererInner {
camera_fov: f32, camera_fov: f32,
camera_yaw: f32, camera_yaw: f32,
camera_pitch: f32, camera_pitch: f32,
bg_color: Vec3,
model_color: Vec3,
accumulation_reset_needed: bool, accumulation_reset_needed: bool,
} }
@ -199,12 +202,13 @@ impl RendererInner {
(swapchain, surface_format, surface_extent, swapchain_images) (swapchain, surface_format, surface_extent, swapchain_images)
} }
fn create_uniform_buffers( fn create_uniform_buffers<T: Sized>(
device: &Device, device: &Device,
allocator: Arc<Mutex<Allocator>>, allocator: Arc<Mutex<Allocator>>,
swapchain_count: usize, swapchain_count: usize,
) -> (Vec<Buffer>, Vec<Allocation>) { ) -> (Vec<Buffer>, Vec<Allocation>) {
let buffer_size = std::mem::size_of::<UniformBufferObject>() as u64; let buffer_size = std::mem::size_of::<T>() as u64;
let buffer_usage = vk::BufferUsageFlags::UNIFORM_BUFFER; let buffer_usage = vk::BufferUsageFlags::UNIFORM_BUFFER;
let buffer_create_info = vk::BufferCreateInfo::builder() let buffer_create_info = vk::BufferCreateInfo::builder()
.size(buffer_size) .size(buffer_size)
@ -269,7 +273,7 @@ impl RendererInner {
.binding(0) .binding(0)
.descriptor_type(vk::DescriptorType::UNIFORM_BUFFER) .descriptor_type(vk::DescriptorType::UNIFORM_BUFFER)
.descriptor_count(1) .descriptor_count(1)
.stage_flags(vk::ShaderStageFlags::VERTEX); .stage_flags(vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT);
let ubo_layout_create_info = vk::DescriptorSetLayoutCreateInfo::builder() let ubo_layout_create_info = vk::DescriptorSetLayoutCreateInfo::builder()
.bindings(std::slice::from_ref(&ubo_layout_binding)); .bindings(std::slice::from_ref(&ubo_layout_binding));
@ -300,7 +304,8 @@ impl RendererInner {
let buffer_info = vk::DescriptorBufferInfo::builder() let buffer_info = vk::DescriptorBufferInfo::builder()
.buffer(uniform_buffers[index]) .buffer(uniform_buffers[index])
.offset(0) .offset(0)
.range(vk::WHOLE_SIZE); .range(vk::WHOLE_SIZE)
.build();
let descriptor_write = vk::WriteDescriptorSet::builder() let descriptor_write = vk::WriteDescriptorSet::builder()
.dst_set(descriptor_sets[index]) .dst_set(descriptor_sets[index])
.dst_binding(0) .dst_binding(0)
@ -535,8 +540,8 @@ impl RendererInner {
.depth_clamp_enable(false) .depth_clamp_enable(false)
.rasterizer_discard_enable(false) .rasterizer_discard_enable(false)
.polygon_mode(vk::PolygonMode::FILL) .polygon_mode(vk::PolygonMode::FILL)
.cull_mode(vk::CullModeFlags::NONE) .cull_mode(vk::CullModeFlags::BACK)
.front_face(vk::FrontFace::COUNTER_CLOCKWISE) .front_face(vk::FrontFace::CLOCKWISE)
.depth_bias_enable(false) .depth_bias_enable(false)
.line_width(1.0); .line_width(1.0);
let stencil_op = vk::StencilOpState::builder() let stencil_op = vk::StencilOpState::builder()
@ -546,7 +551,7 @@ impl RendererInner {
let depth_stencil_info = vk::PipelineDepthStencilStateCreateInfo::builder() let depth_stencil_info = vk::PipelineDepthStencilStateCreateInfo::builder()
.depth_test_enable(true) .depth_test_enable(true)
.depth_write_enable(true) .depth_write_enable(true)
.depth_compare_op(vk::CompareOp::LESS_OR_EQUAL) .depth_compare_op(vk::CompareOp::LESS)
.depth_bounds_test_enable(false) .depth_bounds_test_enable(false)
.stencil_test_enable(false) .stencil_test_enable(false)
.front(*stencil_op) .front(*stencil_op)
@ -792,36 +797,32 @@ impl RendererInner {
swapchain_count: usize, swapchain_count: usize,
) -> (Vec<vk::Fence>, Vec<vk::Semaphore>, Vec<vk::Semaphore>) { ) -> (Vec<vk::Fence>, Vec<vk::Semaphore>, Vec<vk::Semaphore>) {
let fence_create_info = let fence_create_info =
vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED); vk::FenceCreateInfo::builder().flags(vk::FenceCreateFlags::SIGNALED); // Start signaled
let mut in_flight_fences = vec![];
let semaphore_create_info = vk::SemaphoreCreateInfo::builder();
let mut in_flight_fences = Vec::with_capacity(swapchain_count);
let mut image_available_semaphores = Vec::with_capacity(swapchain_count);
let mut render_finished_semaphores = Vec::with_capacity(swapchain_count);
for _ in 0..swapchain_count { for _ in 0..swapchain_count {
let fence = unsafe { unsafe {
device let fence = device
.create_fence(&fence_create_info, None) .create_fence(&fence_create_info, None)
.expect("Failed to create fence") .expect("Failed to create fence");
}; let image_available = device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create semaphore");
let render_finished = device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create semaphore");
in_flight_fences.push(fence); in_flight_fences.push(fence);
image_available_semaphores.push(image_available);
render_finished_semaphores.push(render_finished);
} }
let mut image_available_semaphores = vec![];
for _ in 0..swapchain_count {
let semaphore_create_info = vk::SemaphoreCreateInfo::builder();
let semaphore = unsafe {
device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create semaphore")
};
image_available_semaphores.push(semaphore);
}
let mut render_finished_semaphores = vec![];
for _ in 0..swapchain_count {
let semaphore_create_info = vk::SemaphoreCreateInfo::builder();
let semaphore = unsafe {
device
.create_semaphore(&semaphore_create_info, None)
.expect("Failed to create semaphore")
};
render_finished_semaphores.push(semaphore);
} }
( (
in_flight_fences, in_flight_fences,
image_available_semaphores, image_available_semaphores,
@ -1004,7 +1005,12 @@ impl RendererInner {
height, height,
); );
let (uniform_buffers, uniform_buffer_allocations) = let (uniform_buffers, uniform_buffer_allocations) =
Self::create_uniform_buffers(&device, allocator.clone(), swapchain_images.len()); Self::create_uniform_buffers::<UniformBufferObject>(
&device,
allocator.clone(),
swapchain_images.len(),
);
let descriptor_pool = Self::create_descriptor_pool(&device, swapchain_images.len()); let descriptor_pool = Self::create_descriptor_pool(&device, swapchain_images.len());
let descriptor_set_layouts = let descriptor_set_layouts =
Self::create_descriptor_set_layouts(&device, swapchain_images.len()); Self::create_descriptor_set_layouts(&device, swapchain_images.len());
@ -1083,10 +1089,27 @@ impl RendererInner {
camera_yaw: 0., camera_yaw: 0.,
camera_pitch: 0., camera_pitch: 0.,
camera_fov: 45., camera_fov: 45.,
bg_color: Vec3::splat(0.1),
model_color: Vec3::splat(0.8),
accumulation_reset_needed: true, accumulation_reset_needed: true,
} }
} }
pub fn update_colors(&mut self, bg_color: Vec3, model_color: Vec3) {
let bg_color = clamped_color(bg_color);
let model_color = clamped_color(model_color);
if bg_color != self.bg_color {
self.bg_color = bg_color;
self.accumulation_reset_needed = true;
}
if model_color != self.model_color {
self.model_color = model_color;
self.accumulation_reset_needed = true;
}
}
pub fn update_camera(&mut self, new_position: Vec3, yaw: f32, pitch: f32, fov: f32) { pub fn update_camera(&mut self, new_position: Vec3, yaw: f32, pitch: f32, fov: f32) {
if (new_position - self.camera_position).length() > 0.0001 if (new_position - self.camera_position).length() > 0.0001
|| (yaw - self.camera_yaw).abs() > 0.001 || (yaw - self.camera_yaw).abs() > 0.001
@ -1121,23 +1144,21 @@ impl RendererInner {
self.recreate_swapchain(width, height, &mut egui_cmd); self.recreate_swapchain(width, height, &mut egui_cmd);
} }
let result = unsafe { // unsafe {
puffin::profile_scope!("acquire_next_image"); // self.device
self.swapchain_loader.acquire_next_image( // .wait_for_fences(
self.swapchain, // std::slice::from_ref(&self.in_flight_fences[self.current_frame]),
u64::MAX, // true,
self.image_available_semaphores[self.current_frame], // u64::MAX,
vk::Fence::null(), // )
) // .expect("failed to wait for fences");
}; //
let index = match result { // self.device
Ok((index, _)) => index as usize, // .reset_fences(std::slice::from_ref(
Err(vk::Result::ERROR_OUT_OF_DATE_KHR) => { // &self.in_flight_fences[self.current_frame],
self.dirty_swapchain = true; // ))
return; // .expect("failed to reset fences");
} // }
Err(_) => return,
};
unsafe { unsafe {
puffin::profile_scope!("wait_for_fences"); puffin::profile_scope!("wait_for_fences");
@ -1156,6 +1177,24 @@ impl RendererInner {
} }
.expect("Failed to reset fences"); .expect("Failed to reset fences");
let result = unsafe {
puffin::profile_scope!("acquire_next_image");
self.swapchain_loader.acquire_next_image(
self.swapchain,
u64::MAX,
self.image_available_semaphores[self.current_frame],
vk::Fence::null(),
)
};
let index = match result {
Ok((index, _)) => index as usize,
Err(vk::Result::ERROR_OUT_OF_DATE_KHR) => {
self.dirty_swapchain = true;
return;
}
Err(_) => return,
};
let view = { let view = {
puffin::profile_scope!("calculate_view"); puffin::profile_scope!("calculate_view");
let (sin_pitch, cos_pitch) = self.camera_pitch.sin_cos(); let (sin_pitch, cos_pitch) = self.camera_pitch.sin_cos();
@ -1180,6 +1219,7 @@ impl RendererInner {
0.1, 0.1,
10.0, 10.0,
), ),
model_color: self.model_color,
}; };
unsafe { unsafe {
@ -1215,7 +1255,7 @@ impl RendererInner {
.clear_values(&[ .clear_values(&[
vk::ClearValue { vk::ClearValue {
color: vk::ClearColorValue { color: vk::ClearColorValue {
float32: [0.4, 0.3, 0.2, 1.0], float32: [self.bg_color.x, self.bg_color.y, self.bg_color.z, 1.0],
}, },
}, },
vk::ClearValue { vk::ClearValue {
@ -1388,6 +1428,7 @@ impl RendererInner {
for allocation in self.uniform_buffer_allocations.drain(..) { for allocation in self.uniform_buffer_allocations.drain(..) {
allocator.free(allocation).expect("Failed to free memory"); allocator.free(allocation).expect("Failed to free memory");
} }
self.swapchain_loader self.swapchain_loader
.destroy_swapchain(self.swapchain, None); .destroy_swapchain(self.swapchain, None);
} }
@ -1436,3 +1477,11 @@ impl Renderer {
self.inner.lock().unwrap().destroy(); self.inner.lock().unwrap().destroy();
} }
} }
fn clamped_color(color: Vec3) -> Vec3 {
Vec3::new(
color.x.clamp(0.0, 1.0),
color.y.clamp(0.0, 1.0),
color.z.clamp(0.0, 1.0),
)
}