Vulkan Tutorial의 Rust 버전을 해 보았다 ~ 그래픽 파이프 라인 편 ~

8328 단어 Vulkan입문Rust
Vulkan의 입문을 Rust로 해 나갑니다. 목차는 이쪽 . 이번까지의 구현을 했다 GitHub는 이쪽 .

Vulkan의 그래픽 파이프라인



Vulkan의 그래픽 파이프 라인은 OpenGL 등과 비슷한 느낌으로 그림과 같이되어 있습니다.
(이미지는 htps : // ゔ ヵ ー 토리 토리. 코 m / D 라우 ぃ g_ 아_ t 리안 g ぇ / G 라 p 히 cs_ 피페 네_ 바시 cs / 인 t 로즈 c 치온 보다 인용)

셰이더 만들기 및 로드



Vulkano의 경우 vulkano-shaders을 사용하여 컴파일 할 때 GLSL을 SPIR-V로 변환 할 수 있으므로 이번에는 이것을 사용합니다.
먼저 GLSL에서 vertex shader와 fragment shader를 만듭니다. 이때,
#extension GL_ARB_separate_shader_objects : enable

붙여주세요. 그런 다음 main.rs
mod vertex_shader {
    vulkano_shaders::shader! {
        ty: "vertex",
        path: "path/to/vertex_shader"
    }
}
mod fragment_shader {
    vulkano_shaders::shader! {
            ty: "fragment",
            path: "path/to/fragment_shader"
        }
    }
vertex_shader::Shader::load(device.clone()).expect("Failed to load the vertex shader");
fragment_shader::Shader::load(device.clone()).expect("Failed to load the fragment shader");

합니다. 이제 최소한의 셰이더를 읽을 수 있습니다.

render pass 만들기



참고원 과 순서가 다릅니다만, Vulkano에서는 파이프라인을 만드는데 render pass가 필요하기 때문에 먼저 이것을 만듭니다. 또 Vulkano의 경우는 통상, single_pass_renderpass! 매크로로 각 어태치먼트나 패스를 써 가므로, C/C++와는 오히려 바뀝니다.
let render_pass = single_pass_renderpass!(device.clone(),
    attachments: { /* 各アタッチメント */ },
    pass: { /* パス */ }
).unwrap()

각 부착물 설정



각 어태치먼트는 위의 attachments:에 써 갑니다. 이번에는 colorAttachment를 설정합니다.
attachments: {
    color: {
        load: Clear,
        store: Store,
        format: swapchain.format(),
        samples: 1,
    }
},

여기서, loadstore 는 Vulkan의 loadOpstoreOp 에 상당하는 것으로, samples 는 이번에는 멀티 샘플링을 하지 않기 때문에 1

경로 설정



위에서 설정한 부착물을 사용하여 경로를 설정합니다.
pass: {
    color: [color],
    depth_stencil: {}
}

fixed function 설정



fixed function이란 Viewport나 래스터라이저 등의 총칭과 같습니다. Vulkan의 경우, fixed function으로 분류되는 것은 파이프라인마다 고정으로 기본은 변경할 수 없는 것 같습니다. 다만, Viewport등은 설정시에 동적으로 변환할 수도 있습니다.
Vulkano의 경우는 vulkano::pipeline::GraphicsPipeline 에 이른바 빌더 패턴으로 만들어 갑니다.

vertex input 및 vertex shader 설정



이번 참고원 에서는 vertex shader 자신이 데이터를 가지고 있으므로 외부로부터 정점 데이터를 입력할 필요가 없습니다. Vulkano의 경우 이런 경우에는 vulkano::pipeline::vertex::BufferlessDefinition를 사용합니다. 정점 데이터를 입력할 때는 impl_vertex!를 사용합니다.
.vertex_input(BufferlessDefinition)
.vertex_shader(vertex_shader.main_entry_point(), ())

viewport 설정



위와 같이 동적인 viewport로 하는 것도 가능합니다만 여기에서는 고정 사이즈로 해, scissor는 전체를 찍을 수 있게 합니다.
let viewport = Viewport {
    origin: [0.0, 0.0],
    dimensions: [
        swapchain.dimensions()[0] as _,
        swapchain.dimensions()[1] as _
    ],
    depth_range: 0.0..1.0,
};
builder.viewports(vec![viewport]);

Subpass 설정



위에서 만든 render pass를 Subpass로 변환하여 사용합니다.
.render_pass(Subpass::from(render_pass, 0).unwrap())

정리와 감상



이번에도 특히 실행 결과는 변화하지 않고 셰이더의 로드나 파이프라인의 작성으로 끝났습니다만, 다음번은 드디어 그릴 수 있을 것입니다.

좋은 웹페이지 즐겨찾기