put global light into storage buffer
This commit is contained in:
@@ -41,7 +41,7 @@ pub fn init_world(world: &mut World) {
|
||||
orientation: Rotation3::identity(),
|
||||
grid: VoxelGrid::new(Array3::from_shape_fn(dim, |(x, y, z)| {
|
||||
if y == 0 {
|
||||
rand::random()
|
||||
VoxelColor::random()
|
||||
} else if (y == dim.1 - 1) && (x == 0 || x == dim.0 - 1 || z == 0 || z == dim.2 - 1) {
|
||||
VoxelColor {
|
||||
r: 255,
|
||||
|
||||
@@ -44,7 +44,6 @@ impl Client {
|
||||
|
||||
init_world(&mut world);
|
||||
let state = ClientState::new();
|
||||
// render_channel.send(RenderMessage::ViewUpdate(state.camera)).expect("GRRRR");
|
||||
|
||||
Self {
|
||||
window,
|
||||
@@ -70,6 +69,8 @@ impl Client {
|
||||
|
||||
if self.exit {
|
||||
self.renderer.send(RenderMessage::Exit).expect("AAAA");
|
||||
// you know I'd like to do a timeout here...
|
||||
// only because I have an NVIDIA GPU HELP
|
||||
self.render_handle
|
||||
.take()
|
||||
.expect("uh oh")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::marker::PhantomData;
|
||||
use wgpu::{BufferAddress, BufferUsages};
|
||||
use wgpu::{util::DeviceExt, BufferAddress, BufferUsages};
|
||||
|
||||
pub struct ArrBuf<T: bytemuck::Pod> {
|
||||
len: usize,
|
||||
@@ -74,6 +74,18 @@ impl<T: bytemuck::Pod> ArrBuf<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_with(device: &wgpu::Device, label: &str, usage: BufferUsages, data: &[T]) -> Self {
|
||||
let label = &(label.to_owned() + " Buffer");
|
||||
Self {
|
||||
len: data.len(),
|
||||
buffer: Self::init_buf_with(device, label, usage, data),
|
||||
label: label.to_string(),
|
||||
typ: PhantomData,
|
||||
usage,
|
||||
moves: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn init_buf(
|
||||
device: &wgpu::Device,
|
||||
label: &str,
|
||||
@@ -91,6 +103,19 @@ impl<T: bytemuck::Pod> ArrBuf<T> {
|
||||
})
|
||||
}
|
||||
|
||||
fn init_buf_with(
|
||||
device: &wgpu::Device,
|
||||
label: &str,
|
||||
usage: BufferUsages,
|
||||
data: &[T],
|
||||
) -> wgpu::Buffer {
|
||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some(label),
|
||||
usage: usage | BufferUsages::COPY_DST | BufferUsages::COPY_SRC,
|
||||
contents: bytemuck::cast_slice(data),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn buffer(&self) -> &wgpu::Buffer {
|
||||
&self.buffer
|
||||
}
|
||||
|
||||
@@ -17,6 +17,17 @@ impl<T: PartialEq + bytemuck::Pod> Storage<T> {
|
||||
binding,
|
||||
}
|
||||
}
|
||||
pub fn init_with(device: &wgpu::Device, label: &str, binding: u32, data: &[T]) -> Self {
|
||||
Self {
|
||||
buf: ArrBuf::init_with(
|
||||
device,
|
||||
&(label.to_owned() + " Storage"),
|
||||
BufferUsages::STORAGE,
|
||||
data
|
||||
),
|
||||
binding,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PartialEq + bytemuck::Pod> Storage<T> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use rand::distributions::{Distribution, Standard};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Zeroable, bytemuck::Pod)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||
pub struct VoxelColor {
|
||||
pub r: u8,
|
||||
pub g: u8,
|
||||
@@ -9,6 +9,8 @@ pub struct VoxelColor {
|
||||
pub a: u8,
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for VoxelColor {}
|
||||
|
||||
impl VoxelColor {
|
||||
pub fn none() -> Self {
|
||||
Self {
|
||||
@@ -34,6 +36,9 @@ impl VoxelColor {
|
||||
a: 255,
|
||||
}
|
||||
}
|
||||
pub fn random() -> Self {
|
||||
rand::random()
|
||||
}
|
||||
}
|
||||
|
||||
impl Distribution<VoxelColor> for Standard {
|
||||
|
||||
9
src/client/render/voxel/light.rs
Normal file
9
src/client/render/voxel/light.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
use nalgebra::Vector3;
|
||||
|
||||
#[repr(C, align(16))]
|
||||
#[derive(Clone, Copy, PartialEq, bytemuck::Zeroable)]
|
||||
pub struct GlobalLight {
|
||||
pub direction: Vector3<f32>,
|
||||
}
|
||||
|
||||
unsafe impl bytemuck::Pod for GlobalLight {}
|
||||
@@ -1,13 +1,14 @@
|
||||
mod grid;
|
||||
mod view;
|
||||
mod color;
|
||||
mod grid;
|
||||
mod group;
|
||||
mod light;
|
||||
mod view;
|
||||
|
||||
pub use color::*;
|
||||
|
||||
use nalgebra::{Projective3, Transform3, Translation3, Vector2};
|
||||
use light::GlobalLight;
|
||||
use nalgebra::{Projective3, Transform3, Translation3, Vector2, Vector3};
|
||||
|
||||
use {group::VoxelGroup, view::View};
|
||||
use crate::client::{
|
||||
camera::Camera,
|
||||
render::{
|
||||
@@ -15,6 +16,7 @@ use crate::client::{
|
||||
CreateVoxelGrid,
|
||||
},
|
||||
};
|
||||
use {group::VoxelGroup, view::View};
|
||||
|
||||
pub struct VoxelPipeline {
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
@@ -23,6 +25,7 @@ pub struct VoxelPipeline {
|
||||
bind_group: wgpu::BindGroup,
|
||||
voxel_groups: Storage<VoxelGroup>,
|
||||
voxels: Storage<VoxelColor>,
|
||||
global_lights: Storage<GlobalLight>,
|
||||
}
|
||||
|
||||
impl VoxelPipeline {
|
||||
@@ -33,9 +36,17 @@ impl VoxelPipeline {
|
||||
source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
|
||||
});
|
||||
|
||||
let view = Uniform::<View>::init(device, "view", 0);
|
||||
let view = Uniform::init(device, "view", 0);
|
||||
let voxels = Storage::init(device, "voxels", 1);
|
||||
let voxel_groups = Storage::init(device, "voxel groups", 2);
|
||||
let global_lights = Storage::init_with(
|
||||
device,
|
||||
"global lights",
|
||||
3,
|
||||
&[GlobalLight {
|
||||
direction: Vector3::new(-0.5, -4.0, 2.0).normalize(),
|
||||
}],
|
||||
);
|
||||
|
||||
// bind groups
|
||||
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
@@ -43,6 +54,7 @@ impl VoxelPipeline {
|
||||
view.bind_group_layout_entry(),
|
||||
voxels.bind_group_layout_entry(),
|
||||
voxel_groups.bind_group_layout_entry(),
|
||||
global_lights.bind_group_layout_entry(),
|
||||
],
|
||||
label: Some("tile_bind_group_layout"),
|
||||
});
|
||||
@@ -53,6 +65,7 @@ impl VoxelPipeline {
|
||||
view.bind_group_entry(),
|
||||
voxels.bind_group_entry(),
|
||||
voxel_groups.bind_group_entry(),
|
||||
global_lights.bind_group_entry(),
|
||||
],
|
||||
label: Some("tile_bind_group"),
|
||||
});
|
||||
@@ -109,6 +122,7 @@ impl VoxelPipeline {
|
||||
bind_group_layout,
|
||||
voxels,
|
||||
voxel_groups,
|
||||
global_lights,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +170,7 @@ impl VoxelPipeline {
|
||||
self.view.bind_group_entry(),
|
||||
self.voxels.bind_group_entry(),
|
||||
self.voxel_groups.bind_group_entry(),
|
||||
self.global_lights.bind_group_entry(),
|
||||
],
|
||||
label: Some("tile_bind_group"),
|
||||
});
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
// Vertex shader
|
||||
|
||||
struct GlobalLight {
|
||||
dir: vec3<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) tex_coords: vec2<f32>,
|
||||
@@ -26,6 +30,8 @@ var<uniform> view: View;
|
||||
var<storage, read> voxels: array<u32>;
|
||||
@group(0) @binding(2)
|
||||
var<storage, read> voxel_groups: array<VoxelGroup>;
|
||||
@group(0) @binding(3)
|
||||
var<storage, read> global_lights: array<GlobalLight>;
|
||||
|
||||
@vertex
|
||||
fn vs_main(
|
||||
@@ -62,7 +68,7 @@ fn fs_main(
|
||||
let dir = view.transform * vec4<f32>(normalize(pixel_pos), 0.0);
|
||||
|
||||
var color = trace_full(pos, dir);
|
||||
let light_mult = clamp((-dot(dir.xyz, normalize(GLOBAL_LIGHT)) - 0.99) * 200.0, 0.0, 1.0);
|
||||
let light_mult = clamp((-dot(dir.xyz, global_lights[0].dir) - 0.99) * 200.0, 0.0, 1.0);
|
||||
let sky_color = light_mult * vec3<f32>(1.0, 1.0, 1.0);
|
||||
color += vec4<f32>(sky_color * (1.0 - color.a), 1.0 - color.a);
|
||||
color.a = 1.0;
|
||||
@@ -73,7 +79,6 @@ const ZERO3F = vec3<f32>(0.0);
|
||||
const ZERO2F = vec2<f32>(0.0);
|
||||
const DEPTH = 16u;
|
||||
const FULL_ALPHA = 0.9999;
|
||||
const GLOBAL_LIGHT = vec3<f32>(-0.5, -4.0, 2.0);
|
||||
|
||||
fn trace_full(pos: vec4<f32>, dir: vec4<f32>) -> vec4<f32> {
|
||||
// GPUs hate this
|
||||
@@ -124,7 +129,6 @@ fn apply_group(
|
||||
(group.transform * vec4<f32>(0.0, 0.0, dir_if.z, 0.0)).xyz,
|
||||
);
|
||||
var next_normal = vec3<f32>(0.0, 0.0, 0.0);
|
||||
let norm_light = normalize(GLOBAL_LIGHT);
|
||||
|
||||
// find where ray intersects with group
|
||||
let plane_point = (vec3<f32>(1.0) - dir_if) / 2.0 * dim_f;
|
||||
@@ -204,10 +208,10 @@ fn apply_group(
|
||||
|
||||
// lighting
|
||||
let light = trace_light(full_pos);
|
||||
let diffuse = max(dot(norm_light, normal) * ((dot(dir_view.xyz, normal) + 1.0) / 2.0 * .7 + .3) * 1.3 + 0.1, 0.0);
|
||||
let diffuse = max(dot(global_lights[0].dir, normal) * ((dot(dir_view.xyz, normal) + 1.0) / 2.0 * .7 + .3) * 1.3 + 0.1, 0.0);
|
||||
let ambient = 0.2;
|
||||
let specular = (exp(max(
|
||||
-(dot(reflect(dir_view.xyz, normal), norm_light) + 0.90) * 4.0, 0.0
|
||||
-(dot(reflect(dir_view.xyz, normal), global_lights[0].dir) + 0.90) * 4.0, 0.0
|
||||
)) - 1.0) * light;
|
||||
let lighting = max(diffuse * light.a, ambient);
|
||||
let new_rgb = min(vcolor.xyz * lighting + specular.xyz + light.xyz * vcolor.xyz, vec3<f32>(1.0));
|
||||
@@ -233,7 +237,7 @@ fn apply_group(
|
||||
fn trace_light(
|
||||
pos: vec4<f32>
|
||||
) -> vec4<f32> {
|
||||
let dir = vec4<f32>(-normalize(GLOBAL_LIGHT), 0.0);
|
||||
let dir = vec4<f32>(-global_lights[0].dir, 0.0);
|
||||
var mask = vec4<f32>(0.0);
|
||||
let start = pos + dir * .001;
|
||||
for (var gi: u32 = 0; gi < arrayLength(&voxel_groups); gi = gi + 1) {
|
||||
|
||||
Reference in New Issue
Block a user