챌린지: 바인드리스 레이 트레이싱

거울아, 거울아, ... 다른 거울에 비치는 거울아. 이 챌린지에서는 Metal 3에서 바인드리스 렌더링을 살펴보고 미러링된 표면에 빛을 반사시켜 볼 것입니다.

Metal 3에서 바인드리스가 향상된 덕분에 HybridRendering 샘플 앱이 그 어느 때보다도 멋진 스타일로 변신했습니다. Argument Buffers를 사용하여 셰이더로 모든 장면 리소스를 제공하고, Metal 레이 트레이싱을 사용하여 금속 표면에 빛을 반사시킬 수 있습니다. 아래의 예시를 확인해 보세요.

하지만 앱이 이 장면을 아름답게 그리기는 했지만 아직 한계는 있습니다. 미러링된 바닥에 미러링된 구체가 비치는 것처럼, 상 안에 상을 보여줄 수는 없습니다.

하지만... 상을 비추는 상을 보여주기가 어려운 것은 사실입니다! 빛이 두 개의 표면 사이를 무한히 튀면서, 컴퓨터로는 계산해낼 수 없는 상황을 만들어 냅니다. 레이 트레이싱 앱은 장면 안에 한정된 횟수만 빛(또는 광선)이 “튀도록” 하여 더욱 사실감을 더하는 것으로 이 문제를 해결합니다.

이 챌린지에서는 레이 트레이싱 코드를 확장하고 하나 이상의 추가적인 레이 바운스를 더해서 더욱 실감 나는 이미지를 만들어 보세요.

챌린지 시작하기

거울의 방에 들어가기 전에 먼저 ‘Metal 3로 바인드리스 구현하기’를 시청해 보세요. 시청한 뒤에는 ‘레이 트레이싱으로 실시간 상 렌더링’ 샘플 코드를 다운로드하세요. 이 코드는 챌린지에서 사용할 것입니다.

Metal 3로 바인드리스 구현

Watch now

Rendering reflections in real time using ray tracing

샘플 앱에는 이미지의 각 픽셀에 대해 위치와 법선을 포함하는 씬 G-Buffer에서 상을 계산하는 전용 컴퓨팅 경로가 있습니다.

레이 트레이싱 셰이더는 이 데이터를 읽고 카메라가 보는 방향으로 이를 사용하여 반사된 빛의 방향을 계산합니다. 그런 다음, Metal을 사용하여 이러한 광선을 추적하여 교차점을 찾은 다음, 상을 셰이딩합니다.

raytracing::ray r;
r.origin = positions.read(tid).xyz;
r.direction = normalize(directions.read(tid).xyz);
r.min_distance = 0.1;
r.max_distance = FLT_MAX;

raytracing::intersector<raytracing::instancing, raytracing::triangle_data> inter;
inter.assume_geometry_type( raytracing::geometry_type::triangle );
auto intersection = inter.intersect( r, accelerationStructure, 0xFF );
if ( intersection.type == raytracing::intersection_type::triangle )
{
  // Calculate direct reflections
}

그러면 다음과 같은 이미지가 생성됩니다.

하지만 문제가 하나 있습니다! 바닥에 비친 구체의 상에 소방차의 모습이 보이지 않습니다. 레이 트레이싱 셰이더 rtReflection을 수정하여 추가적인 레이 트레이스 단계를 더함으로써 사라진 트럭을 찾아주세요.

이 챌린지를 완료하려면 다음이 필요합니다.

  1. 반사된 법선 및 교차 위치를 사용하여 빛의 다음 바운스를 계산합니다.
  2. 재료 셰이딩 로직을 도우미 함수로 추출하여 상 내에 상을 셰이딩합니다.
  3. 모든 반사된 색을 결합하고 outImage로 작성합니다.

작업이 끝나면 스크린샷 도구나 GPU Debugger, 또는 QuickTime을 사용하여 솔루션을 캡처하고 Twitter에 해시태그 #WWDC22Challenges로 작품을 게시해 보세요. 바인드리스 레이 트레이싱과 다른 그래픽 및 게임 주제에 대해 의견을 나누고 싶다면 WWDC22 주간에 진행되는 이벤트에 참여하시기 바랍니다.

Read the WWDC22 Challenges Terms and Conditions