Add placeholder fog volume
This commit is contained in:
parent
4b03671a62
commit
ca9ed36c37
5 changed files with 227 additions and 23 deletions
46
res/shaders/fog.wgsl
Normal file
46
res/shaders/fog.wgsl
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include globals.wgsl
|
||||
|
||||
@vertex
|
||||
fn vs_main(
|
||||
model: VertexInput,
|
||||
instance: InstanceInput,
|
||||
) -> VertexOutput {
|
||||
let model_matrix = mat4x4<f32>(
|
||||
instance.model_matrix_0,
|
||||
instance.model_matrix_1,
|
||||
instance.model_matrix_2,
|
||||
instance.model_matrix_3,
|
||||
);
|
||||
let normal_matrix = mat3x3<f32>(
|
||||
instance.normal_matrix_0,
|
||||
instance.normal_matrix_1,
|
||||
instance.normal_matrix_2,
|
||||
);
|
||||
|
||||
let world_normal = normalize(normal_matrix * model.normal);
|
||||
let world_tangent = normalize(normal_matrix * model.tangent);
|
||||
let world_bitangent = normalize(normal_matrix * model.bitangent);
|
||||
let tangent_matrix = transpose(mat3x3<f32>(
|
||||
world_tangent,
|
||||
world_bitangent,
|
||||
world_normal,
|
||||
));
|
||||
|
||||
let world_position = model_matrix * vec4<f32>(model.position, 1.0);
|
||||
|
||||
var out: VertexOutput;
|
||||
out.clip_position = camera.proj * camera.view * world_position;
|
||||
out.tex_coords = model.tex_coords;
|
||||
out.tangent_position = tangent_matrix * world_position.xyz;
|
||||
out.tangent_light_position = tangent_matrix * light.position;
|
||||
out.tangent_view_position = tangent_matrix * camera.position.xyz;
|
||||
|
||||
out.world_position = world_position;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fs_main(vert: VertexOutput) -> @location(0) vec4<f32> {
|
||||
return vec4<f32>(0.5, 0.5, 0.5, 0.1);
|
||||
}
|
|
@ -3,6 +3,7 @@ use super::model::Vertex;
|
|||
pub struct Instance {
|
||||
pub position: cgmath::Vector3<f32>,
|
||||
pub rotation: cgmath::Quaternion<f32>,
|
||||
pub scale: cgmath::Vector3<f32>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -16,6 +17,7 @@ impl Instance {
|
|||
pub fn to_raw(&self) -> InstanceRaw {
|
||||
InstanceRaw {
|
||||
model: (cgmath::Matrix4::from_translation(self.position)
|
||||
* cgmath::Matrix4::from_nonuniform_scale(self.scale.x, self.scale.y, self.scale.z)
|
||||
* cgmath::Matrix4::from(self.rotation))
|
||||
.into(),
|
||||
normal: cgmath::Matrix3::from(self.rotation).into(),
|
||||
|
|
|
@ -155,4 +155,63 @@ impl Mesh {
|
|||
v.bitangent = (cgmath::Vector3::from(v.bitangent) * denom).into();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn cube(device: &wgpu::Device, size: [f32; 3], name: &str, material_index: usize) -> Mesh {
|
||||
#[rustfmt::skip]
|
||||
let mut vertices = vec![
|
||||
// front
|
||||
ModelVertex { position: [-size[0], -size[1], -size[2]], tex_coords: [0.0, 0.0], normal: [-size[0], -size[1], -size[2]], ..Default::default() },
|
||||
ModelVertex { position: [ size[0], -size[1], -size[2]], tex_coords: [0.0, 0.0], normal: [ size[0], -size[1], -size[2]], ..Default::default() },
|
||||
ModelVertex { position: [ size[0], size[1], -size[2]], tex_coords: [0.0, 0.0], normal: [ size[0], size[1], -size[2]], ..Default::default() },
|
||||
ModelVertex { position: [-size[0], size[1], -size[2]], tex_coords: [0.0, 0.0], normal: [-size[0], size[1], -size[2]], ..Default::default() },
|
||||
|
||||
// back
|
||||
ModelVertex { position: [-size[0], -size[1], size[2]], tex_coords: [0.0, 0.0], normal: [-size[0], -size[1], size[2]], ..Default::default() },
|
||||
ModelVertex { position: [ size[0], -size[1], size[2]], tex_coords: [0.0, 0.0], normal: [ size[0], -size[1], size[2]], ..Default::default() },
|
||||
ModelVertex { position: [ size[0], size[1], size[2]], tex_coords: [0.0, 0.0], normal: [ size[0], size[1], size[2]], ..Default::default() },
|
||||
ModelVertex { position: [-size[0], size[1], size[2]], tex_coords: [0.0, 0.0], normal: [-size[0], size[1], size[2]], ..Default::default() },
|
||||
];
|
||||
#[rustfmt::skip]
|
||||
let indices = vec![
|
||||
// front
|
||||
0, 1, 2,
|
||||
2, 3, 0,
|
||||
// back
|
||||
4, 6, 5,
|
||||
4, 7, 6,
|
||||
// left
|
||||
0, 3, 4,
|
||||
3, 7, 4,
|
||||
// right
|
||||
1, 2, 5,
|
||||
2, 6, 5,
|
||||
// top
|
||||
2, 7, 3,
|
||||
2, 6, 7,
|
||||
// bottom
|
||||
1, 4, 0,
|
||||
1, 5, 4
|
||||
];
|
||||
Mesh::calc_tangents(&indices, &mut vertices);
|
||||
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some(&format!("{:?} Vertex Buffer", name)),
|
||||
contents: bytemuck::cast_slice(&vertices),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some(&format!("{:?} Index Buffer", name)),
|
||||
contents: bytemuck::cast_slice(&indices),
|
||||
usage: wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
|
||||
Mesh {
|
||||
name: name.to_string(),
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
num_elements: indices.len() as u32,
|
||||
material: material_index,
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -19,6 +19,7 @@ impl RenderPass {
|
|||
vertex_layouts: &[VertexBufferLayout],
|
||||
label: &str,
|
||||
is_shadow: bool,
|
||||
has_transparency: bool,
|
||||
) -> Self {
|
||||
let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some((label.to_owned() + " pipeline Layout").as_str()),
|
||||
|
@ -38,6 +39,7 @@ impl RenderPass {
|
|||
shader,
|
||||
label,
|
||||
is_shadow,
|
||||
has_transparency,
|
||||
);
|
||||
|
||||
Self { pipeline }
|
||||
|
@ -52,14 +54,25 @@ impl RenderPass {
|
|||
shader: wgpu::ShaderModuleDescriptor,
|
||||
label: &str,
|
||||
is_shadow: bool,
|
||||
has_transparency: bool,
|
||||
) -> wgpu::RenderPipeline {
|
||||
let shader = device.create_shader_module(shader);
|
||||
|
||||
let blend_comp = if has_transparency {
|
||||
wgpu::BlendComponent {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
}
|
||||
} else {
|
||||
wgpu::BlendComponent::REPLACE
|
||||
};
|
||||
|
||||
let fragment_targets = &[Some(wgpu::ColorTargetState {
|
||||
format: color_format.unwrap_or(wgpu::TextureFormat::Bgra8Unorm),
|
||||
blend: Some(wgpu::BlendState {
|
||||
alpha: wgpu::BlendComponent::REPLACE,
|
||||
color: wgpu::BlendComponent::REPLACE,
|
||||
alpha: blend_comp,
|
||||
color: blend_comp,
|
||||
}),
|
||||
write_mask: wgpu::ColorWrites::ALL,
|
||||
})];
|
||||
|
@ -104,8 +117,7 @@ impl RenderPass {
|
|||
slope_scale: 2.0,
|
||||
clamp: 0.0,
|
||||
}
|
||||
}
|
||||
else { wgpu::DepthBiasState::default() },
|
||||
} else { wgpu::DepthBiasState::default() },
|
||||
}),
|
||||
multisample: wgpu::MultisampleState {
|
||||
count: 1,
|
||||
|
|
|
@ -35,15 +35,19 @@ pub struct State {
|
|||
queue: wgpu::Queue,
|
||||
config: wgpu::SurfaceConfiguration,
|
||||
geometry_pass: RenderPass,
|
||||
fog_pass: RenderPass,
|
||||
camera: Camera,
|
||||
camera_uniform: CameraUniform,
|
||||
camera_buffer: wgpu::Buffer,
|
||||
camera_bind_group: wgpu::BindGroup,
|
||||
camera_controller: CameraController,
|
||||
instances: Vec<Instance>,
|
||||
instance_buffer: wgpu::Buffer,
|
||||
geom_instances: Vec<Instance>,
|
||||
geom_instance_buffer: wgpu::Buffer,
|
||||
fog_instances: Vec<Instance>,
|
||||
fog_instance_buffer: wgpu::Buffer,
|
||||
depth_texture: Texture,
|
||||
model: Model,
|
||||
geom_model: Model,
|
||||
fog_model: Model,
|
||||
light_model: Model,
|
||||
light_uniform: LightUniform,
|
||||
light_buffer: wgpu::Buffer,
|
||||
|
@ -350,7 +354,7 @@ impl State {
|
|||
label: Some("texture_bind_group_layout"),
|
||||
});
|
||||
|
||||
let model = resources::load_model_gltf(
|
||||
let geom_model = resources::load_model_gltf(
|
||||
"models/Sponza.glb",
|
||||
&device,
|
||||
&queue,
|
||||
|
@ -359,6 +363,15 @@ impl State {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let fog_model = resources::load_model_gltf(
|
||||
"models/Cube.glb",
|
||||
&device,
|
||||
&queue,
|
||||
&texture_bind_group_layout,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let light_model = resources::load_model_gltf(
|
||||
"models/Cube.glb",
|
||||
&device,
|
||||
|
@ -368,15 +381,28 @@ impl State {
|
|||
.await
|
||||
.unwrap();
|
||||
|
||||
let instances = vec![Instance {
|
||||
position: [0.0, 0.0, 0.0].into(),
|
||||
let geom_instances = vec![Instance {
|
||||
// this sponza model isn't quite centered
|
||||
position: [60.0, 0.0, 35.0].into(),
|
||||
rotation: cgmath::Quaternion::one(),
|
||||
scale: [1.0, 1.0, 1.0].into(),
|
||||
}];
|
||||
let geom_instance_data = geom_instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
|
||||
let geom_instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Geometry Instance Buffer"),
|
||||
contents: bytemuck::cast_slice(&geom_instance_data),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
|
||||
let instance_data = instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
|
||||
let instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Instance Buffer"),
|
||||
contents: bytemuck::cast_slice(&instance_data),
|
||||
let fog_instances = vec![Instance {
|
||||
position: [0.0, 20.0, 0.0].into(),
|
||||
rotation: cgmath::Quaternion::one(),
|
||||
scale: [1360.0, 20.0, 600.0].into(),
|
||||
}];
|
||||
let fog_instance_data = fog_instances.iter().map(Instance::to_raw).collect::<Vec<_>>();
|
||||
let fog_instance_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Fog Instance Buffer"),
|
||||
contents: bytemuck::cast_slice(&fog_instance_data),
|
||||
usage: wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
|
||||
|
@ -393,6 +419,7 @@ impl State {
|
|||
&[ModelVertex::desc(), InstanceRaw::desc()],
|
||||
"light depth pass",
|
||||
true,
|
||||
false,
|
||||
);
|
||||
|
||||
let geometry_pass = RenderPass::new(
|
||||
|
@ -410,6 +437,25 @@ impl State {
|
|||
&[ModelVertex::desc(), InstanceRaw::desc()],
|
||||
"geometry pass",
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
let fog_pass = RenderPass::new(
|
||||
&device,
|
||||
&[
|
||||
&camera_bind_group_layout,
|
||||
&light_bind_group_layout,
|
||||
&light_depth_bind_group_layout,
|
||||
&texture_bind_group_layout,
|
||||
],
|
||||
&[],
|
||||
"fog.wgsl",
|
||||
Some(config.format),
|
||||
Some(Texture::DEPTH_FORMAT),
|
||||
&[ModelVertex::desc(), InstanceRaw::desc()],
|
||||
"fog pass",
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
let light_debug_pass = RenderPass::new(
|
||||
|
@ -422,6 +468,7 @@ impl State {
|
|||
&[ModelVertex::desc()],
|
||||
"light debug pass",
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
Self {
|
||||
|
@ -431,15 +478,19 @@ impl State {
|
|||
queue,
|
||||
config,
|
||||
geometry_pass,
|
||||
fog_pass,
|
||||
camera,
|
||||
camera_uniform,
|
||||
camera_buffer,
|
||||
camera_bind_group,
|
||||
camera_controller,
|
||||
instances,
|
||||
instance_buffer,
|
||||
geom_instances,
|
||||
geom_instance_buffer,
|
||||
fog_instances,
|
||||
fog_instance_buffer,
|
||||
depth_texture,
|
||||
model,
|
||||
geom_model,
|
||||
fog_model,
|
||||
light_model,
|
||||
light_uniform,
|
||||
light_buffer,
|
||||
|
@ -546,11 +597,11 @@ impl State {
|
|||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
light_depth_render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
|
||||
light_depth_render_pass.set_vertex_buffer(1, self.geom_instance_buffer.slice(..));
|
||||
light_depth_render_pass.set_pipeline(&self.light_depth_pass.pipeline);
|
||||
light_depth_render_pass.draw_model_instanced(
|
||||
&self.model,
|
||||
0..self.instances.len() as u32,
|
||||
&self.geom_model,
|
||||
0..self.geom_instances.len() as u32,
|
||||
[&self.camera_bind_group, &self.light_bind_group].into(),
|
||||
);
|
||||
}
|
||||
|
@ -598,11 +649,45 @@ impl State {
|
|||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
geom_render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
|
||||
geom_render_pass.set_vertex_buffer(1, self.geom_instance_buffer.slice(..));
|
||||
geom_render_pass.set_pipeline(&self.geometry_pass.pipeline);
|
||||
geom_render_pass.draw_model_instanced(
|
||||
&self.model,
|
||||
0..self.instances.len() as u32,
|
||||
&self.geom_model,
|
||||
0..self.geom_instances.len() as u32,
|
||||
[&self.camera_bind_group, &self.light_bind_group, &self.light_depth_bind_group].into(),
|
||||
);
|
||||
}
|
||||
encoder.pop_debug_group();
|
||||
|
||||
encoder.push_debug_group("fog pass");
|
||||
{
|
||||
let mut fog_render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("Fog Render Pass"),
|
||||
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
||||
view: &surface_view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
||||
view: &self.depth_texture.view,
|
||||
depth_ops: Some(wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: StoreOp::Store,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
fog_render_pass.set_vertex_buffer(1, self.fog_instance_buffer.slice(..));
|
||||
fog_render_pass.set_pipeline(&self.fog_pass.pipeline);
|
||||
fog_render_pass.draw_model_instanced(
|
||||
&self.fog_model,
|
||||
0..self.fog_instances.len() as u32,
|
||||
[&self.camera_bind_group, &self.light_bind_group, &self.light_depth_bind_group].into(),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue