Quick Flow
scene render
-> HDR render target
-> post-process passes
-> tone mapping
-> gamma/output transform
-> display| 효과 | 필요한 입력 | 해상도 또는 history |
|---|---|---|
| Bloom | 선형 HDR color, threshold 또는 prefilter | 보통 half/quarter resolution mip chain |
| Tone mapping | 노출이 적용된 HDR color | full resolution, history 없음 |
| Color grading | linear color, LUT | full resolution |
| Depth of field | color, linearized depth, focus 값 | blur 단계는 축소 해상도를 자주 사용 |
| SSAO | depth, normal, projection | temporal filter가 있으면 history 필요 |
| Motion blur / TAA | color, motion vector, depth | reprojection history 필요 |
패스 입출력
후처리는 이미 그려진 장면 이미지를 다시 처리하는 화면 공간 기법입니다. 장면을 바로 화면에 그리지 않고 렌더 타깃에 먼저 저장한 뒤, fullscreen triangle이나 quad를 그리며 fragment shader에서 이미지를 샘플링합니다.
input texture -> post shader -> output render target여러 후처리를 연결하면 pass graph가 됩니다. 각 pass는 입력 texture를 읽고 새 render target에 씁니다. 같은 texture를 동시에 읽고 쓰는 구조는 API와 backend에 따라 feedback loop 또는 정의되지 않은 결과가 될 수 있으므로 피합니다. 필요하면 ping-pong target 또는 별도 resolve target을 둡니다.
Bloom은 밝은 픽셀만 추출해 blur한 뒤 원본에 더합니다. Color grading은 LUT나 색 변환으로 최종 인상을 조정하고, depth of field는 depth를 기준으로 초점 밖 영역을 흐리게 만듭니다.
SSAO는 depth와 normal을 이용해 주변이 막힌 접촉부를 어둡게 하는 화면 공간 visibility 근사입니다. Motion blur는 현재 프레임 색만으로 충분하지 않아 물체나 카메라 움직임을 담은 motion vector가 필요합니다.
HDR와 tone mapping
HDR 렌더 타깃은 1보다 큰 선형 밝기 값을 저장할 수 있습니다. tone mapping은 이 넓은 밝기 범위를 display에 맞는 LDR 범위로 압축합니다. gamma/output 변환은 tone mapping 이후 단계에 위치하는 경우가 많습니다. 같은 bloom 강도라도 HDR prefilter를 linear space가 아닌 이미 인코딩된 색에 적용하면 threshold와 blur의 의미가 달라집니다.
순서와 상태
| 처리 | 일반적 위치 |
|---|---|
| Scene lighting | HDR buffer |
| Bloom extraction | tone mapping 전 |
| Bloom composite | tone mapping 전 또는 정책에 따라 |
| Tone mapping | display 출력 전 |
| Color grading | tone mapping 전후 파이프라인 정책 |
| UI 합성 | 대개 최종 단계 근처 |
후처리는 순서가 결과를 크게 바꿉니다. bloom을 tone mapping 전에 합성하는지, color grading을 어느 색 공간에서 하는지에 따라 밝기와 색이 달라집니다. UI는 보통 tone-mapped scene 뒤에 합성하므로, UI까지 HDR bloom에 넣을지 여부도 의도적으로 정합니다.
HDR scene color
-> exposure
-> bloom extract / downsample / blur / upsample
-> HDR composite
-> tone mapping
-> output transform
-> UI and display targettemporal effect는 color만 history로 저장하지 않습니다. history가 현재 픽셀의 어느 표면에서 왔는지 확인할 depth, normal, motion vector와, camera cut이나 dynamic resolution 변경 뒤 history를 버리는 규칙이 함께 필요합니다. full-resolution texture 한 장의 read와 write가 여럿인 체인이라면 shader ALU보다 bandwidth가 먼저 병목이 될 수 있습니다.
실패 신호
후처리는 전체 화면을 읽고 쓰는 작업이라 bandwidth 비용이 큽니다. full-resolution pass가 많아지면 shader 계산보다 texture read/write가 병목이 될 수 있습니다. 효과를 꺼도 빨라지지 않는다면 해당 pass의 GPU time, target format, load/store, resolve와 memory traffic을 frame capture에서 확인합니다.
| 증상 | 먼저 확인할 항목 |
|---|---|
| bloom이 전 화면에 번짐 | HDR prefilter threshold, exposure 위치, linear sampling |
| 화면이 이중으로 보이거나 flicker | source와 destination이 같은 texture인지, ping-pong 순서 |
| 이동 시 잔상 | motion vector 방향/단위, disocclusion, history reset |
| 색이 탁하거나 과포화됨 | LUT와 tone mapping의 순서, sRGB decode/encode 횟수 |
| 모바일에서 급격히 느려짐 | full-resolution pass 수, HDR format, MSAA resolve, downsample 비율 |
참고 링크
2 sources