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)]
use glam::Mat4;
use glam::{Mat4, Vec3};
#[repr(C)]
#[derive(Clone)]
@ -8,4 +8,5 @@ pub struct UniformBufferObject {
pub model: Mat4,
pub view: Mat4,
pub proj: Mat4,
pub model_color: Vec3,
}

View file

@ -32,8 +32,13 @@ pub fn main_vs(
}
#[spirv(fragment)]
pub fn main_fs(frag_world_position: Vec3, frag_world_normal: Vec3, out_color: &mut Vec4) {
let base_color = Vec3::new(1.0, 0.5, 0.5);
pub fn main_fs(
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);
// Calculate light direction

View file

@ -6,6 +6,10 @@ use std::{
use spirv_builder::{MetadataPrintout, SpirvBuilder};
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")
.print_metadata(MetadataPrintout::None)
.multimodule(true)

Binary file not shown.

Binary file not shown.

View file

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

View file

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