renderling/
cubemap.rs

1//! Render pipelines and layouts for creating cubemaps.
2
3use crate::texture::Texture;
4
5pub fn cubemap_making_bindgroup_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout {
6    device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
7        label: Some("cubemap-making bindgroup"),
8        entries: &[
9            wgpu::BindGroupLayoutEntry {
10                binding: 0,
11                visibility: wgpu::ShaderStages::VERTEX,
12                ty: wgpu::BindingType::Buffer {
13                    ty: wgpu::BufferBindingType::Storage { read_only: true },
14                    has_dynamic_offset: false,
15                    min_binding_size: None,
16                },
17                count: None,
18            },
19            wgpu::BindGroupLayoutEntry {
20                binding: 1,
21                visibility: wgpu::ShaderStages::FRAGMENT,
22                ty: wgpu::BindingType::Texture {
23                    sample_type: wgpu::TextureSampleType::Float { filterable: false },
24                    view_dimension: wgpu::TextureViewDimension::D2,
25                    multisampled: false,
26                },
27                count: None,
28            },
29            wgpu::BindGroupLayoutEntry {
30                binding: 2,
31                visibility: wgpu::ShaderStages::FRAGMENT,
32                ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::NonFiltering),
33                count: None,
34            },
35        ],
36    })
37}
38
39pub fn cubemap_making_bindgroup(
40    device: &wgpu::Device,
41    label: Option<&str>,
42    buffer: &wgpu::Buffer,
43    // The texture to sample the environment from
44    texture: &Texture,
45) -> wgpu::BindGroup {
46    device.create_bind_group(&wgpu::BindGroupDescriptor {
47        label,
48        layout: &cubemap_making_bindgroup_layout(device),
49        entries: &[
50            wgpu::BindGroupEntry {
51                binding: 0,
52                resource: wgpu::BindingResource::Buffer(buffer.as_entire_buffer_binding()),
53            },
54            wgpu::BindGroupEntry {
55                binding: 1,
56                resource: wgpu::BindingResource::TextureView(&texture.view),
57            },
58            wgpu::BindGroupEntry {
59                binding: 2,
60                resource: wgpu::BindingResource::Sampler(&texture.sampler),
61            },
62        ],
63    })
64}
65
66pub struct CubemapMakingRenderPipeline(pub wgpu::RenderPipeline);
67
68impl CubemapMakingRenderPipeline {
69    /// Create the rendering pipeline that creates cubemaps from equirectangular
70    /// images.
71    pub fn new(device: &wgpu::Device, format: wgpu::TextureFormat) -> Self {
72        log::trace!("creating cubemap-making render pipeline with format '{format:?}'");
73        let vertex_linkage = crate::linkage::skybox_cubemap_vertex::linkage(device);
74        let fragment_linkage = crate::linkage::skybox_equirectangular_fragment::linkage(device);
75        let bg_layout = cubemap_making_bindgroup_layout(device);
76        let pp_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
77            label: Some("cubemap-making pipeline layout"),
78            bind_group_layouts: &[&bg_layout],
79            push_constant_ranges: &[],
80        });
81        CubemapMakingRenderPipeline(device.create_render_pipeline(
82            &wgpu::RenderPipelineDescriptor {
83                label: Some("cubemap-making pipeline"),
84                layout: Some(&pp_layout),
85                vertex: wgpu::VertexState {
86                    module: &vertex_linkage.module,
87                    entry_point: vertex_linkage.entry_point,
88                    buffers: &[],
89                    compilation_options: Default::default(),
90                },
91                primitive: wgpu::PrimitiveState {
92                    topology: wgpu::PrimitiveTopology::TriangleList,
93                    strip_index_format: None,
94                    front_face: wgpu::FrontFace::Ccw,
95                    cull_mode: None,
96                    unclipped_depth: false,
97                    polygon_mode: wgpu::PolygonMode::Fill,
98                    conservative: false,
99                },
100                depth_stencil: None,
101                multisample: wgpu::MultisampleState {
102                    mask: !0,
103                    alpha_to_coverage_enabled: false,
104                    count: 1,
105                },
106                fragment: Some(wgpu::FragmentState {
107                    module: &fragment_linkage.module,
108                    entry_point: fragment_linkage.entry_point,
109                    targets: &[Some(wgpu::ColorTargetState {
110                        format,
111                        blend: Some(wgpu::BlendState::ALPHA_BLENDING),
112                        write_mask: wgpu::ColorWrites::ALL,
113                    })],
114                    compilation_options: Default::default(),
115                }),
116                multiview: None,
117                cache: None,
118            },
119        ))
120    }
121}