쉐이딩이란 3D 그래픽스에서 물체의 표면이 어떻게 빛을 받아 표현되는지를 계산하는 과정입니다.
쉐이딩을 할 때 크게 두가지로 나뉘는데 첫번째는 버텍스 쉐이딩이고 두번째는 픽셀 쉐이딩입니다. DirectX에는 픽셀쉐이딩이라고 하지만 OpenGl에서는 프래그먼트 쉐이딩이라고 합니다. 순서는 버텍스 쉐이딩이 먼저고 그 다음에 픽셀 쉐이딩을 합니다. DirectX내부에서는 모든 물체를 삼각형을 통해 그리는데, 이 삼각형들을 꼭짓점이 버텍스 입니다. 버텍스들을 이리저리 움직여서 물체의 '상'을 나타내는 작업을 버텍스 쉐이딩이라고 합니다. 그 다음 정해진 삼각형에 해당하는 픽셀들에 값을 넣어야하는데, 이 작업을 픽셀 쉐이딩이라고 합니다. 둘을 나눠야지만 움직임과 색을 입히는 작업을 나눠서 할 수 있습니다.
예를들어, 다음과 같은 삼각형 두개로 이루어진 사각형이 있다고 생각해봅시다.
오른쪽은 노란색, 왼쪽은 흰색으로 만들고 싶습니다. 그리고 사각형이 반시계방향으로 돌아가도록 애니메이션을 추가하고 싶습니다. 순서는 버텍스들을 update문에서 조금씩 회전시켜 사각형을 돌아가도록 만드는 것이고, 그에 해당하는 픽셀 중 사각형의 오른쪽 부분에만 노란색을 입혀주면 됩니다.
간단한 코드는 다음과 같습니다.
VSOutput MyVertexShader(const VSInput vsInput) {
VSOutput vsOutput;
// 여기서 여러가지 변환 가능
vsOutput.position = RotateAboutZ(vsInput.position, constants.rotationZ);
vsOutput.color = vsInput.color;
vsOutput.uv = vsInput.uv;
return vsOutput;
}
void Rasterization::Update() {
// 애니메이션 구현
for (auto &mesh : this->meshes) {
mesh->rotationZ += 0.005f;
}
}
vec4 MyPixelShader(const PSInput psInput) {
// 여기서 픽셀의 색을 결정하기 위한 여러가지 규칙 적용
return psInput.uv.x > 0.5f ? vec4(1.0f, 1.0f, 0.0f, 1.0f)
: vec4(psInput.color, 1.0f);
}
void Rander()
{
.....
pixels[i + width * j] = MyPixelShader(psInput);
.....
}
여기서 중요한 점은 픽셀 쉐이딩을 할 때 uv좌표계를 통해 텍스춰링을 한다는 것입니다. 여기서는 간단히 흰색으로만 color를 결정했지만, 이미지 좌표계에서 가져올 때는 더욱더 중요해집니다. uv좌표계는 다음과 같이 약속을 하였습니다.
여기서 왜 uv좌표계는 v축이 아래를 향하는지 의아해 할 수 있는데, 보통 이미지를 가져올 때 이미지의 픽셀값들이 왼쪽위에서 오른쪽 아래로 진행되기 때문입니다. 텍스춰링에 대한 자세한내용은 이전글 : https://pdy0930.tistory.com/58 에서 자세히 이해할 수 있습니다.
추가적으로 물체들을 표현할 때 뒷면까지 고려해서 렌더링할 필요는 없습니다. 이때 사용되는 것이 뒷면 제거인데, 삼각형이 뒷면을 나타낸다면 아예 그리지 않습니다. 삼각형이 뒷면인지 앞면인지 알 수 있는 방법은 삼각형의 외적을 이용해서 알 수 있습니다. DirectX에서는 삼각형을 정의할 때 시계방향이 앞면이라고 정의합니다. 물체를 이리저리 움직일 때 즉 버텍스 쉐이딩을 할 때 앞면이었던 삼각형이 뒷면으로 바뀔 수도 있겠죠? 그럴 때는 그리지 않도록 하는 기법입니다.
간단히 표현하자면 다음과 같습니다.
float Rasterization::EdgeFunction(const vec2 &v0, const vec2 &v1,
const vec2 &point) {
const vec2 a = v1 - v0;
const vec2 b = point - v0;
return a.x * b.y - a.y * b.x;
}
void Render()
{
const float area = EdgeFunction(v0, v1, v2);
if (area < 0.0f) return;
//픽쉘 세이딩...
}
'Graphics Techniques' 카테고리의 다른 글
[Rasterization] 빛의 조명 3가지 (1) | 2024.11.11 |
---|---|
[Rasterization] Blinn-Phone 모델(블린 퐁 모델) (0) | 2024.11.05 |
[Rasterization] 원 그리기와 vertex 2차원 변환 (1) | 2024.10.28 |
[Rasterization] 삼각형의 레스터화 (1) | 2024.10.24 |
[Ray Tracing] - 투명한 구의 빛의 굴절 (0) | 2024.10.22 |