veloren_voxygen/render/pipelines/
lod_object.rs1use super::super::{AaMode, GlobalsLayouts, 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
78pub 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 aa_mode: AaMode,
96 format: wgpu::TextureFormat,
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 = aa_mode.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: wgpu::PolygonMode::Fill,
124 conservative: false,
125 },
126 depth_stencil: Some(wgpu::DepthStencilState {
127 format: wgpu::TextureFormat::Depth32Float,
128 depth_write_enabled: true,
129 depth_compare: wgpu::CompareFunction::GreaterEqual,
130 stencil: wgpu::StencilState {
131 front: wgpu::StencilFaceState::IGNORE,
132 back: wgpu::StencilFaceState::IGNORE,
133 read_mask: !0,
134 write_mask: 0,
135 },
136 bias: wgpu::DepthBiasState {
137 constant: 0,
138 slope_scale: 0.0,
139 clamp: 0.0,
140 },
141 }),
142 multisample: wgpu::MultisampleState {
143 count: samples,
144 mask: !0,
145 alpha_to_coverage_enabled: false,
146 },
147 fragment: Some(wgpu::FragmentState {
148 module: fs_module,
149 entry_point: Some("main"),
150 targets: &[
151 Some(wgpu::ColorTargetState {
152 format,
153 blend: Some(wgpu::BlendState::REPLACE),
154 write_mask: wgpu::ColorWrites::ALL,
155 }),
156 Some(wgpu::ColorTargetState {
157 format: wgpu::TextureFormat::Rgba8Uint,
158 blend: None,
159 write_mask: wgpu::ColorWrites::ALL,
160 }),
161 ],
162 compilation_options: Default::default(),
163 }),
164 multiview: None,
165 cache: None,
166 });
167
168 Self {
169 pipeline: render_pipeline,
170 }
171 }
172}