개인적으로 공부한 내용을 작성한 것으로 틀린 부분이 있을 수 있습니다.
혹 틀린 부분이 있다면 말씀해주시면 감사하겠습니다.🙏
현재 일반적인 디스플레이는 한 픽셀당 24bit를 사용한다(R,G,B 각각 8bit씩). 즉 R,G,B 각 색상마다 0~255 사이의 값을 갖는다.
이때 위와 같은 그라데이션을 만든다고 생각해보자.
위 이미지에서 색상의 변화를 x, y좌표에 따라 RGB 수치로 나타내보면,
y=0일때 (0, 0, 255), y=255일때 (255, 255, 255)이다. x값은 영향을 주지 않는다(*DirectX에서는 좌표의 시작점이 왼쪽 위이다).
즉 R,G값이 y값에 비례하는 것을 알 수 있다.
// 스캔라인 알고리즘에 의한 렌더링
int RenderScanLine(void)
{
int x, y;
int nBright;
for (y = 0; y < VIEW_HEIGHT; y++) { // y 방향 루프
for (x = 0; x < VIEW_WIDTH; x++) { // x 방향 루프
nBright = y & 0xff; // 밝기가 y 좌표에 연동
DrawPoints(x, y, nBright, nBright, 255); //1픽셀 그리기 함수(x,y,r,g,b)
}
FlushDrawingPictures(); //그리기 대기 행렬 플러시 함수
}
return 0;
}
nBright = y & 0xff;
<- 여기가 핵심 라인이다.
y를 x로 바꾸면 그라데이션이 x값을 따라 그려지게 될 것이다.
0xff(=255)와 AND 연산하는 것은 y값이 255보다 커지더라도 nBright가 색상 표현 범위(0~255)를 넘어가지 않도록 하기 위함이다.
예를 들어 y=256인 경우
0000 0001 0000 0000 (256)
0000 0000 1111 1111 (255)
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ &
0000 0000 0000 0000 (0) 이므로
nBright = 0 이 된다.
그래서 위 이미지에서처럼 점점 흰색이 되다가 중간쯤(256px)부터 다시 완전한 파란색이 되는 것이다.
(*DrawPoints() 와 FlushDrawingPictures() 는 저자가 제공하는 코드에서 정의된 사용자 정의 함수이다.
DrawPoints(): 정점의 좌표와 색상을 XMFLOAT4 형식으로 정점 버퍼에 저장함.
FlushDrawingPictures(): DeviceContext를 통해 화면에 출력하는 함수인 것 같은데, 자세한건 따로 공부해야될듯.)
사선 그라데이션은 이미지처럼 x, y값 모두 밝기에 영향을 미친다.
그리고 x, y값에 따른 가로의 밝기 변화량과 세로의 밝기 변화량이 같으므로, 코드로 작성하면
nBright = (x+y) & 0xff;
와 같다.
이때 '&0xff' 부분을 제외하면 nBright = x+y
인데, 좌변과 우변을 바꾸고 x를 이항하면
y = -x + nBright
즉, 기울기가 -1이고 절편이 nBright인 직선의 방정식이 된다는 것을 알 수 있다!
(*실제 출력된 그라데이션은 기울기가 1인데, 이는 아까도 말했듯 D2D의 좌표계는 y축이 아래를 향하기 때문이다)
이를 응용하여 그라데이션의 기울기를 조정할 수 있다.
또 x와 y에 동일한 값을 곱하거나 나눠줌으로써 기울기는 같되 간격을 달리할 수도 있다.
위의 식을 조금 바꿔서 두 색상이 부드럽게 교차되는 그라데이션을 만든다고 생각해보자.
일단 2번의 이미지와 비교해봤을 때,
기울기는 그대로이고(x+y
), 색상 간격은 2배 가까워졌음을 알 수 있다.(2*(x+y)
)
① 2(x+y) & 0xff
의 이미지와 ② 만들고자 하는 최종 이미지 에서의 밝기 값을 그래프로 나타내면 다음과 같다.
①의 그래프를 ②처럼 만드는 방법을 생각해보자.
0) 2(x+y) & 0xff 의 밝기 값 그래프이다. -> 범위: 0~255
1) 밝기 범위를 0x1ff (=(256*2)-1) 로 설정한다. -> 범위: 0~511
2) 0x1ff의 절반만큼을 마이너스한다. -> 범위: -255~256
3) 절댓값을 취하여 마이너스 영역을 플러스로 반전시킨다. -> 범위: 255~0, 0~256
따라서 최종 이미지의 밝기 값은 nBright = abs(((2*(x+y)) & 0x1ff)-255);
이 된다.
실제 색의 밝기 범위는 255까지이므로 색의 범위가 1만큼 오버되었지만, 지정된 범위를 넘어섰을 경우 최대한 가까운 값의 색으로 조정하기 때문에 255로 조정된다.