Game Dev/Unity Shader

레트로 게임을 스케일링 해주는 xBR 알고리즘 - Unity Shader

Septentrions 2025. 12. 30. 23:30

https://forums.libretro.com/t/xbr-algorithm-tutorial/123

 

xBR algorithm tutorial

This is an old topic I made in another forum. As Retroarch benefits from this filter, I decided to post here too. Sorry if some format are broken.

forums.libretro.com

 

 

 

이전 포스팅에서는 Super Resolution 모델을 이용한 고해상도 기술을 알아보았는데 (Real-ESRGAN)

이번 포스팅은 비 AI Scailing 기술이다.

2011년에 개발자가 공개한 알고리즘인데, 지금도 쓰이는 것 같아서 한번 분석해보았다.

업그레이드 된 버전들도 있는것 같은데, 차차 알아보려고 한다.

 

(1) Introduction

이 필터는 Edge를 감지하고, Edge 사이의 픽셀들을 보간한다.

이미지 픽셀 영역에서 Edge는 매우 분별있는 픽셀이다. (High Color Frequency)

그리고 수직인 방향으로는 매우 유사하다. (Low Color Frequency)

이 필터는 기본적으로 2개의 모듈로 구분했다.

- Edge Detection Rule

- Interpolation Rule

 

(2) Edge Detection Rule (EDR)

E 에 해당하는 픽셀과 그 주변의 픽셀들 (neighbors)이 있다고 가정하자.

- set "E"

- set "Neighbors"

 

EDR 을 적용하기 전에 알아둬야 할 사실이 있다.

E를 기준으로 주변 픽셀들은 4면의 Edge로 이루어져있다.

즉, 1면의 Edge에 적용되는 법칙들은 다른 3면의 Edge에도 똑같이 적용된다.

(A, A1, A0, B, B1, D0, D 에 적용될 룰은 다른 면에도 똑같이 적용된다.)

 

일단, H랑 F 가 Edge라면? E는 보간될 것이 틀림없다.

아니면? E랑 I를 따라 경계가 형성되므로, E는 보간할 필요가 없다.

이유는 다음 이미지를 보면서 이해할 수 있다.

픽셀 사이에 Weighted Distance (붉은 선) 들이 우측의 푸른 선들보다 작다면,

경계가 H-F 방향에 있다는 걸 알 수 있다.

(2) Interpolation Rules (IRs)

이제 E 픽셀 하나에 대하여 어떻게 보간될 것인지 보자.

(2-1) Interpolation Level 1

이 보간 방법은 가장 간단하고 45도 대각선에서만 적용할 수 있다.

푸른색 선 영역이 변경되어야 한다.

이 파란색 영역은 F랑 H 영역의 중앙까지 이어진다.

이 때, 색상은 F나 H중 하나가 될 것이다.

색상을 결정하는 수식은 다음과 같다. 이번에도 distance를 이용하는 것.

EDR이 True 라면, 새로운 색상이 F나 H로 변경될 것이다.

만약 E 같은 픽셀의 영역이 Scale Factor가 적용된다면, 경우에 따라 여러 색상이 공존할 가능성이 있다.

이럴 때는 F와 H의 색상을 Blend 해야 한다.

2x일 경우, Shader에서는 mix(newColor, E, 0.5)를 사용한다.

 

(2-2) Interpolation Level 2

 

색상 변경 수식은 Level1 과 같지만, 영역의 차이점이 존재한다.

이런 형태의 인터폴레이션이 진행되려면, 다음 2가지 조건중 하나를 만족해야한다.

이 2가지 조건들은 서로 독립적이다.

한쪽 영역만 만족하면, 한쪽 영역에 대하여 보간을 하면 되지만, 둘 다 만족한다면 두 영역에 대한 교집합에 대하여 보간해야 한다.

Level2 조건이 만족된다면 Level1 조건도 만족되어진다.

그러므로 Level 2를 먼저 체크해야 한다.

 

(3) 번외

- Distance Function

Distance는 YUV 필터를 통해서 구해진다. 색상 값의 차이를 distance로 사용한 것 같다.

 

사실 바로 이해되지 않았다.

Distance Function을 보고나서야 그나마..