Neural Rendering
신경 렌더링은 그래픽 파이프라인의 일부를 신경망으로 대체해 사진에서 학습한 이미지와 3D 장면을 생성합니다. 방법과 코드를 살펴봅니다.
뉴럴 렌더링은 기존 컴퓨터 그래픽스 파이프라인의 일부를 대체하거나 보강하는 신경망을 사용해 이미지와 비디오를 생성하면서, 카메라 시점, 조명, 기하 구조, 외관과 같은 장면 속성을 제어하는 기법입니다. 기존 렌더링은 빛의 전파 물리를 사용해 직접 제작한 3D 모델, 재질, 광원으로부터 이미지를 계산합니다. 반면 뉴럴 렌더링은 사진과 비디오에서 이러한 요소 일부를 학습하거나 최종 픽셀을 직접 생성하는 방법을 학습합니다. 뉴럴 렌더링은 흔히 네트워크 학습에 미분 가능한 렌더링을 포함하여 생성형 머신러닝과 컴퓨터 그래픽스의 물리 지식을 결합하는 분야입니다. 뉴럴 렌더링은 실제 장소를 사실적인 3D로 캡처하고, 비디오 게임에서 AI 업스케일링과 프레임 생성을 수행하며, 로보틱스 및 자율주행차 시뮬레이션에도 활용됩니다.
뉴럴 렌더링의 작동 방식#
가장 영향력 있는 분야는 일반 사진에서 3D 장면을 학습합니다. 신경망, 학습된 특징의 그리드, 3D 프리미티브 집합과 같은 장면 표현을 학습 사진의 카메라 위치에서 이미지로 렌더링하는 과정은 미분 가능한 렌더러를 통해 이루어집니다. 렌더러의 모든 단계를 미분할 수 있으므로 렌더링된 이미지와 실제 사진 간의 차이를 역전파하여 장면의 각 파라미터까지 추적할 수 있습니다. 여러 시점에 걸쳐 이 과정을 반복하면 어떤 카메라에도 포착되지 않은 시점까지 렌더링할 수 있을 만큼 장면을 잘 재구성할 수 있습니다.
사진의 카메라 포즈는 보통 COLMAP과 같은 Structure from Motion 소프트웨어로 구합니다. 이 소프트웨어는 겹치는 사진 간의 특징을 매칭해 각 사진이 촬영된 위치를 복원합니다.
뉴럴 장면 표현#
2020년에 발표된 뉴럴 래디언스 필드(NeRF)는 3D 위치와 시선 방향을 밀도와 색상에 매핑하는 다층 퍼셉트론의 가중치에 장면을 저장합니다. 픽셀을 렌더링하기 위해 NeRF는 카메라 광선을 따라 점을 샘플링하고 볼륨 렌더링으로 색상을 혼합합니다. 각 샘플은 불투명도와 앞선 샘플을 통과해 남은 빛의 양에 따라 기여합니다. 다음 PyTorch 코드는 광선 하나를 따라 관측된 픽셀 하나를 재현하도록 작은 필드를 학습합니다.
import torch
from torch import nn
# A tiny neural field that maps a 3D point to a density and an RGB color
torch.manual_seed(0)
field = nn.Sequential(nn.Linear(3, 64), nn.ReLU(), nn.Linear(64, 4))
optimizer = torch.optim.Adam(field.parameters(), lr=0.01)
# 64 points along one camera ray, and the color a training photo shows for that pixel
depths = torch.linspace(2.0, 6.0, 64)
points = torch.stack([torch.zeros(64), torch.zeros(64), depths], dim=1)
observed = torch.tensor([0.9, 0.4, 0.1])
for step in range(200):
density, color = field(points).split([1, 3], dim=1)
# Volume rendering: each sample's opacity times the light that reaches it through the samples in front
alpha = 1 - torch.exp(-nn.functional.softplus(density.squeeze(1)) * (depths[1] - depths[0]))
transmittance = torch.cumprod(torch.cat([torch.ones(1), 1 - alpha[:-1]]), dim=0)
pixel = (transmittance * alpha) @ torch.sigmoid(color)
loss = ((pixel - observed) ** 2).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step in (0, 199):
print(f"step {step}: rendered {pixel.detach().numpy().round(2)}, loss {loss.item():.4f}")step 0: rendered [0.71 0.37 0.56], loss 0.2496과 step 199: rendered [0.9 0.4 0.1], loss 0.0000을 출력합니다. 학습되지 않은 네트워크는 임의의 색상을 렌더링하며, 렌더링 방정식을 거슬러 전달되는 그래디언트가 가중치를 조정해 렌더링된 픽셀이 사진과 일치하게 합니다. 실제 NeRF도 수십 장에서 수백 장의 사진에서 얻은 수백만 개의 광선에 대해 같은 작업을 수행합니다.
초기 NeRF는 NVIDIA V100 GPU에서 장면당 1~2일 동안 학습해야 했고, 이미지를 하나 렌더링할 때마다 네트워크를 1억 5천만~2억 번 쿼리해 프레임당 약 30초가 걸렸습니다. NVIDIA의 Instant NGP는 네트워크 대부분을 학습된 특징의 다중 해상도 해시 테이블로 대체해 학습 시간을 수초에서 수분으로, 1920×1080 해상도의 렌더링 시간을 수십 밀리초로 단축했습니다. 2023년에는 가우시안 스플래팅이 한 단계 더 나아가 장면을 명시적 3D 가우시안 수백만 개로 표현했습니다. 렌더링 시 네트워크를 실행하지 않고도 실시간으로 래스터화할 수 있으며, 같은 방식으로 최적화되므로 일반적으로 뉴럴 렌더링에 포함됩니다.
이미지 공간 뉴럴 렌더링#
두 번째 분야는 기존 렌더러를 유지하면서 네트워크로 출력을 완성하거나 확장합니다. NVIDIA의 DLSS는 게임을 낮은 해상도로 렌더링하고 트랜스포머 모델로 업스케일하며, GeForce RTX 50 시리즈 GPU에서는 게임이 렌더링하는 프레임마다 최대 5개 프레임을 생성합니다. 패스 트레이싱 렌더링에서는 학습된 디노이저가 픽셀당 소수의 광원 샘플에서 깨끗한 이미지를 생성합니다. 다른 모델은 장면 레이아웃에서 이미지를 합성합니다. NVIDIA의 GauGAN은 하늘, 물, 나무의 시맨틱 맵을 사실적인 풍경으로 변환했으며, 뉴럴 아바타 시스템은 새로운 각도나 조명 아래에서 사람의 얼굴을 렌더링합니다.
뉴럴 렌더링과 관련 용어 비교#
- 미분 가능한 렌더링: 입력에 대해 출력의 미분을 계산할 수 있는 렌더러입니다. 뉴럴 렌더링이 이미지에서 학습할 수 있게 하는 메커니즘이며, 예를 들어 메시를 사진에 맞추는 경우처럼 신경망 없이도 사용됩니다.
- 역렌더링: 이미지에서 기하 구조, 재질, 조명을 복원하는 방식으로, 흔히 미분 가능한 렌더링을 사용해 결과를 편집하고 다시 렌더링할 수 있도록 합니다.
- 새로운 시점 합성: 관측되지 않은 시점의 이미지를 생성하는 작업으로, NeRF와 가우시안 스플래팅이 이 작업을 수행합니다. 뉴럴 렌더링은 더 광범위한 기법을 아우릅니다.
- 생성형 AI: 텍스트-이미지 및 비디오 생성 모델은 프롬프트에서 콘텐츠를 생성하며, 일반적으로 선택한 카메라 위치에서 볼 수 있는 명시적 장면 표현은 사용하지 않습니다.
실제 적용 사례#
- 영화 및 버추얼 프로덕션: 캡처한 장소를 래디언스 필드나 스플랫으로 재구성하고, 시각 효과와 프리비주얼라이제이션을 위해 새로운 카메라 경로에서 렌더링합니다.
- 디지털 트윈 및 이커머스: 방, 건물, 제품을 휴대전화로 캡처해 고객과 기획자가 브라우저나 AR 헤드셋에서 살펴볼 수 있는 3D 뷰로 변환합니다.
- 로보틱스 및 자율주행차: 주행 기록을 재구성하고 시점을 이동해 다시 렌더링하여 인식 시스템 테스트용 합성 데이터를 생성합니다. 캡처 도중 움직이는 사람과 차량은 반투명 아티팩트를 남기므로 파이프라인은 학습 사진에서 이들을 마스킹합니다. YOLO26 인스턴스 세그멘테이션 모델은 모든 프레임에서 해당 마스크를 자동으로 생성합니다. Waymo의 Block-NeRF는 개별적으로 학습된 NeRF 그리드를 이어 붙여 이미지 280만 장으로 샌프란시스코의 한 지역 전체를 재구성했습니다.










