added vertex buffer
This commit is contained in:
parent
dce8b57b0e
commit
d26de46d92
|
@ -0,0 +1,2 @@
|
||||||
|
# Blender 3.5.0 MTL File: 'None'
|
||||||
|
# www.blender.org
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Blender 3.5.0
|
||||||
|
# www.blender.org
|
||||||
|
mtllib cube.mtl
|
||||||
|
o Cube
|
||||||
|
v -1.000000 -1.000000 1.000000
|
||||||
|
v -1.000000 1.000000 1.000000
|
||||||
|
v -1.000000 -1.000000 -1.000000
|
||||||
|
v -1.000000 1.000000 -1.000000
|
||||||
|
v 1.000000 -1.000000 1.000000
|
||||||
|
v 1.000000 1.000000 1.000000
|
||||||
|
v 1.000000 -1.000000 -1.000000
|
||||||
|
v 1.000000 1.000000 -1.000000
|
||||||
|
s 0
|
||||||
|
f 2 3 1
|
||||||
|
f 4 7 3
|
||||||
|
f 8 5 7
|
||||||
|
f 6 1 5
|
||||||
|
f 7 1 3
|
||||||
|
f 4 6 8
|
||||||
|
f 2 4 3
|
||||||
|
f 4 8 7
|
||||||
|
f 8 6 5
|
||||||
|
f 6 2 1
|
||||||
|
f 7 5 1
|
||||||
|
f 4 2 6
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Blender 3.5.0 MTL File: 'None'
|
||||||
|
# www.blender.org
|
File diff suppressed because it is too large
Load Diff
|
@ -3,21 +3,21 @@ use cgmath::prelude::*;
|
||||||
use cgmath::{Rad, Vector2, Vector3};
|
use cgmath::{Rad, Vector2, Vector3};
|
||||||
|
|
||||||
pub struct Camera {
|
pub struct Camera {
|
||||||
front: Vector3<f32>,
|
pub(crate) front: Vector3<f32>,
|
||||||
left: Vector3<f32>,
|
pub(crate) left: Vector3<f32>,
|
||||||
up: Vector3<f32>,
|
pub(crate) up: Vector3<f32>,
|
||||||
pos: Vector3<f32>,
|
pub(crate) pos: Vector3<f32>,
|
||||||
fov: f32,
|
pub(crate) fov: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
front: Vector3::new(0.0, 0.0, 1.0),
|
front: Vector3::new(0.0, 0.0, -1.0),
|
||||||
left: Vector3::new(1.0, 0.0, 0.0),
|
left: Vector3::new(1.0, 0.0, 0.0),
|
||||||
up: Vector3::new(0.0, 1.0, 0.0),
|
up: Vector3::new(0.0, -1.0, 0.0),
|
||||||
pos: Vector3::new(0.0, 0.0, -4.0),
|
pos: Vector3::new(0.0, 0.0, 9.0),
|
||||||
fov: 90.0f32
|
fov: 90.0f32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ use vulkano::memory::allocator::{AllocationCreateInfo, MemoryUsage, StandardMemo
|
||||||
use vulkano::padded::Padded;
|
use vulkano::padded::Padded;
|
||||||
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
|
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
|
||||||
use vulkano::sync::GpuFuture;
|
use vulkano::sync::GpuFuture;
|
||||||
|
use crate::shader::pathtracing::camera::Camera;
|
||||||
use crate::vulkan::Renderer;
|
use crate::vulkan::Renderer;
|
||||||
|
|
||||||
pub(crate) mod cs {
|
pub(crate) mod cs {
|
||||||
|
@ -36,8 +37,9 @@ pub struct PathtracerPipeline {
|
||||||
raw_image: Subbuffer<[[f32; 4]]>,
|
raw_image: Subbuffer<[[f32; 4]]>,
|
||||||
seconds: Instant,
|
seconds: Instant,
|
||||||
uniform_buffer: Arc<SubbufferAllocator>,
|
uniform_buffer: Arc<SubbufferAllocator>,
|
||||||
vertex_buffer: Subbuffer<[[f32; 3]]>,
|
vertex_buffer: Subbuffer<[[f32; 4]]>,
|
||||||
index_buffer: Subbuffer<[u32]>,
|
index_buffer: Subbuffer<[u32]>,
|
||||||
|
camera: Camera
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathtracerPipeline {
|
impl PathtracerPipeline {
|
||||||
|
@ -79,7 +81,8 @@ impl PathtracerPipeline {
|
||||||
uniform_buffer: Arc::new(uniform_buffer),
|
uniform_buffer: Arc::new(uniform_buffer),
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
index_buffer,
|
index_buffer,
|
||||||
seconds: Instant::now()
|
seconds: Instant::now(),
|
||||||
|
camera: Camera::new()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,13 +121,13 @@ impl PathtracerPipeline {
|
||||||
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer,Arc<StandardCommandBufferAllocator>>
|
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer,Arc<StandardCommandBufferAllocator>>
|
||||||
) {
|
) {
|
||||||
let camera = cs::Camera {
|
let camera = cs::Camera {
|
||||||
front: Padded::from([0f32, 0f32, 1f32]),
|
front: Padded::from(Into::<[f32; 3]>::into(self.camera.front)),
|
||||||
left: Padded::from([1f32, 0f32, 0f32]),
|
left: Padded::from(Into::<[f32; 3]>::into(self.camera.left)),
|
||||||
up: Padded::from([0f32, 1f32, 0f32]),
|
up: Padded::from(Into::<[f32; 3]>::into(self.camera.up)),
|
||||||
|
|
||||||
position: [0f32, 0f32, -12f32],
|
position: Into::<[f32; 3]>::into(self.camera.pos),
|
||||||
|
|
||||||
fov: 90f32
|
fov: self.camera.fov,
|
||||||
};
|
};
|
||||||
|
|
||||||
let subbuffer = self.uniform_buffer.allocate_sized().unwrap();
|
let subbuffer = self.uniform_buffer.allocate_sized().unwrap();
|
||||||
|
@ -188,35 +191,33 @@ fn create_image(memory_allocator: &StandardMemoryAllocator, queue: &Arc<Queue>,
|
||||||
(raw_image, image)
|
(raw_image, image)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_example_scene() -> (Vec<[f32; 3]>, Vec<u32>) {
|
fn load_example_scene() -> (Vec<[f32; 4]>, Vec<u32>) {
|
||||||
let (mut models, materials) = tobj::load_obj("res/example-scene.obj", &tobj::GPU_LOAD_OPTIONS).expect("unable to load scene from obj");
|
let (mut models, materials) = tobj::load_obj("res/example-scene.obj", &tobj::GPU_LOAD_OPTIONS).expect("unable to load scene from obj");
|
||||||
|
|
||||||
let mut vertices:Vec<[f32; 3]> = Vec::new();
|
let mut vertices:Vec<[f32; 4]> = vec![];
|
||||||
let mut indices:Vec<u32> = Vec::new();
|
let mut indices:Vec<u32> = vec![];
|
||||||
|
|
||||||
for model in models.iter_mut() {
|
for model in models.iter_mut() {
|
||||||
let num_triangles = model.mesh.positions.len() / 3;
|
let offset = vertices.len() as u32;
|
||||||
|
|
||||||
for triangle_index in 0..num_triangles {
|
for vertex_index in (0..model.mesh.positions.len()).step_by(3) {
|
||||||
let vertex_index = triangle_index * 3;
|
|
||||||
vertices.push([
|
vertices.push([
|
||||||
model.mesh.positions[vertex_index],
|
model.mesh.positions[vertex_index],
|
||||||
model.mesh.positions[vertex_index + 1],
|
model.mesh.positions[vertex_index + 1],
|
||||||
model.mesh.positions[vertex_index + 2]
|
model.mesh.positions[vertex_index + 2],
|
||||||
|
0.0
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for index in model.mesh.indices.iter() {
|
for index in model.mesh.indices.iter() {
|
||||||
indices.push(*index);
|
indices.push(*index + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// model.mesh.indices.iter_mut().for_each(|i| indices.push(*i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(vertices, indices)
|
(vertices, indices)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_gpu_buffer(vertices: &Vec<[f32; 3]>, indices: &Vec<u32>, memory_allocator: &StandardMemoryAllocator) -> (Subbuffer<[[f32; 3]]>, Subbuffer<[u32]>) {
|
fn create_gpu_buffer(vertices: &Vec<[f32; 4]>, indices: &Vec<u32>, memory_allocator: &StandardMemoryAllocator) -> (Subbuffer<[[f32; 4]]>, Subbuffer<[u32]>) {
|
||||||
let vertex_buffer = Buffer::from_iter(
|
let vertex_buffer = Buffer::from_iter(
|
||||||
memory_allocator,
|
memory_allocator,
|
||||||
BufferCreateInfo {
|
BufferCreateInfo {
|
||||||
|
|
|
@ -25,6 +25,45 @@ uint get_pixel_index() {
|
||||||
return gl_GlobalInvocationID.y * uint(program_metadata.resolution.x) + gl_GlobalInvocationID.x;
|
return gl_GlobalInvocationID.y * uint(program_metadata.resolution.x) + gl_GlobalInvocationID.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 project(in vec3 a, in vec3 b) {
|
||||||
|
return a * (dot(a, b) / dot(a, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct_orthonormal_basis(in vec3 up, out vec3 u, out vec3 v, out vec3 w) {
|
||||||
|
u = normalize(up);
|
||||||
|
|
||||||
|
vec3 n2 = vec3(1) - u;
|
||||||
|
vec3 n3 = vec3(1) - u.zxy;
|
||||||
|
|
||||||
|
vec3 w2 = normalize(n2 - (project(u, n2)));
|
||||||
|
vec3 w3 = normalize(n3 - project(u, n3) - project(w2, n3));
|
||||||
|
|
||||||
|
v = w2;
|
||||||
|
w = w3;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 cosine_weighted_hemisphere() {
|
||||||
|
float u1 = random();
|
||||||
|
float u2 = random();
|
||||||
|
|
||||||
|
float r = sqrt(u1);
|
||||||
|
float theta = 2 * 3.1415926535 * u2;
|
||||||
|
|
||||||
|
float x = r * cos(theta);
|
||||||
|
float y = r * sin(theta);
|
||||||
|
|
||||||
|
return vec3(x, y, sqrt(1.0 - u1));
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 generate_diffuse_ray_direction(in vec3 nor) {
|
||||||
|
vec3 hemisphere = cosine_weighted_hemisphere();
|
||||||
|
|
||||||
|
vec3 u, v, w;
|
||||||
|
construct_orthonormal_basis(nor, u, v, w);
|
||||||
|
|
||||||
|
return normalize(u * hemisphere.x + v * hemisphere.y + w * hemisphere.z);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
init_random_state(floatBitsToInt(program_metadata.seconds));
|
init_random_state(floatBitsToInt(program_metadata.seconds));
|
||||||
|
|
||||||
|
@ -34,10 +73,20 @@ void main() {
|
||||||
|
|
||||||
vec3 color = vec3(0);
|
vec3 color = vec3(0);
|
||||||
|
|
||||||
vec4 result = intersect_scene(camera_ray);
|
Hit result = intersect_scene(camera_ray);
|
||||||
|
|
||||||
if (result.a == 1.0) {
|
if (result.depth < camera_ray.far) {
|
||||||
color = vec3(result.y, result.z, 0);
|
Ray ao;
|
||||||
|
ao.origin = camera_ray.origin + camera_ray.direction * result.depth;
|
||||||
|
ao.direction = generate_diffuse_ray_direction(result.nor);
|
||||||
|
ao.near = 1e-3;
|
||||||
|
ao.far = 1e3;
|
||||||
|
|
||||||
|
Hit r2 = intersect_scene(ao);
|
||||||
|
|
||||||
|
if (r2.depth > 1.0) {
|
||||||
|
color = vec3(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// index of the current pixel as array index
|
// index of the current pixel as array index
|
||||||
|
|
|
@ -7,42 +7,54 @@ struct Ray {
|
||||||
float far;
|
float far;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Hit {
|
||||||
|
vec3 nor;
|
||||||
|
vec2 uv;
|
||||||
|
float depth;
|
||||||
|
};
|
||||||
|
|
||||||
layout(set = 0, binding = 3) buffer VertexBuffer {
|
layout(set = 0, binding = 3) buffer VertexBuffer {
|
||||||
vec3 vertices[];
|
vec4 vertices[];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 0, binding = 4) buffer IndexBuffer {
|
layout(set = 0, binding = 4) buffer IndexBuffer {
|
||||||
uint indices[];
|
uint indices[];
|
||||||
};
|
};
|
||||||
|
|
||||||
vec3 intersect_triangle(in Ray ray, in vec3 v0, in vec3 v1, in vec3 v2) {
|
vec3 intersect_triangle(in Ray ray, in vec3 v0, in vec3 v1, in vec3 v2, out vec3 n) {
|
||||||
vec3 v1v0 = v1 - v0;
|
vec3 v1v0 = v1 - v0;
|
||||||
vec3 v2v0 = v2 - v0;
|
vec3 v2v0 = v2 - v0;
|
||||||
vec3 rov0 = ray.origin - v0;
|
vec3 rov0 = ray.origin - v0;
|
||||||
vec3 n = cross(v1v0, v2v0);
|
n = cross(v1v0, v2v0);
|
||||||
|
|
||||||
vec3 q = cross(rov0, ray.direction);
|
vec3 q = cross(rov0, ray.direction);
|
||||||
float d = 1.0 / dot(ray.direction, n);
|
float d = 1.0 / dot(ray.direction, n);
|
||||||
float u = d * dot( -q, v2v0);
|
float u = d * dot( -q, v2v0);
|
||||||
float v = d * dot( q, v1v0);
|
float v = d * dot( q, v1v0);
|
||||||
float t = d * dot( -n, rov0);
|
float t = d * dot( -n, rov0);
|
||||||
|
|
||||||
t = min(u, min(v, min(1.0 - (u + v), t)));
|
if(u < 0.0 || v < 0.0 || (u+v) > 1.0 || d > 0.0)
|
||||||
|
t = -1.0;
|
||||||
|
|
||||||
return vec3( t, u, v );
|
return vec3(t, u, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 intersect_scene(in Ray ray) {
|
Hit intersect_scene(in Ray ray) {
|
||||||
vec4 hit = vec4(ray.far, -1, -1, 0);
|
Hit hit;
|
||||||
|
hit.depth = ray.far;
|
||||||
|
|
||||||
for (int i = 0; i < indices.length(); i += 3) {
|
for (int i = 0; i < indices.length(); i += 3) {
|
||||||
vec3 v0 = vertices[indices[i]];
|
vec3 v0 = vertices[indices[i]].xyz;
|
||||||
vec3 v1 = vertices[indices[i + 1]];
|
vec3 v1 = vertices[indices[i + 1]].xyz;
|
||||||
vec3 v2 = vertices[indices[i + 2]];
|
vec3 v2 = vertices[indices[i + 2]].xyz;
|
||||||
|
|
||||||
vec3 result = intersect_triangle(ray, v0, v1, v2);
|
vec3 n;
|
||||||
|
vec3 result = intersect_triangle(ray, v0, v1, v2, n);
|
||||||
|
|
||||||
if (result.x > ray.near && result.x < hit.x) {
|
if (result.x > ray.near && result.x < hit.depth) {
|
||||||
hit = vec4(result, 1);
|
hit.uv = result.yz;
|
||||||
|
hit.depth = result.x;
|
||||||
|
hit.nor = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ mod device;
|
||||||
pub(crate) mod textured_quad;
|
pub(crate) mod textured_quad;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::Instant;
|
||||||
use vulkano::device::{Device};
|
use vulkano::device::{Device};
|
||||||
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
|
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
|
||||||
use vulkano::instance::{Instance, InstanceCreateInfo};
|
use vulkano::instance::{Instance, InstanceCreateInfo};
|
||||||
|
@ -17,7 +18,7 @@ use vulkano::image::view::ImageView;
|
||||||
use vulkano::pipeline::graphics::viewport::Viewport;
|
use vulkano::pipeline::graphics::viewport::Viewport;
|
||||||
use vulkano::render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass};
|
use vulkano::render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass};
|
||||||
use vulkano::sync::{FlushError, GpuFuture};
|
use vulkano::sync::{FlushError, GpuFuture};
|
||||||
use winit::event::{Event, WindowEvent};
|
use winit::event::{Event, VirtualKeyCode, WindowEvent};
|
||||||
use crate::shader::composite::TextureDrawPipeline;
|
use crate::shader::composite::TextureDrawPipeline;
|
||||||
use crate::shader::pathtracing::PathtracerPipeline;
|
use crate::shader::pathtracing::PathtracerPipeline;
|
||||||
|
|
||||||
|
@ -133,6 +134,8 @@ pub fn init() {
|
||||||
|
|
||||||
let mut now_keys = [false; 255];
|
let mut now_keys = [false; 255];
|
||||||
|
|
||||||
|
let mut start_frame = Instant::now();
|
||||||
|
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
@ -172,6 +175,8 @@ pub fn init() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
|
let elapsed = (Instant::now() - start_frame).as_secs_f32();
|
||||||
|
|
||||||
// Do not draw the frame when the screen dimensions are zero. On Windows, this can
|
// Do not draw the frame when the screen dimensions are zero. On Windows, this can
|
||||||
// occur when minimizing the application.
|
// occur when minimizing the application.
|
||||||
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
|
let window = surface.object().unwrap().downcast_ref::<Window>().unwrap();
|
||||||
|
@ -280,6 +285,8 @@ pub fn init() {
|
||||||
// previous_frame_end = Some(sync::now(device.clone()).boxed());
|
// previous_frame_end = Some(sync::now(device.clone()).boxed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
start_frame = Instant::now();
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue