Vulkan tutorial #2 Graphic pipeline overview
요약
Vulkan의 Graphics pipeline
<High Level Overview (간단한 설명)>
vertex/index buffer >> Input Assembles >> VertexShader >>...>> Rasterization >> Fragment Shader >> Color Blending >> FrameBuffer(image)
저자는 각 단계를 두가지 부분으로 나
Fixed Function : programmers의 영향을 적게 미치는 공간, InputAssembles, Rasterization, Color Blending이 해당부분
Programmable : 우리가 직접 관여할 수 있는 부분 , Vertex Shader, Fragment Shaders 가 해당부분에 속함 gpu에서 사용 할 수 있는 언어인 glsl (directx의 hlsl과 같음)을 사용
glsl에서의 NDC(Normal device coordinate) 왼쪽 위 (-1, -1), 오른쪽 아래 (1, 1) 센터가 (0,0)
simple_shader.vert
#version 450
vec2 positions[3] = vec2[](
vec2(0.0, -0.5),
vec2(0.5, 0.5),
vec2(-0.5, 0.5)
);
void main() {
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
}
- gl_Position : 결과저장할 변수
- gl_VertexIndex 현재 인덱스
simple_shader.frag
#version 450
layout (location = 0) out vec4 outColor;
void main() {
outColor = vec4(1.0, 0.0, 0.0, 1.0);
}
outColor : 표현할 색깔
shader를 vulkan에 사용하기 위해서는 SPIR-V(Standard Portable Intermediate Representation V) 를 이용해서 출력해야함. vulkan sdk의 glslc.exe 컴파일러 사용
lve_pipeline.cpp
#include "lve_pipeline.h"
//std
#include <fstream>
#include <stdexcept>
#include <iostream>
namespace lve {
// init
LvePipeline::LvePipeline(const std::string& vertFilepath, const std::string& fragFilepath)
{
createGraphicsPipeline(vertFilepath, fragFilepath);
}
/*
* readFile
*/
std::vector<char> LvePipeline::readFile(const std::string& filepath)
{
std::ifstream file{ filepath, std::ios::ate | std::ios::binary };
if (!file.is_open())
{
throw std::runtime_error("failed to open file: " + filepath);
}
size_t fileSize = static_cast<size_t>(file.tellg());
std::vector<char> buffer(fileSize);
file.seekg(0);
file.read(buffer.data(), fileSize);
file.close();
return buffer;
}
void LvePipeline::createGraphicsPipeline(const std::string& vertFilepath, const std::string& fragFilepath)
{
auto vertCode = readFile(vertFilepath);
auto fragCode = readFile(fragFilepath);
std::cout << "Vertex Shader Code Size: " << vertCode.size() << std::endl;
std::cout << "fragCode Shader Code Size: " << fragCode.size() << std::endl;
}
}
}
tutorial2에서는 first_app.h에서 lve_pipeline 을 불러서 readFile을 해서 컴파일된 쉐이더의 크기를 불러오는 부분이다.
결과물이 잘 나온다면 다음을 출력한다.