비디오 게임에서 LUT(룩업 테이블)를 쓰는 법
(blog.frost.kiwi)- LUT(룩업 테이블) 는 미리 계산한 값을 표처럼 참조하는 방식으로, 흑백 열화상 영상의 컬러화부터 게임 오브젝트 변형과 영상 색보정까지 폭넓게 쓰임
- WebGL 예제는 비디오 프레임을 GPU에 2D 텍스처로 올린 뒤, 픽셀별 색을 결정하는 Fragment Shader에서 tinting, 1D LUT, 3D LUT를 적용하는 흐름을 보여줌
- 1D LUT 는 밝기값
[0.0 - 1.0]을 색상 배열 좌표로 사용해 흑백 입력을 RGB로 바꾸며, GPU의 쌍선형 필터링으로 작은 LUT도 중간값을 자연스럽게 보간함 - Valve의 Left 4 Dead 사례처럼 tinting과 LUT는 제한된 텍스처 메모리 안에서 자동차, 좀비 피부, 의상 색상 변형을 만드는 데 활용됨
- LUT는 추가 텍스처 읽기 비용을 만들지만, 감마 보정 같은 비싼 계산을 미리 저장하거나 외부 색보정 워크플로를 실시간 그래픽에 가져오는 실용적인 도구임
LUT가 그래픽 프로그래밍에서 하는 일
- 룩업 테이블(LUT)은 값을 미리 계산해 행이나 표에 저장한 뒤 필요할 때 참조하는 방식임
- 그래픽 프로그래밍에서는 이 단순한 구조가 여러 시각 효과로 이어짐
- 흑백 영상을 컬러로 바꿈
- 색상 보정과 스타일링을 적용함
- 비디오 게임에서 오브젝트 변형을 효율적으로 만듦
- 예제는 WebGL을 사용하지만, 같은 기법은 DirectX, OpenGL, Vulkan, Unity, 과학 데이터 시각화에도 적용 가능함
- 데모 영상은 Panasonic GH6와 TESTO 890 열화상 카메라 캡처이며, 처리 과정은 기기 밖으로 나가지 않고 GPU에서 로컬 처리됨
WebGL 파이프라인과 tinting
- 열화상 카메라 출력은 흑백 비디오이며, 각 프레임은 WebGL을 통해 GPU에 2D 텍스처로 전달됨
- Fragment Shader는 출력의 각 fragment에 대해 최종 색상을 결정하는 코드임
- 예제에서는
texture2D(video, tex).rgb로 현재 위치의 비디오 색을 읽음 - WebGL 1.0의 최종 출력은
gl_FragColor에 RGBA로 기록됨
- 예제에서는
- tinting은 텍스처 색상에 특정 색을 곱해 색조를 입히는 방식임
- 예제에서는
videoColor * vec3(1.0, 0.5, 0.0)으로 오렌지색을 곱함 - 흰색은 오렌지색이 되고, 검은색은 0을 곱하므로 검은색으로 남음
- 예제에서는
- 이 문맥에서 tinting의 곱셈 비용은 측정하기 어려울 수 있음
- 텍스처를 메모리에서 가져오는 비용이 곱셈보다 훨씬 큼
- 여러 스레드가 병렬 실행되면서 한 픽셀의 텍스처 읽기를 기다리는 동안 다른 픽셀의 곱셈이 수행될 수 있음
- 이는 tinting이 만드는 차이에 대한 설명이며, 전체 성능 최적화가 끝났다는 뜻은 아님
Valve의 tinting 활용
- Valve Software의 Left 4 Dead는 자동차 변형을 만들기 위해 tinting을 활용함
- 자동차 종류와 색상마다 별도 텍스처를 두는 방식은 텍스처 메모리 예산을 초과할 수 있음
- Valve는 추가 mask 텍스처를 사용해 자동차의 도장 영역을 인스턴스별로 다른 색으로 tinting함
- 한 색상 텍스처가 3개 자동차 모델에서 공유됨
- 두 개의 텍스처 비용으로 4개의 자동차 모델과 사실상 무제한 색상 변형을 만들 수 있음
- Source Engine에서는 자동차뿐 아니라 본질적으로 모든 것을 tinting할 수 있음
1D LUT로 흑백 값을 색상으로 바꾸기
- 1D LUT 는 숫자 배열이며, RGB 이미지라면 색상들의 1차원 배열임
- 흑백 영상의 밝기값을 LUT의 X축 좌표로 사용해 색을 가져옴
- 비디오 밝기값은
[0.0 - 1.0]범위를 가짐 0.0검은색은 LUT 왼쪽 색으로,1.0흰색은 LUT 오른쪽 색으로 매핑됨- 중간값은 대응하는 위치의 색으로 매핑됨
- 비디오 밝기값은
- WebGL 1.0에는 1D 텍스처가 없으므로 높이 1px인 2D 텍스처를 사용함
- 예제 코드는
texture2D(lut, vec2(videoColor, 0.5))형태임 - 입력은 1D 값이고 출력은 RGB이므로 “1D vector in, 3D vector out” 구조임
- 예제 코드는
- GPU의 쌍선형 필터링은 텍스처 읽기 때 중간값을 자동 보간함
- 8비트 흑백 영상은 256단계 밝기를 가짐
- 1D LUT가 32픽셀 폭이어도 픽셀 사이 접근은 선형 보간됨
- 8픽셀 정보만으로도 256픽셀 폭의 다채로운 그라디언트에 가까운 결과를 만들 수 있음
컬러맵 선택과 지각적 균일성
- 예제에는 matplotlib이 지원하는 컬러맵을 1D LUT로 내보낸 목록이 포함됨
- 데이터에 특정 구조가 없다면 지각적으로 균일한 컬러맵을 사용하거나 그에 기반해 색을 설정하는 것이 적합함
- viridis 계열이 대표적인 예임
- 지각적으로 균일한 컬러맵은 흑백으로 출력해도 차가운 부분은 어둡고 뜨거운 부분은 밝게 유지됨
- jet처럼 주로 색상(hue)만 바꾸고 지각 밝기를 무시하는 컬러맵은 이 속성을 보장하지 않음
- 색각 이상이 있는 사람도 데이터를 올바르게 해석할 수 있다는 점이 컬러맵 선택의 중요한 기준임
1D LUT의 성능과 다항식 근사
- 작은 1D LUT의 비용은 대체로 낮을 수 있지만, tinting보다는 고려할 점이 많음
- 주요 성능 우려는 의존적 텍스처 읽기임
- 첫 번째 텍스처 읽기의 결과로 두 번째 텍스처 읽기 좌표를 결정함
- 그래픽 프로그래밍에서는 최적화 가능한 경로 일부를 없앨 수 있는 패턴임
- GPU에는 텍스처 캐시가 있고, 작은 LUT는 캐시에 들어갈 수 있어 LUT 읽기 비용이 매우 낮을 수 있음
- 세밀한 성능 판단에는 플랫폼별 분석 도구가 필요함
- Nvidia NSight는 셰이더 단계별 성능 분석을 제공하지만 OpenGL은 지원하지 않음
- 컬러맵을 다항식 근사로 구현하면 LUT 텍스처를 다루지 않아도 됨
- Matt Zucker의 ShaderToy viridis 근사는 Horner’s method 형태로 작성됨
c0+t*(c1+t*(c2+t*(c3+t*(c4+t*(c5+t*c6)))))형태의 multiply-add 연산으로 색을 계산함- 실제로 LUT보다 빠른지는 플랫폼별 분석 없이는 판단하기 어려움
Left 4 Dead 2의 좀비 변형
- Left 4 Dead 2는 단순 tinting만으로 충분하지 않은 피부와 의상 색상 변형에 LUT를 활용함
- 단순 tinting은 색상의 휘도 다양성을 충분히 제공하지 못할 수 있음
- 피부와 의상에는 몇 개의 LUT를 무작위로 선택해 다양한 색상 변형을 만듦
- 아티스트가 적절한 color ramp를 선택해 최종 게임에 포함함
- 하나의 텍스처에서 밝은 정장과 어두운 정장 변형을 모두 만들 수 있음
- 관련 전체 발표는 GDC의 Shading a Bigger Better Sequel에서 확인할 수 있음
- “Exclusive Masking”은 한 채널 안에 두 텍스처 범위를 넣는 방식임
- Texture 1은 0-128 범위
- Texture 2는 128-256 범위
- 비용은 색 정밀도 감소임
계산을 미리 저장하는 1D LUT
- 1D LUT는 그래픽 프로그래밍에서 비싼 계산 캐시로도 쓰일 수 있음
- Gamma correction은 대표적인 사례임
- 근사가 아니라면
pow()함수가 필요함 - 특히 오래된 GPU에서는
pow()가 비싼 명령일 수 있음 - 표준 sRGB 조각별 곡선을 쓰면 분기 경로도 추가됨
- 근사가 아니라면
- 감마 변환을 1D LUT로 미리 계산하면 픽셀별 계산을 건너뛸 수 있음
- 이 경우 “1D vector in, 1D vector out” 구조임
- 1D LUT는 색상 채널 4개까지 출력할 수 있음
- Redshift는 야간에 모니터를 오렌지색으로 tinting해 눈 피로를 줄이는 소프트웨어 사례임
- 모니터의 Red, Green, Blue 채널별 Gamma Ramp를 바꿈
- Kelvin Warmth → RGB와 추가 Gamma 계산을 3개의 1D LUT로 미리 계산함
- 관련 구현은 Redshift 소스 코드에 있음
- 이 방식은 재매핑이 그래픽 카드가 아니라 모니터에서 이뤄져 성능 영향이 없지만, 하드웨어 인터페이스 지원은 현재 흔들리거나 깨진 경우가 많음
- Raspberry Pi 그래픽 스택은 새 업데이트에서 관련 지원을 잃은 사례가 있음
- Microsoft는 SetDeviceGammaRamp 사용을 경고함
3D LUT: RGB 공간 전체를 다시 매핑하기
- 3D LUT 는 전체 RGB 공간을 하나의 큐브로 표현하고, 모든 가능한 색을 다시 매핑함
- 입력 RGB 3차원 벡터를 출력 RGB 3차원 벡터로 바꾸므로 “3D vector in, 3D vector out” 구조임
- Red, Green, Blue 각각에 1D LUT를 적용하면 색상 균형은 바꿀 수 있음
- 3D LUT는 입력 RGB 조합이 필요한 변환에 필요함
- 채도 변경
- 색상(hue) 변경
- 특정 색상 조정
- 색상 분리
- 3D LUT는 보통 큐브 형태이며, 게임에서는 strip이나 square 형태로 저장되고 영상 편집 도구에서는 “Iridas/Adobe”
.cube파일로 사용됨
WebGL 1.0에서 3D LUT 구현하기
- 예제의 영상은 Panasonic GH6로 촬영한 Panasonic V-Log 색상 프로파일 영상임
- V-Log는 더 많은 다이내믹 레인지를 보존하고 Gamut과 Gamma 정의가 명확한 로그 프로파일임
- WebGL 1.0은 3D 텍스처를 지원하지 않으므로, 3D 텍스처 읽기를 2D 텍스처 읽기 두 번과 보간으로 구현함
- 이 접근은 Gregg Tavares의 Google I/O 2011 발표와 webglfundamentals.org 설명에 기반함
- 기존 예제 코드에는 큐브의 Z축 계산 문제로 색이 파랗게 이동하는 실수가 있었고, 2019년에 수정됨
- WebGL 1.0, OpenGLES 2, OpenGL 2.1에서
OES_texture_3D없이 호환성을 유지하려면 최신 버전의 3D 텍스처 샘플링 코드를 써야 함
3D LUT로 색보정 워크플로 가져오기
- 3D LUT에 적용한 보정은 해당 LUT를 통과하는 영상이나 그래픽 장면에 그대로 적용됨
- 예제에서는 V-Log 영상과 LUT를 DaVinci Resolve에 가져와 처리함
- Panasonic의 V-Log to V-709 3D-LUT를 적용함
- 대비와 white point를 보정해 흰색이 full-bright가 되도록 함
- 보정된 LUT를 다시 내보냄
- 실제 비디오는 원본 그대로이며, 색보정은 WebGL에서 LUT를 통해 실시간으로 적용됨
- 업로드하는 LUT는 같은 크기를 유지해야 함
- 예제 제약은 1024px × 32px
- 32³px 큐브 형태를 유지해야 함
게임 업계의 3D LUT 사용법
- 3D LUT로 게임 색을 외부 도구에서 스타일링하는 방식은 비디오 게임 업계에서 잘 알려진 표준 워크플로임
- 일반적인 절차는 다음과 같음
- 색보정할 장면의 스크린샷을 찍음
- 스크린샷과 초기화된 3D LUT를 Photoshop 같은 도구에서 함께 엶
- 스크린샷과 LUT에 같은 색보정을 적용함
- 3D LUT 부분을 잘라내 내보냄
- Left 4 Dead도 같은 방식을 사용함
- Photoshop의 색보정 도구는 자유롭게 사용할 수 있지만, 여러 픽셀 간 관계를 바꾸는 필터는 사용할 수 없음
- blur, sharpen, emboss 같은 convolution 계열은 remapped color를 흐리게 만들어 예기치 않은 결과를 낼 수 있음
복잡한 색보정을 하나의 LUT로 굽기
- DaVinci Resolve 같은 색보정 도구는 복잡한 색 변환과 color grade를 만들고 3D LUT로 내보낼 수 있음
- 예제는 필름 프린트 룩을 목표로 하는 Kodak 2383 LUT를 적용함
- V-Log gamma 영상을 Cineon Film Log로 변환함
- 색 공간을 Rec.709로 변환함
- 필름 에뮬레이션을 적용하고 gamma를 다시 Rec.709로 변환함
- 마지막으로 white point를 조정함
- 복잡한 세부 변환을 직접 구현하지 않고 하나의 LUT로 구워 그래픽 애플리케이션에 가져올 수 있음
- 예제 영상은 글 호환성을 위해 8비트 고압축 형식이지만, 일반적으로는 10비트 footage에서 수행되는 작업임
- LUT 크기는 생각보다 작게 쓰임
- Panasonic 공식 V-Log to V-709 3D-LUT는 33³px 크기임
- Panasonic의 카메라 내 모니터링 LUT는 17³px를 사용함
- Panasonic의 5자리 달러 가격대 시네마 카메라에서도 17³px가 쓰임
그래픽 밖의 LUT 사례
- LUT는 그래픽 프로그래밍 외에도 쓰임
- Tomb Raider를 Game Boy Advance에 포팅한 사례에서도 LUT가 활용됨
- 오픈소스 OpenLara 엔진 포트는 Game Boy Advance에 3D 기능이 없기 때문에 많은 부분을 소프트웨어로 처리함
- 그중 하나가 정수 나눗셈을 구현하는 LUT임
- 이 LUT는 load instruction을 건너뛰기 위해 ROM 주소 공간의 시작 부분에 배치됨
댓글과 토론
Hacker News 의견들
-
조회 테이블이 아니었으면 이 효과를 아예 구현하지 못했을 것 같음: https://twitter.com/zeta0134/status/1756988843851383181
핵심은 조회 테이블을 두 개 쓴다는 점임. 큰 테이블은 플레이어 주변의 설정 가능한 반지름 안에서 원형 조명 정보를 저장하고, 반지름마다 테이블 하나가 통째로 있음. 두 번째 테이블은 배경 행의 의사 난수 순서를 담음. 횃불 조명 루틴이 호출될 때마다 화면의 1/20만 갱신할 시간밖에 없지만, 순서를 조금 무작위화하면 가장자리가 부드러워 보이고 원래 보일 래스터 스캔을 숨길 수 있음. 이 순서는 행이 갱신에서 굶지 않게 하는 grab bag이라 실시간 계산이 너무 느려서 테이블을 씀- 꽤 멋져 보이고, 기억나는 어떤 NES 게임보다 그래픽이 훨씬 좋아서 SNES 수준 그래픽처럼 보임. 에뮬레이터에서 돌리는 것 같은데, 그 에뮬레이터가 성능을 NES 수준으로 제한하나 궁금함
- 정말 멋진 게임처럼 보임. Crypt of the Necrodancer에서 영감을 받았는지 궁금함. 좋아하는 게임 중 하나임. 그런 메커니즘이 당시 발명됐다면 NES나 다른 구형 콘솔이 어느 정도까지 처리할 수 있었을지 생각해 봤는데, 가능하다는 걸 보여주는 것 같음
- 1/20 갱신이 잘 먹히는 건 램프가 움직일 때 타일이 자연스럽게 드러나는 착시를 주기 때문임. 이런 효과로 넘어갈 수 있다는 게 멋짐
- 같은 콘솔용 게임도 사람들이 코딩법을 익히면서 점점 훨씬 예뻐지는 과정이 늘 흥미로움. 예를 들면 Mario 1과 3, 또는 N64의 두 Zelda 게임이 그렇다
- “행이 갱신에서 굶지 않게 하려고 무작위 순서를 grab bag으로 둔다”는 부분의 검색 키워드는 아마 quasirandom일 것 같음
-
처음으로 정말 인상 깊었던 조회 테이블 효과는 텍스처 터널을 만드는 데 쓰는 방식이었음
화면의 각 픽셀마다 화면 중심으로부터의 각도와 거리를 알 수 있는 조회 테이블을 두고, 그걸로 각 픽셀 위치에 어떤 텍셀을 놓을지 고름. 3D 지오메트리 터널 안을 이동하는 것처럼 보이지만 비용이 매우 낮아서 pico에서도 가능함: https://www.lexaloffle.com/bbs/?pid=63818
처음엔 Stardust가 이 효과를 썼을 거라 생각했는데, 방금 찾아보니 실제로는 배경에 반복되는 6프레임 애니메이션을 재생했을 뿐이었음: https://codetapper.com/amiga/sprite-tricks/stardust/- 색상 팔레트를 조회 테이블로 보면, 팔레트 순환도 아주 흔했고 꽤 관련 있어 보임
- 이 원리를 고급스럽게 쓴 것이 시차 차폐 매핑(POM) 임. 자기 그림자까지 가능함
https://web.engr.oregonstate.edu/~mjb/cs557/Projects/Papers/Parallax_Occlusion_Mapping.pdf - 어떻게 동작하는지 보고 싶으면 데모 아래에 작은 Code ▽ 버튼이 있음
- 특정 경우의 대칭성을 보면 편리한 해법을 찾을 수 있음
-
Wind Waker가 독특한 외형을 만들기 위해 여러 LUT를 쓰는 방식에 대한 영상이 있음. BoTW와 ToTK도 같은 기법을 씀
https://www.youtube.com/watch?v=mnxs6CR6Zrk -
글 작성자임. 질문이 있으면 답할 수 있음
- LUT 활용 예들이 훌륭하고, 이런 내용을 깔끔하게 설명한 글이라 반가움. WebGL을 쓰고 직접 데이터를 올릴 수 있게 한 점도 좋음
다만 LUT를 이용한 색 보정을 소개한 방식은 조금 놀라웠음. 글에서는 L4D2가 쓴 멋진 틈새 해법처럼 보이지만, 실제로는 오래전부터 업계 표준이었고 내가 작업한 모든 게임에서 쓰였음. AAA 게임인 NFS (2015)부터 Lost in Random 같은 큰 인디 게임까지 모두 그랬다 - 글이 좋았고, 마지막 섹션을 조금 보충하고 싶음. Game Boy Advance는 정수 나눗셈을 어느 정도 지원했지만 하드웨어 가속은 아니었음 [1]. LUT 모델은 성능상 이유였을 가능성이 크고, 그 판단은 타당해 보임
[1] https://www.copetti.org/writings/consoles/game-boy-advance/#operating-system - 오타 때문에 다른 플로팅 라이브러리가 있는 줄 알고 한참 혼란스러웠음
“Here is every single colormap that matlibplot supports,...” - 애니메이션 GIF가 너무 많아서 짜증나고 산만함. 2010년대식 재미없는 부머 밈도 없어도 됨. 알록달록한 GIF가 계속 튀어나오니 글을 읽기 불편함
- LUT 활용 예들이 훌륭하고, 이런 내용을 깔끔하게 설명한 글이라 반가움. WebGL을 쓰고 직접 데이터를 올릴 수 있게 한 점도 좋음
-
따분한 비즈니스 프로세스 영역에서도 이게 놀랄 만큼 유용함
조건문으로 가득 찬 코드베이스를 깔끔한 조회 테이블로 단순화할 수 있는 경우가 많음. 단순해 보이는 것도 조회 테이블이 5만 행이 될 수 있어서 항상 떠올리지 못하는 듯함. 최종 사용자에게는 많아 보일 수 있지만 컴퓨터는 별로 신경 쓰지 않음. 게다가 조회 테이블은 반복적이라 보통 관리하기 쉽고, 그렇지 않을 때도 여전히 가치가 있음. 코드 변경 없이 최종 사용자가 설정할 수도 있음. 전반적으로 비즈니스 로직을 코딩할 때 늘 튀어나오는 여러 시나리오에 특히 유용한 개념임- 그렇게 해서 결국 DSL이 생김
- 이중 버퍼링된 조회 테이블이라니!
-
레트로 게임은 테이블을 정말 많이 썼음. 당시에는 메모리 속도가 매우 빨랐고 프로세서는 느렸기 때문에, 가능한 많은 계산을 테이블에 밀어 넣는 게 합리적이었음. 더 영리하게 할수록 더 화려한 게임을 만들 수 있었음
- 항상 그런 건 아니고, 레트로가 어떤 플랫폼을 뜻하느냐에 따라 달라질 듯함. YouTube의 Kaze Emanuar는 N64 개발을 많이 하는데, 최적화 얘기의 절반쯤은 메모리 버스가 온갖 최적화에 어떤 영향을 주는지임. Mario 64에서는 사인 함수용 기존 조회 테이블을 근사식으로 바꿨는데, 근사식이 더 빠르고 충분히 정확했기 때문임. 정확히는 서로 다른 목적을 위한 근사식 두 개였음
그 채널을 좋아함. 자기 모드가 더 빠르게 돌게 하려고 Mario 64 코드 전체를 손봐서 안정적인 60FPS로 만들었음 [0]
[0] https://www.youtube.com/watch?v=t_rzYnXEQlE - 회전 정확도를 360/256도 단위로 제한해서 바이트 하나에 넣고, 그 값을 삼각함수 조회 테이블의 인덱스로 쓰던 시절이 기억남 :)
- 항상 그런 건 아니고, 레트로가 어떤 플랫폼을 뜻하느냐에 따라 달라질 듯함. YouTube의 Kaze Emanuar는 N64 개발을 많이 하는데, 최적화 얘기의 절반쯤은 메모리 버스가 온갖 최적화에 어떤 영향을 주는지임. Mario 64에서는 사인 함수용 기존 조회 테이블을 근사식으로 바꿨는데, 근사식이 더 빠르고 충분히 정확했기 때문임. 정확히는 서로 다른 목적을 위한 근사식 두 개였음
-
LUT를 많이 다룬다면, 고급 색 과학과 변환 작업을 처리하는 Mac 앱을 만들고 있음: https://videovillage.com/lattice
-
예전에 NES 홈브루 씬을 조금 파고들었는데, Bobl이라는 게임에서 시스템이 계산할 수 있는 수준을 훨씬 넘는 놀라운 물리 효과를 봤음. 알고 보니 조회 테이블이었고, 단순한 도구로 아주 복잡한 과정처럼 보이게 만들 수 있다는 걸 깨닫게 됨
https://morphcatgames.itch.io/bobl- 그 효과가 인상적이라는 건 부정하지 않지만, 말한 게 표면 잔물결이나 모세관파라면 1차원 셀룰러 오토마톤을 NES가 실시간으로 계산하기 정말 어려웠을지 궁금함
-
A Podcast Of Unnecessary Detail에서 SNES Doom 포팅과 LUT를 삼각함수에 사용한 방식을 다룬 에피소드를 냈음. SNES에는 그래픽 프로세서가 없었다는 맥락임
https://festivalofthespokennerd.com/podcast/series-3-episode-4/
https://github.com/RandalLinden/DOOM-FX- “SNES에는 그래픽 프로세서가 없었다”는 건 완전히 틀림. NES에도 있었음. SNES의 CPU인 복제 Motorola 65c816 외에도, PPU(picture processing unit)는 CRT TV가 각 스캔라인을 물리적으로 그릴 때 타일 기반 배경과 스프라이트를 내보내는 여러 레이아웃을 제공한 커스텀 칩이었음
배경 회전과 스케일링도 가능했음. Mario Kart를 떠올리면 되는 Mode 7이 그렇고, 여러 게임에서 볼 수 있는 하드웨어 투명도도 지원했음. 게다가 Doom과 Starfox 같은 경우 카트리지에 3D 계산을 처리하는 Super FX 칩이 들어 있었음. 그러니 그 특정 타이틀에서는 사실상 그래픽 프로세서를 두 개 다루고 있었던 셈임
SNES 하드웨어를 훌륭하고도 고통스러울 만큼 자세히 다룬 Retro Game Mechanics Explained 시리즈가 있음:
https://www.youtube.com/watch?v=57ibhDU2SAI&list=PLHQ0utQyFw5KCcj1ljIhExH_lvGwfn6GV&index=1
- “SNES에는 그래픽 프로세서가 없었다”는 건 완전히 틀림. NES에도 있었음. SNES의 CPU인 복제 Motorola 65c816 외에도, PPU(picture processing unit)는 CRT TV가 각 스캔라인을 물리적으로 그릴 때 타일 기반 배경과 스프라이트를 내보내는 여러 레이아웃을 제공한 커스텀 칩이었음
-
떠오르는 내가 쓴 LUT 용도는 대기 산란, 스프라이트 색 입히기, 야간 투시 조준경, FLIR 조준경, 흑백 “비디오 피드” 효과, 글리치 효과, 높이맵 셰이딩, 우주선 배기 플룸의 알파 점 계수, 웹사이트 방문자의 마우스 체류 히트맵, 결정질 효과, 마지막으로 원시 색 공간에서의 후처리 색상화였음
LUT는 이미 알고 있는 값 배열을 시각화한 것이고, 놀랄 만큼 유용함- “스프라이트 색 입히기”라니, 요즘 애들은 팔레트 기반 스프라이트를 다 잊었구나! “팔레트 스왑”이라는 말이 어디서 나왔겠음? ;)
http://www.effectgames.com/demos/canvascycle/
원래 Xbox가 이걸 잘 못했고 Photoshop도 지원하지 않아서 인기가 식었음. 하지만 최신 하드웨어는 AESprite에서 만든 팔레트 스왑을 충분히 처리할 수 있음
- “스프라이트 색 입히기”라니, 요즘 애들은 팔레트 기반 스프라이트를 다 잊었구나! “팔레트 스왑”이라는 말이 어디서 나왔겠음? ;)