add color changing
This commit is contained in:
parent
94432b0c0d
commit
210d5078c6
7 changed files with 129 additions and 54 deletions
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue