1.11 전/후면 컬링

이 섹션에서는 전면과 후면이라는 중요한 렌더링 개념을 살펴봅니다. 파이프라인 디스크립터의 primitive 설정에서 cullMode 필드를 back 또는 none으로 설정한 것을 보셨을 것입니다. 이제 cullMode의 의미와 컬링의 중요성에 대해 논의해 봅시다.

플레이그라운드 실행 - 1_11_front_and_back_faces

컬링은 관찰자로부터 멀리 떨어져 있어서 현재 보이지 않는 불필요한 지오메트리를 제거하는 과정입니다. 프리미티브 설정에서 cullMode는 특히 면 컬링 모드를 나타냅니다. 이를 none으로 설정하면 모든 삼각형이 유지되고, back으로 설정하면 GPU가 후면 삼각형을 폐기하도록 지시합니다.

컬링은 래스터화 전에 발생합니다. 전면의 정점 순서는 cw(시계 방향) 및 ccw(반시계 방향)와 같은 토폴로지 구성의 frontFace 매개변수로 지정됩니다. GPU는 삼각형 정점의 순서를 검사합니다. 면 방향이 컬링 설정과 일치하면 삼각형은 래스터화되지 않습니다.

컬링과 밀접하게 관련된 또 다른 개념은 클리핑으로, 이 또한 보이지 않는 지오메트리를 제거하고 렌더링 작업 부하를 줄이는 역할을 합니다. 컬링은 면 방향을 다루는 반면, 클리핑은 지오메트리와 시야 절두체(view frustum) 사이의 공간 관계에 중점을 둡니다. 클리핑은 시야 절두체의 경계에 대해 각 삼각형을 검사합니다. 이 뷰 볼륨 밖에 완전히 있는 모든 삼각형은 추가 처리 전에 폐기되거나 "클리핑"됩니다.

컬링이 비활성화된 경우, @builtin(front_facing) 불리언을 사용하여 래스터화된 프래그먼트가 우리를 향하거나 멀어지는 삼각형의 일부인지 확인할 수 있습니다. 이 정보를 사용하면 프래그먼트의 방향에 따라 다른 색상을 할당하여 외부 및 내부 표면을 다르게 렌더링할 수 있습니다. 이러한 개념이 간단해 보일지라도, 이는 다음 장에서 다룰 깊이(Z-버퍼)를 이해하는 데 기초가 됩니다.

전면과 후면을 다르게 시각화하면 깊이 테스트를 비활성화했을 때 발생할 수 있는 아티팩트를 파악하는 데 도움이 됩니다. 셰이더 측 변경 사항을 살펴보겠습니다:

@fragment
fn fs_main(in: VertexOutput,  @builtin(front_facing) face: bool) -> @location(0) vec4 {
    if (face) {
        return vec4(0.0, 0.0, 1.0 ,1.0);
    }
    else {
        return vec4(0.0, 1.0, 0.0 ,1.0);
    }
}

JavaScript 코드에서는 파이프라인 디스크립터의 프리미티브 섹션에서 cullModenone으로 설정하여 후면 컬링을 비활성화해야 합니다. 이렇게 하면 뒤집힌 면이 프래그먼트 스테이지에 도달합니다:

primitive: {
    topology: 'triangle-strip',
    frontFace: 'ccw',
    cullMode: 'none'
}

다른 면에 의해 가려져야 할 일부 면이 관통하는 모습
다른 면에 의해 가려져야 할 일부 면이 관통하는 모습

렌더링이 부정확하게 나타나고, 다른 면에 의해 가려져야 할 일부 면이 관통하는 것을 볼 수 있습니다. 이는 설정에서 깊이를 활성화하지 않았기 때문에 발생합니다. 깊이 없이 어떤 삼각형이 다른 삼각형을 가려야 하는지 결정할 수 없습니다. 이 상황에서 가림은 오직 그리기 명령의 순서에 의해서만 결정됩니다. 이 문제는 다음 튜토리얼에서 다룰 것입니다.

GitHub에 의견 남기기