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: "main",
114 buffers: &[Vertex::desc(), Instance::desc()],
115 },
116 primitive: wgpu::PrimitiveState {
117 topology: wgpu::PrimitiveTopology::TriangleList,
118 strip_index_format: None,
119 front_face: wgpu::FrontFace::Ccw,
120 cull_mode: Some(wgpu::Face::Back),
121 unclipped_depth: false,
122 polygon_mode: wgpu::PolygonMode::Fill,
123 conservative: false,
124 },
125 depth_stencil: Some(wgpu::DepthStencilState {
126 format: wgpu::TextureFormat::Depth32Float,
127 depth_write_enabled: true,
128 depth_compare: wgpu::CompareFunction::GreaterEqual,
129 stencil: wgpu::StencilState {
130 front: wgpu::StencilFaceState::IGNORE,
131 back: wgpu::StencilFaceState::IGNORE,
132 read_mask: !0,
133 write_mask: 0,
134 },
135 bias: wgpu::DepthBiasState {
136 constant: 0,
137 slope_scale: 0.0,
138 clamp: 0.0,
139 },
140 }),
141 multisample: wgpu::MultisampleState {
142 count: samples,
143 mask: !0,
144 alpha_to_coverage_enabled: false,
145 },
146 fragment: Some(wgpu::FragmentState {
147 module: fs_module,
148 entry_point: "main",
149 targets: &[
150 Some(wgpu::ColorTargetState {
151 format,
152 blend: Some(wgpu::BlendState::REPLACE),
153 write_mask: wgpu::ColorWrites::ALL,
154 }),
155 Some(wgpu::ColorTargetState {
156 format: wgpu::TextureFormat::Rgba8Uint,
157 blend: None,
158 write_mask: wgpu::ColorWrites::ALL,
159 }),
160 ],
161 }),
162 multiview: None,
163 });
164
165 Self {
166 pipeline: render_pipeline,
167 }
168 }
169}