mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Finished porting all pipelines
This commit is contained in:
parent
32a78c3988
commit
4fd9567da5
@ -8,7 +8,7 @@ pub enum RenderError {
|
||||
CustomError(String),
|
||||
CouldNotFindAdapter,
|
||||
ErrorInitializingCompiler,
|
||||
ShaderError(shaderc::Error)
|
||||
ShaderError(shaderc::Error),
|
||||
}
|
||||
|
||||
impl From<wgpu::RequestDeviceError> for RenderError {
|
||||
|
@ -18,20 +18,23 @@ pub use self::{
|
||||
model::{Model, SubModel},
|
||||
pipelines::{
|
||||
clouds::{create_mesh as create_clouds_mesh, Locals as CloudsLocals},
|
||||
figure::{BoneData as FigureBoneData, BoneMeshes, FigureModel, Locals as FigureLocals},
|
||||
figure::{
|
||||
BoneData as FigureBoneData, BoneMeshes, FigureLayout, FigureModel,
|
||||
Locals as FigureLocals,
|
||||
},
|
||||
lod_terrain::LodData,
|
||||
particle::Instance as ParticleInstance,
|
||||
postprocess::create_mesh as create_pp_mesh,
|
||||
shadow::Locals as ShadowLocals,
|
||||
skybox::create_mesh as create_skybox_mesh,
|
||||
sprite::{Instance as SpriteInstance, Locals as SpriteLocals},
|
||||
terrain::Locals as TerrainLocals,
|
||||
terrain::{Locals as TerrainLocals, TerrainLayout, Vertex as TerrainVertex},
|
||||
ui::{
|
||||
create_quad as create_ui_quad,
|
||||
create_quad_vert_gradient as create_ui_quad_vert_gradient, create_tri as create_ui_tri,
|
||||
Locals as UiLocals, Mode as UiMode,
|
||||
},
|
||||
GlobalModel, Globals, Light, Shadow,
|
||||
GlobalModel, Globals, GlobalsLayouts, Light, Shadow,
|
||||
},
|
||||
renderer::{ColLightInfo, Renderer},
|
||||
texture::Texture,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{
|
||||
super::{Mesh, Model},
|
||||
super::{AaMode, GlobalsLayouts, Mesh, Model},
|
||||
terrain::Vertex,
|
||||
};
|
||||
use crate::mesh::greedy::GreedyMesh;
|
||||
@ -105,20 +105,6 @@ impl Default for BoneData {
|
||||
fn default() -> Self { Self::new(anim::vek::Mat4::identity(), anim::vek::Mat4::identity()) }
|
||||
}
|
||||
|
||||
pub struct FigureLayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
pub bone_data: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl FigureLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
locals: Locals::locals_layout(device),
|
||||
bone_data: BoneData::bone_data_layout(device),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FigureModel {
|
||||
pub opaque: Model<Vertex>,
|
||||
/* TODO: Consider using mipmaps instead of storing multiple texture atlases for different
|
||||
@ -139,48 +125,138 @@ impl FigureModel {
|
||||
|
||||
pub type BoneMeshes = (Mesh<Vertex>, anim::vek::Aabb<f32>);
|
||||
|
||||
//gfx_defines! {
|
||||
// constant Locals {
|
||||
// model_mat: [[f32; 4]; 4] = "model_mat",
|
||||
// highlight_col: [f32; 4] = "highlight_col",
|
||||
// model_light: [f32; 4] = "model_light",
|
||||
// atlas_offs: [i32; 4] = "atlas_offs",
|
||||
// model_pos: [f32; 3] = "model_pos",
|
||||
// flags: u32 = "flags",
|
||||
// }
|
||||
//
|
||||
// constant BoneData {
|
||||
// bone_mat: [[f32; 4]; 4] = "bone_mat",
|
||||
// normals_mat: [[f32; 4]; 4] = "normals_mat",
|
||||
// }
|
||||
//
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> = (),
|
||||
// // abuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> =
|
||||
// (), col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||
//
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
// bones: gfx::ConstantBuffer<BoneData> = "u_bones",
|
||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
//
|
||||
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
// directed_shadow_maps: gfx::TextureSampler<f32> =
|
||||
// "t_directed_shadow_maps",
|
||||
//
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
//
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
//
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
|
||||
// "u_light_shadows",
|
||||
//
|
||||
// tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color",
|
||||
// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil:
|
||||
// gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
// // tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))), }
|
||||
pub struct FigureLayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
pub bone_data: wgpu::BindGroupLayout,
|
||||
pub col_lights: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl FigureLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
locals: Locals::layout(device),
|
||||
bone_data: BoneData::layout(device),
|
||||
col_lights: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FigurePipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl FigurePipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &FigureLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Figure pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.alt_horizon,
|
||||
&global_layout.light,
|
||||
&global_layout.shadow,
|
||||
&global_layout.shadow_maps,
|
||||
&global_layout.light_shadows,
|
||||
&layout.locals,
|
||||
&layout.bone_data,
|
||||
&layout.col_lights,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Figure pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
alpha_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +1,7 @@
|
||||
use super::super::{AaMode, GlobalsLayouts};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos_norm: u32 = "v_pos_norm",
|
||||
// }
|
||||
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
|
||||
// locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
// directed_shadow_maps: gfx::TextureSampler<f32> =
|
||||
// "t_directed_shadow_maps",
|
||||
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
// waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
|
||||
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
|
||||
// "u_light_shadows",
|
||||
|
||||
// tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color",
|
||||
// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil:
|
||||
// gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
||||
// // tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
@ -64,4 +30,147 @@ impl Vertex {
|
||||
| (norm_bits & 0x7) << 29,
|
||||
}
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Uint,
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FluidLayout {
|
||||
pub waves: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl FluidLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
waves: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FluidPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl FluidPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &FluidLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Fluid pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.alt_horizon,
|
||||
&global_layout.light,
|
||||
&global_layout.shadow,
|
||||
&global_layout.shadow_maps,
|
||||
&global_layout.light_shadows,
|
||||
&layout.waves,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Fluid pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::None,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
alpha_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: false,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,7 @@
|
||||
use super::super::{Renderer, Texture};
|
||||
use super::super::{AaMode, GlobalsLayouts, Renderer, Texture};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos: [f32; 2] = "v_pos",
|
||||
// }
|
||||
|
||||
// constant Locals {
|
||||
// nul: [f32; 4] = "nul",
|
||||
// }
|
||||
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
// map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
// tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
// tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> =
|
||||
// gfx::preset::depth::LESS_EQUAL_WRITE, // tgt_depth_stencil:
|
||||
// gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
@ -42,6 +14,19 @@ impl Vertex {
|
||||
pos: pos.into_array(),
|
||||
}
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Float2,
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LodData {
|
||||
@ -156,3 +141,88 @@ impl LodData {
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LodTerrainPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl LodTerrainPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Lod terrain pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.alt_horizon,
|
||||
&global_layout.lod_map,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Lod terrain pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,34 +225,201 @@ pub struct GlobalModel {
|
||||
pub shadow_mats: Consts<shadow::Locals>,
|
||||
}
|
||||
|
||||
//gfx_defines! {
|
||||
// constant Globals {
|
||||
// view_mat: [[f32; 4]; 4] = "view_mat",
|
||||
// proj_mat: [[f32; 4]; 4] = "proj_mat",
|
||||
// all_mat: [[f32; 4]; 4] = "all_mat",
|
||||
// cam_pos: [f32; 4] = "cam_pos",
|
||||
// focus_off: [f32; 4] = "focus_off",
|
||||
// focus_pos: [f32; 4] = "focus_pos",
|
||||
// /// NOTE: view_distance.x is the horizontal view distance,
|
||||
// view_distance.y is the LOD /// detail, view_distance.z is the
|
||||
// /// minimum height over any land chunk (i.e. the sea level), and
|
||||
// view_distance.w is the /// maximum height over this minimum height.
|
||||
// ///
|
||||
// /// TODO: Fix whatever alignment issue requires these uniforms to be
|
||||
// aligned. view_distance: [f32; 4] = "view_distance",
|
||||
// time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
|
||||
// sun_dir: [f32; 4] = "sun_dir",
|
||||
// moon_dir: [f32; 4] = "moon_dir",
|
||||
// tick: [f32; 4] = "tick",
|
||||
// /// x, y represent the resolution of the screen;
|
||||
// /// w, z represent the near and far planes of the shadow map.
|
||||
// screen_res: [f32; 4] = "screen_res",
|
||||
// light_shadow_count: [u32; 4] = "light_shadow_count",
|
||||
// shadow_proj_factors: [f32; 4] = "shadow_proj_factors",
|
||||
// medium: [u32; 4] = "medium",
|
||||
// select_pos: [i32; 4] = "select_pos",
|
||||
// gamma_exposure: [f32; 4] = "gamma_exposure",
|
||||
// ambiance: f32 = "ambiance",
|
||||
// cam_mode: u32 = "cam_mode",
|
||||
// sprite_render_distance: f32 = "sprite_render_distance",
|
||||
// }
|
||||
pub struct GlobalsLayouts {
|
||||
pub globals: wgpu::BindGroupLayout,
|
||||
pub light: wgpu::BindGroupLayout,
|
||||
pub shadow: wgpu::BindGroupLayout,
|
||||
pub alt_horizon: wgpu::BindGroupLayout,
|
||||
pub shadow_maps: wgpu::BindGroupLayout,
|
||||
pub light_shadows: wgpu::BindGroupLayout,
|
||||
pub lod_map: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl GlobalsLayouts {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
let globals = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Globals layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
let light = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Light layout"),
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
let shadow = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Shadow layout"),
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
let alt_horizon = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("alt/horizon layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 3,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let shadow_maps = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Shadow maps layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let light_shadows = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Light shadows layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 2,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 3,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let lod_map = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("Lod layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
Self {
|
||||
globals,
|
||||
light,
|
||||
shadow,
|
||||
alt_horizon,
|
||||
shadow_maps,
|
||||
light_shadows,
|
||||
lod_map,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,7 @@
|
||||
use super::super::{AaMode, GlobalsLayouts};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos: [f32; 3] = "v_pos",
|
||||
// // ____BBBBBBBBGGGGGGGGRRRRRRRR
|
||||
// // col: u32 = "v_col",
|
||||
// // ...AANNN
|
||||
// // A = AO
|
||||
// // N = Normal
|
||||
// norm_ao: u32 = "v_norm_ao",
|
||||
// }
|
||||
//
|
||||
// vertex Instance {
|
||||
// // created_at time, so we can calculate time relativity, needed for
|
||||
// relative animation. // can save 32 bits per instance, for particles
|
||||
// that are not relatively animated. inst_time: f32 = "inst_time",
|
||||
//
|
||||
// // The lifespan in seconds of the particle
|
||||
// inst_lifespan: f32 = "inst_lifespan",
|
||||
//
|
||||
// // a seed value for randomness
|
||||
// // can save 32 bits per instance, for particles that don't need
|
||||
// randomness/uniqueness. inst_entropy: f32 = "inst_entropy",
|
||||
//
|
||||
// // modes should probably be seperate shaders, as a part of scaling
|
||||
// and optimisation efforts. // can save 32 bits per instance, and have
|
||||
// cleaner tailor made code. inst_mode: i32 = "inst_mode",
|
||||
//
|
||||
// // A direction for particles to move in
|
||||
// inst_dir: [f32; 3] = "inst_dir",
|
||||
//
|
||||
// // a triangle is: f32 x 3 x 3 x 1 = 288 bits
|
||||
// // a quad is: f32 x 3 x 3 x 2 = 576 bits
|
||||
// // a cube is: f32 x 3 x 3 x 12 = 3456 bits
|
||||
// // this vec is: f32 x 3 x 1 x 1 = 96 bits (per instance!)
|
||||
// // consider using a throw-away mesh and
|
||||
// // positioning the vertex vertices instead,
|
||||
// // if we have:
|
||||
// // - a triangle mesh, and 3 or more instances.
|
||||
// // - a quad mesh, and 6 or more instances.
|
||||
// // - a cube mesh, and 36 or more instances.
|
||||
// inst_pos: [f32; 3] = "inst_pos",
|
||||
// }
|
||||
//
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
// ibuf: gfx::InstanceBuffer<Instance> = (),
|
||||
//
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
//
|
||||
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
// directed_shadow_maps: gfx::TextureSampler<f32> =
|
||||
// "t_directed_shadow_maps",
|
||||
//
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
//
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
//
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
|
||||
// "u_light_shadows",
|
||||
//
|
||||
// tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color",
|
||||
// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil:
|
||||
// gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
// // tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
@ -100,6 +30,15 @@ impl Vertex {
|
||||
norm_ao: norm_bits,
|
||||
}
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Uint],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -198,8 +137,113 @@ impl Instance {
|
||||
inst_dir: (inst_pos2 - inst_pos).into_array(),
|
||||
}
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Instance,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float, 1 => Float, 2 => Float, 3 => Int, 4 => Float3],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Instance {
|
||||
fn default() -> Self { Self::new(0.0, 0.0, ParticleMode::CampfireSmoke, Vec3::zero()) }
|
||||
}
|
||||
|
||||
pub struct ParticlePipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl ParticlePipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Particle pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.alt_horizon,
|
||||
&global_layout.light,
|
||||
&global_layout.shadow,
|
||||
&global_layout.shadow_maps,
|
||||
&global_layout.light_shadows,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Particle pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
alpha_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc(), Instance::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,7 @@
|
||||
use super::super::{Mesh, Tri};
|
||||
use super::super::{AaMode, GlobalsLayouts, Mesh, Tri};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos: [f32; 2] = "v_pos",
|
||||
// }
|
||||
//
|
||||
// constant Locals {
|
||||
// proj_mat_inv: [[f32; 4]; 4] = "proj_mat_inv",
|
||||
// view_mat_inv: [[f32; 4]; 4] = "view_mat_inv",
|
||||
// }
|
||||
//
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
//
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
//
|
||||
// map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
//
|
||||
// color_sampler: gfx::TextureSampler<<TgtColorFmt as
|
||||
// gfx::format::Formatted>::View> = "src_color", depth_sampler:
|
||||
// gfx::TextureSampler<<TgtDepthStencilFmt as gfx::format::Formatted>::View> =
|
||||
// "src_depth",
|
||||
//
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
//
|
||||
// tgt_color: gfx::RenderTarget<WinColorFmt> = "tgt_color",
|
||||
// }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Locals {
|
||||
@ -59,6 +28,21 @@ pub struct Vertex {
|
||||
pub pos: [f32; 2],
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Float2,
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_mesh() -> Mesh<Vertex> {
|
||||
let mut mesh = Mesh::new();
|
||||
|
||||
@ -78,3 +62,117 @@ pub fn create_mesh() -> Mesh<Vertex> {
|
||||
|
||||
mesh
|
||||
}
|
||||
|
||||
pub struct PostProcessLayout {
|
||||
pub src_color: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl PostProcessLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
src_color: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PostProcessPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl PostProcessPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &PostProcessLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Post process pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[&global_layout.globals, &layout.src_color],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Post process pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: false,
|
||||
depth_compare: wgpu::CompareFunction::Always,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,9 @@
|
||||
use super::super::{ColLightInfo, Renderer, Texture};
|
||||
use super::super::{
|
||||
AaMode, ColLightInfo, FigureLayout, GlobalsLayouts, Renderer, TerrainVertex, Texture,
|
||||
};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// constant Locals {
|
||||
// shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
||||
// texture_mats: [[f32; 4]; 4] = "texture_mat",
|
||||
// }
|
||||
|
||||
// pipeline pipe {
|
||||
// // Terrain vertex stuff
|
||||
// vbuf: gfx::VertexBuffer<terrain::Vertex> = (),
|
||||
|
||||
// locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||
|
||||
// tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> =
|
||||
// gfx::state::Depth { fun: gfx::state::Comparison::Less,
|
||||
// write: true,
|
||||
// },
|
||||
// }
|
||||
|
||||
// pipeline figure_pipe {
|
||||
// // Terrain vertex stuff
|
||||
// vbuf: gfx::VertexBuffer<terrain::Vertex> = (),
|
||||
|
||||
// locals: gfx::ConstantBuffer<figure::Locals> = "u_locals",
|
||||
// bones: gfx::ConstantBuffer<figure::BoneData> = "u_bones",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||
|
||||
// tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> =
|
||||
// gfx::state::Depth { fun: gfx::state::Comparison::Less,
|
||||
// write: true,
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Locals {
|
||||
@ -58,6 +20,33 @@ impl Locals {
|
||||
}
|
||||
|
||||
pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
||||
|
||||
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ShadowLayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl ShadowLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
locals: Locals::layout(device),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_col_lights(
|
||||
@ -98,3 +87,165 @@ pub fn create_col_lights(
|
||||
col_lights.as_bytes(),
|
||||
)
|
||||
}
|
||||
|
||||
pub struct ShadowFigurePipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl ShadowFigurePipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &FigureLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Shadow figure pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.light_shadows,
|
||||
&layout.waves,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Shadow figure pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::Less,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[TerrainVertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ShadowPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl ShadowPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &ShadowLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Shadow pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.light_shadows,
|
||||
&layout.locals,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Shadow pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::Less,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[TerrainVertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,40 +1,108 @@
|
||||
use super::super::{Mesh, Quad};
|
||||
use super::super::{AaMode, GlobalsLayouts, Mesh, Quad};
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos: [f32; 3] = "v_pos",
|
||||
// }
|
||||
|
||||
// constant Locals {
|
||||
// nul: [f32; 4] = "nul",
|
||||
// }
|
||||
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
// tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
// tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> =
|
||||
// gfx::preset::depth::LESS_EQUAL_TEST, // tgt_depth_stencil:
|
||||
// gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
pub pos: [f32; 3],
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &[wgpu::VertexAttributeDescriptor {
|
||||
offset: 0,
|
||||
shader_location: 0,
|
||||
format: wgpu::VertexFormat::Float3,
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SkyboxPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl SkyboxPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
layouts: &GlobalsLayouts,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Skybox pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[&layouts.globals, &layouts.alt_horizon],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Skybox pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_mesh() -> Mesh<Vertex> {
|
||||
let mut mesh = Mesh::new();
|
||||
|
||||
|
@ -1,73 +1,8 @@
|
||||
use super::super::{AaMode, GlobalsLayouts, TerrainLayout};
|
||||
use core::fmt;
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos: [f32; 3] = "v_pos",
|
||||
// // Because we try to restrict terrain sprite data to a 128×128 block
|
||||
// // we need an offset into the texture atlas.
|
||||
// atlas_pos: u32 = "v_atlas_pos",
|
||||
// // ____BBBBBBBBGGGGGGGGRRRRRRRR
|
||||
// // col: u32 = "v_col",
|
||||
// // ...AANNN
|
||||
// // A = AO
|
||||
// // N = Normal
|
||||
// norm_ao: u32 = "v_norm_ao",
|
||||
// }
|
||||
//
|
||||
// constant Locals {
|
||||
// // Each matrix performs rotatation, translation, and scaling,
|
||||
// relative to the sprite // origin, for all sprite instances. The
|
||||
// matrix will be in an array indexed by the // sprite instance's
|
||||
// orientation (0 through 7). mat: [[f32; 4]; 4] = "mat",
|
||||
// wind_sway: [f32; 4] = "wind_sway",
|
||||
// offs: [f32; 4] = "offs",
|
||||
// }
|
||||
//
|
||||
// vertex/*constant*/ Instance {
|
||||
// // Terrain block position and orientation
|
||||
// pos_ori: u32 = "inst_pos_ori",
|
||||
// inst_mat0: [f32; 4] = "inst_mat0",
|
||||
// inst_mat1: [f32; 4] = "inst_mat1",
|
||||
// inst_mat2: [f32; 4] = "inst_mat2",
|
||||
// inst_mat3: [f32; 4] = "inst_mat3",
|
||||
// inst_light: [f32; 4] = "inst_light",
|
||||
// inst_wind_sway: f32 = "inst_wind_sway",
|
||||
// }
|
||||
//
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
// ibuf: gfx::InstanceBuffer<Instance> = (),
|
||||
// col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||
//
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// // A sprite instance is a cross between a sprite and a terrain chunk.
|
||||
// terrain_locals: gfx::ConstantBuffer<terrain::Locals> =
|
||||
// "u_terrain_locals", globals: gfx::ConstantBuffer<Globals> =
|
||||
// "u_globals", lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
//
|
||||
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
// directed_shadow_maps: gfx::TextureSampler<f32> =
|
||||
// "t_directed_shadow_maps",
|
||||
//
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
//
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
//
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
|
||||
// "u_light_shadows",
|
||||
//
|
||||
// tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color",
|
||||
// ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth_stencil:
|
||||
// gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
// // tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
@ -123,6 +58,15 @@ impl Vertex {
|
||||
norm_ao: norm_bits,
|
||||
}
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float3, 1 => Uint, 2 => Uint],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -162,6 +106,15 @@ impl Instance {
|
||||
inst_wind_sway: wind_sway,
|
||||
}
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Instance,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Uint, 1 => Float4,2 => Float4, 3 => Float4,4 => Float4,5 => Float],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Instance {
|
||||
@ -191,4 +144,154 @@ impl Locals {
|
||||
offs: [offs.x, offs.y, offs.z, 0.0],
|
||||
}
|
||||
}
|
||||
|
||||
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SpriteLayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
pub col_lights: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl SpriteLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
locals: Locals::layout(device),
|
||||
col_lights: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SpritePipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl SpritePipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &SpriteLayout,
|
||||
terrain_layout: &TerrainLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Sprite pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.alt_horizon,
|
||||
&global_layout.light,
|
||||
&global_layout.shadow,
|
||||
&global_layout.shadow_maps,
|
||||
&global_layout.light_shadows,
|
||||
&layout.col_lights,
|
||||
&layout.locals,
|
||||
&terrain_layout.locals,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Sprite pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
alpha_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc(), Instance::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,48 +1,7 @@
|
||||
use super::super::{AaMode, GlobalsLayouts};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos_norm: u32 = "v_pos_norm",
|
||||
// atlas_pos: u32 = "v_atlas_pos",
|
||||
// }
|
||||
|
||||
// constant Locals {
|
||||
// model_offs: [f32; 3] = "model_offs",
|
||||
// load_time: f32 = "load_time",
|
||||
// atlas_offs: [i32; 4] = "atlas_offs",
|
||||
// }
|
||||
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
// col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
// lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||
// shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||
|
||||
// point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||
// directed_shadow_maps: gfx::TextureSampler<f32> =
|
||||
// "t_directed_shadow_maps",
|
||||
|
||||
// alt: gfx::TextureSampler<[f32; 2]> = "t_alt",
|
||||
// horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||
|
||||
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||
|
||||
// // Shadow stuff
|
||||
// light_shadows: gfx::ConstantBuffer<shadow::Locals> =
|
||||
// "u_light_shadows",
|
||||
|
||||
// tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||
// tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> =
|
||||
// gfx::preset::depth::LESS_EQUAL_WRITE, // tgt_depth_stencil:
|
||||
// gfx::DepthStencilTarget<TgtDepthStencilFmt> =
|
||||
// (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,
|
||||
// (StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))), }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
@ -141,6 +100,15 @@ impl Vertex {
|
||||
pub fn set_bone_idx(&mut self, bone_idx: u8) {
|
||||
self.pos_norm = (self.pos_norm & !(0xF << 27)) | ((bone_idx as u32 & 0xF) << 27);
|
||||
}
|
||||
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Uint,1 => Uint],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
@ -159,4 +127,144 @@ impl Locals {
|
||||
atlas_offs: [0; 4],
|
||||
}
|
||||
}
|
||||
|
||||
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TerrainLayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
pub col_lights: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl TerrainLayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
locals: Locals::layout(device),
|
||||
col_lights: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TerrainPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl TerrainPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &TerrainLayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("Terrain pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[
|
||||
&global_layout.globals,
|
||||
&global_layout.alt_horizon,
|
||||
&global_layout.light,
|
||||
&global_layout.shadow,
|
||||
&global_layout.shadow_maps,
|
||||
&global_layout.light_shadows,
|
||||
&layout.locals,
|
||||
&layout.col_lights,
|
||||
],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("Terrain pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
alpha_blend: wgpu::BlendDescriptor::REPLACE,
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +1,7 @@
|
||||
use super::super::{Quad, Tri};
|
||||
use super::super::{AaMode, GlobalsLayouts, Quad, Tri};
|
||||
use vek::*;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
// gfx_defines! {
|
||||
// vertex Vertex {
|
||||
// pos: [f32; 2] = "v_pos",
|
||||
// uv: [f32; 2] = "v_uv",
|
||||
// color: [f32; 4] = "v_color",
|
||||
// center: [f32; 2] = "v_center",
|
||||
// mode: u32 = "v_mode",
|
||||
// }
|
||||
|
||||
// constant Locals {
|
||||
// pos: [f32; 4] = "w_pos",
|
||||
// }
|
||||
|
||||
// pipeline pipe {
|
||||
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
|
||||
// locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
// globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
// tex: gfx::TextureSampler<[f32; 4]> = "u_tex",
|
||||
|
||||
// scissor: gfx::Scissor = (),
|
||||
|
||||
// tgt_color: gfx::BlendTarget<WinColorFmt> = ("tgt_color",
|
||||
// gfx::state::ColorMask::all(), gfx::preset::blend::ALPHA), tgt_depth:
|
||||
// gfx::DepthTarget<WinDepthFmt> = gfx::preset::depth::LESS_EQUAL_TEST, }
|
||||
// }
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Vertex {
|
||||
@ -39,12 +12,40 @@ pub struct Vertex {
|
||||
mode: u32,
|
||||
}
|
||||
|
||||
impl Vertex {
|
||||
fn desc<'a>() -> wgpu::VertexBufferDescriptor<'a> {
|
||||
use std::mem;
|
||||
wgpu::VertexBufferDescriptor {
|
||||
stride: mem::size_of::<Self>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::InputStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![0 => Float2, 1 => Float2, 2 => Float4, 3 => Float2, 4 => Uint],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, AsBytes)]
|
||||
pub struct Locals {
|
||||
pos: [f32; 4],
|
||||
}
|
||||
|
||||
impl Locals {
|
||||
fn layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
|
||||
device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::UniformBuffer {
|
||||
dynamic: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec4<f32>> for Locals {
|
||||
fn from(pos: Vec4<f32>) -> Self {
|
||||
Self {
|
||||
@ -94,6 +95,130 @@ impl Mode {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UILayout {
|
||||
pub locals: wgpu::BindGroupLayout,
|
||||
pub tex: wgpu::BindGroupLayout,
|
||||
}
|
||||
|
||||
impl UILayout {
|
||||
pub fn new(device: &wgpu::Device) -> Self {
|
||||
Self {
|
||||
locals: Locals::layout(device),
|
||||
tex: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::SampledTexture {
|
||||
component_type: wgpu::TextureComponentType::Float,
|
||||
dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler { comparison: false },
|
||||
count: None,
|
||||
},
|
||||
],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UIPipeline {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
impl UIPipeline {
|
||||
pub fn new(
|
||||
device: &wgpu::Device,
|
||||
vs_module: &wgpu::ShaderModule,
|
||||
fs_module: &wgpu::ShaderModule,
|
||||
sc_desc: &wgpu::SwapChainDescriptor,
|
||||
global_layout: &GlobalsLayouts,
|
||||
layout: &UILayout,
|
||||
aa_mode: AaMode,
|
||||
) -> Self {
|
||||
let render_pipeline_layout =
|
||||
device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("UI pipeline layout"),
|
||||
push_constant_ranges: &[],
|
||||
bind_group_layouts: &[&global_layout.globals, &layout.locals, &layout.tex],
|
||||
});
|
||||
|
||||
let samples = match aa_mode {
|
||||
AaMode::None | AaMode::Fxaa => 1,
|
||||
// TODO: Ensure sampling in the shader is exactly between the 4 texels
|
||||
AaMode::SsaaX4 => 1,
|
||||
AaMode::MsaaX4 => 4,
|
||||
AaMode::MsaaX8 => 8,
|
||||
AaMode::MsaaX16 => 16,
|
||||
};
|
||||
|
||||
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("UI pipeline"),
|
||||
layout: Some(&render_pipeline_layout),
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: vs_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: Some(wgpu::ProgrammableStageDescriptor {
|
||||
module: fs_module,
|
||||
entry_point: "main",
|
||||
}),
|
||||
rasterization_state: Some(wgpu::RasterizationStateDescriptor {
|
||||
front_face: wgpu::FrontFace::Ccw,
|
||||
cull_mode: wgpu::CullMode::Back,
|
||||
clamp_depth: false,
|
||||
depth_bias: 0,
|
||||
depth_bias_slope_scale: 0.0,
|
||||
depth_bias_clamp: 0.0,
|
||||
}),
|
||||
primitive_topology: wgpu::PrimitiveTopology::TriangleList,
|
||||
color_states: &[wgpu::ColorStateDescriptor {
|
||||
format: sc_desc.format,
|
||||
color_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::SrcAlpha,
|
||||
dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
alpha_blend: wgpu::BlendDescriptor {
|
||||
src_factor: wgpu::BlendFactor::One,
|
||||
dst_factor: wgpu::BlendFactor::One,
|
||||
operation: wgpu::BlendOperation::Add,
|
||||
},
|
||||
write_mask: wgpu::ColorWrite::ALL,
|
||||
}],
|
||||
depth_stencil_state: Some(wgpu::DepthStencilStateDescriptor {
|
||||
format: wgpu::TextureFormat::Depth24Plus,
|
||||
depth_write_enabled: false,
|
||||
depth_compare: wgpu::CompareFunction::LessEqual,
|
||||
stencil: wgpu::StencilStateDescriptor {
|
||||
front: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
back: wgpu::StencilStateFaceDescriptor::IGNORE,
|
||||
read_mask: !0,
|
||||
write_mask: !0,
|
||||
},
|
||||
}),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: wgpu::IndexFormat::Uint16,
|
||||
vertex_buffers: &[Vertex::desc()],
|
||||
},
|
||||
sample_count: samples,
|
||||
sample_mask: !0,
|
||||
alpha_to_coverage_enabled: false,
|
||||
});
|
||||
|
||||
Self {
|
||||
pipeline: render_pipeline,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_quad(
|
||||
rect: Aabr<f32>,
|
||||
uv_rect: Aabr<f32>,
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user