Skip to main content

veloren_voxygen/render/pipelines/
lod_object.rs

1use super::super::{ExperimentalShader, GlobalsLayouts, PipelineModes, Vertex as VertexTrait};
2use bytemuck::{Pod, Zeroable};
3use common::util::srgb_to_linear;
4use std::mem;
5use vek::*;
6
7#[repr(C)]
8#[derive(Copy, Clone, Debug, Zeroable, Pod)]
9pub struct Vertex {
10    pos: [f32; 3],
11    norm: [f32; 3],
12    col: [f32; 3],
13    flags: u32,
14}
15
16impl Vertex {
17    pub fn new(
18        pos: Vec3<f32>,
19        norm: Vec3<f32>,
20        col: Rgb<f32>,
21        flags: crate::scene::lod::VertexFlags,
22    ) -> Self {
23        Self {
24            pos: pos.into_array(),
25            norm: norm.into_array(),
26            col: col.into_array(),
27            flags: flags.bits() as u32,
28        }
29    }
30
31    fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
32        const ATTRIBUTES: [wgpu::VertexAttribute; 4] =
33            wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32x3, 3 => Uint32];
34        wgpu::VertexBufferLayout {
35            array_stride: Self::STRIDE,
36            step_mode: wgpu::VertexStepMode::Vertex,
37            attributes: &ATTRIBUTES,
38        }
39    }
40}
41
42impl VertexTrait for Vertex {
43    const QUADS_INDEX: Option<wgpu::IndexFormat> = None;
44    const STRIDE: wgpu::BufferAddress = mem::size_of::<Self>() as wgpu::BufferAddress;
45}
46
47#[repr(C)]
48#[derive(Copy, Clone, Debug, Zeroable, Pod)]
49pub struct Instance {
50    inst_pos: [f32; 3],
51    inst_col: [f32; 3],
52    flags: u32,
53}
54
55impl Instance {
56    pub fn new(inst_pos: Vec3<f32>, col: Rgb<u8>, flags: common::lod::InstFlags) -> Self {
57        Self {
58            inst_pos: inst_pos.into_array(),
59            inst_col: srgb_to_linear(col.map(|c| c as f32 / 255.0)).into_array(),
60            flags: flags.bits() as u32,
61        }
62    }
63
64    fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
65        const ATTRIBUTES: [wgpu::VertexAttribute; 3] = wgpu::vertex_attr_array![
66            4 => Float32x3,
67            5 => Float32x3,
68            6 => Uint32,
69        ];
70        wgpu::VertexBufferLayout {
71            array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
72            step_mode: wgpu::VertexStepMode::Instance,
73            attributes: &ATTRIBUTES,
74        }
75    }
76}
77
78// impl Default for Instance {
79//     fn default() -> Self { Self::new(Mat4::identity(), 0.0, 0.0,
80// Vec3::zero(), 0, 1.0, 0.0, 0) } }
81
82// TODO: ColLightsWrapper instead?
83pub struct Locals;
84
85pub struct LodObjectPipeline {
86    pub pipeline: wgpu::RenderPipeline,
87}
88
89impl LodObjectPipeline {
90    pub fn new(
91        device: &wgpu::Device,
92        vs_module: &wgpu::ShaderModule,
93        fs_module: &wgpu::ShaderModule,
94        global_layout: &GlobalsLayouts,
95        format: wgpu::TextureFormat,
96        pipeline_modes: &PipelineModes,
97    ) -> Self {
98        common_base::span!(_guard, "LodObjectPipeline::new");
99        let render_pipeline_layout =
100            device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
101                label: Some("LoD object pipeline layout"),
102                push_constant_ranges: &[],
103                bind_group_layouts: &[&global_layout.globals, &global_layout.shadow_textures],
104            });
105
106        let samples = pipeline_modes.aa.samples();
107
108        let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
109            label: Some("LoD object pipeline"),
110            layout: Some(&render_pipeline_layout),
111            vertex: wgpu::VertexState {
112                module: vs_module,
113                entry_point: Some("main"),
114                buffers: &[Vertex::desc(), Instance::desc()],
115                compilation_options: Default::default(),
116            },
117            primitive: wgpu::PrimitiveState {
118                topology: wgpu::PrimitiveTopology::TriangleList,
119                strip_index_format: None,
120                front_face: wgpu::FrontFace::Ccw,
121                cull_mode: Some(wgpu::Face::Back),
122                unclipped_depth: false,
123                polygon_mode: if pipeline_modes
124                    .experimental_shaders
125                    .contains(&ExperimentalShader::Wireframe)
126                {
127                    wgpu::PolygonMode::Line
128                } else {
129                    wgpu::PolygonMode::Fill
130                },
131                conservative: false,
132            },
133            depth_stencil: Some(wgpu::DepthStencilState {
134                format: wgpu::TextureFormat::Depth32Float,
135                depth_write_enabled: true,
136                depth_compare: wgpu::CompareFunction::GreaterEqual,
137                stencil: wgpu::StencilState {
138                    front: wgpu::StencilFaceState::IGNORE,
139                    back: wgpu::StencilFaceState::IGNORE,
140                    read_mask: !0,
141                    write_mask: 0,
142                },
143                bias: wgpu::DepthBiasState {
144                    constant: 0,
145                    slope_scale: 0.0,
146                    clamp: 0.0,
147                },
148            }),
149            multisample: wgpu::MultisampleState {
150                count: samples,
151                mask: !0,
152                alpha_to_coverage_enabled: false,
153            },
154            fragment: Some(wgpu::FragmentState {
155                module: fs_module,
156                entry_point: Some("main"),
157                targets: &[
158                    Some(wgpu::ColorTargetState {
159                        format,
160                        blend: Some(wgpu::BlendState::REPLACE),
161                        write_mask: wgpu::ColorWrites::ALL,
162                    }),
163                    Some(wgpu::ColorTargetState {
164                        format: wgpu::TextureFormat::Rgba8Uint,
165                        blend: None,
166                        write_mask: wgpu::ColorWrites::ALL,
167                    }),
168                ],
169                compilation_options: Default::default(),
170            }),
171            multiview: None,
172            cache: None,
173        });
174
175        Self {
176            pipeline: render_pipeline,
177        }
178    }
179}