veloren_voxygen/render/pipelines/
fluid.rs1use super::super::{AaMode, GlobalsLayouts, TerrainLayout, Vertex as VertexTrait};
2use bytemuck::{Pod, Zeroable};
3use std::mem;
4use vek::*;
5
6#[repr(C)]
7#[derive(Copy, Clone, Debug, Zeroable, Pod)]
8pub struct Vertex {
9 pos_norm: u32,
10 vel: u32,
11}
12
13impl Vertex {
14 pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, river_velocity: Vec2<f32>) -> Self {
15 let (norm_axis, norm_dir) = norm
16 .as_slice()
17 .iter()
18 .enumerate()
19 .find(|(_i, e)| **e != 0.0)
20 .unwrap_or((0, &1.0));
21 let norm_bits = ((norm_axis << 1) | usize::from(*norm_dir > 0.0)) as u32;
22
23 const EXTRA_NEG_Z: f32 = 65536.0;
24
25 Self {
26 pos_norm: 0
27 | (((pos.x as u32) & 0x003F) << 0)
28 | (((pos.y as u32) & 0x003F) << 6)
29 | ((((pos.z + EXTRA_NEG_Z).clamp(0.0, (1 << 17) as f32) as u32) & 0x1FFFF) << 12)
30 | ((norm_bits & 0x7) << 29),
31 vel: river_velocity
32 .map2(Vec2::new(0, 16), |e, off| {
33 ((e * 1000.0 + 32768.9) as u16 as u32) << off
34 })
35 .reduce_bitor(),
36 }
37 }
38
39 fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
40 const ATTRIBUTES: [wgpu::VertexAttribute; 2] = wgpu::vertex_attr_array![
41 0 => Uint32,
42 1 => Uint32,
43 ];
44 wgpu::VertexBufferLayout {
45 array_stride: Self::STRIDE,
46 step_mode: wgpu::VertexStepMode::Vertex,
47 attributes: &ATTRIBUTES,
48 }
49 }
50}
51
52impl VertexTrait for Vertex {
53 const QUADS_INDEX: Option<wgpu::IndexFormat> = Some(wgpu::IndexFormat::Uint16);
54 const STRIDE: wgpu::BufferAddress = mem::size_of::<Self>() as wgpu::BufferAddress;
55}
56
57pub struct FluidPipeline {
58 pub pipeline: wgpu::RenderPipeline,
59}
60
61impl FluidPipeline {
62 pub fn new(
63 device: &wgpu::Device,
64 vs_module: &wgpu::ShaderModule,
65 fs_module: &wgpu::ShaderModule,
66 global_layout: &GlobalsLayouts,
67 terrain_layout: &TerrainLayout,
68 aa_mode: AaMode,
69 format: wgpu::TextureFormat,
70 ) -> Self {
71 common_base::span!(_guard, "FluidPipeline::new");
72 let render_pipeline_layout =
73 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
74 label: Some("Fluid pipeline layout"),
75 push_constant_ranges: &[],
76 bind_group_layouts: &[
77 &global_layout.globals,
78 &global_layout.shadow_textures,
79 &terrain_layout.locals,
80 ],
81 });
82
83 let samples = aa_mode.samples();
84
85 let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
86 label: Some("Fluid pipeline"),
87 layout: Some(&render_pipeline_layout),
88 vertex: wgpu::VertexState {
89 module: vs_module,
90 entry_point: "main",
91 buffers: &[Vertex::desc()],
92 },
93 primitive: wgpu::PrimitiveState {
94 topology: wgpu::PrimitiveTopology::TriangleList,
95 strip_index_format: None,
96 front_face: wgpu::FrontFace::Ccw,
97 cull_mode: None,
98 unclipped_depth: false,
99 polygon_mode: wgpu::PolygonMode::Fill,
100 conservative: false,
101 },
102 depth_stencil: Some(wgpu::DepthStencilState {
103 format: wgpu::TextureFormat::Depth32Float,
104 depth_write_enabled: true,
105 depth_compare: wgpu::CompareFunction::GreaterEqual,
106 stencil: wgpu::StencilState {
107 front: wgpu::StencilFaceState::IGNORE,
108 back: wgpu::StencilFaceState::IGNORE,
109 read_mask: !0,
110 write_mask: 0,
111 },
112 bias: wgpu::DepthBiasState {
113 constant: 0,
114 slope_scale: 0.0,
115 clamp: 0.0,
116 },
117 }),
118 multisample: wgpu::MultisampleState {
119 count: samples,
120 mask: !0,
121 alpha_to_coverage_enabled: false,
122 },
123 fragment: Some(wgpu::FragmentState {
124 module: fs_module,
125 entry_point: "main",
126 targets: &[
127 Some(wgpu::ColorTargetState {
128 format,
129 blend: Some(wgpu::BlendState {
130 color: wgpu::BlendComponent {
131 src_factor: wgpu::BlendFactor::SrcAlpha,
132 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
133 operation: wgpu::BlendOperation::Add,
134 },
135 alpha: wgpu::BlendComponent {
136 src_factor: wgpu::BlendFactor::One,
137 dst_factor: wgpu::BlendFactor::One,
138 operation: wgpu::BlendOperation::Min,
139 },
140 }),
141 write_mask: wgpu::ColorWrites::ALL,
142 }),
143 Some(wgpu::ColorTargetState {
144 format: wgpu::TextureFormat::Rgba8Uint,
145 blend: None,
146 write_mask: wgpu::ColorWrites::ALL,
147 }),
148 ],
149 }),
150 multiview: None,
151 });
152
153 Self {
154 pipeline: render_pipeline,
155 }
156 }
157}