재질에 따른 반사양 조절, toon shading

2023. 7. 14. 17:48컴퓨터 그래픽스/HLSL

 앞의 specular, diffuse를 이용하여 빛을 표현했는데 이제는 물체의 재질마다 빛이 정반사, 난반사 하는 양이 다른 것을 생각해봐야 한다.

고려할 것

  • 난반사광이 반사하는 빛, 정반사광이 반사하는 빛의 스펙트럼이 다른 경우
  • 각 픽셀이 반사하는 정반사광의 정도를 조절하는 경우 (ex. 사람의 얼굴)

이때 diffuse map(난반사광에 이용), specular map(정반사광에 이용)을 이용하여 표현합니다.

diffuse map은 실제 물체를 지각할 때는 난반사광으로 인식하므로 diffuse map에는 텍스쳐를 적용하는 것으로 끝난다.

specular는 빛이 나올 곳 안나올 곳을 텍스쳐로 보여준다. 즉 반사하는 정반사광의 양이므로 검은색일 경우 빛을 전혀 반사하지 않는다. 그래서 난반사광으로 표현한 것만 표시하게 된다. 어둡게 표현하고 싶다면 specular map에서 진한 색을 이용하면 된다.

공식 : 난반사양(diffuse) * 빛의 색상 * diffuse map 값
          정반사양(specular) * 빛의 색상 * specular map 값

왼쪽 diffuse, 오른쪽 specular 

셰이더 프로그래밍 입문 책 자료에서 얻은 자료입니다

vertex shader에서는 앞의 diffuse, specular를 나타냈을 때랑 크게 다를 것이 없다. 달라진 것은 texture를 이용해야하므로 texture uv 좌표를 가져와서 fragment shader에 전달해야 한다.

vertex shader의 input에 uv 좌표를 쓰고 output에 mUV 좌표를 넣어서 fragment에 전달한다.

fragment에서는 sampler2D 자료형으로 2d texture들을 받아온다.

그리고 빛의 색을 나타내는 global 변수를 만들어준다.

float4 albedo = tex2D(DiffuseSampler, Input.mUV);를 이용하게 되는데 tex2D는 sampler diffuse 텍스쳐의 input에서 받아온 uv 좌표에서의 texture 한 픽셀(텍셀)을 가져오는 역할을 한다. 텍셀에는 rgba 값이 들어있을 것이다.

specular map 또한 같은 방법으로 가져오고 나서 위의 공식을 이용한다.

결과 사진

toon shading

툰 쉐이딩은 여태까지 현실적으로 표현했던 것들을 좀 더 극적인 표현으로 만화적인 표현을 하는 쉐이딩이다. 여러 가지 방법이 있지만 자연스럽게 cos 곡선으로 나타났던 색을 올림을 이용하여 극적인 표현을 해주는 방법을 해볼 것이다.

툰 쉐이딩에서 일단 난반사를 표현해야한다.

이때 필요한 것은 normal vector이므로 vertex input에 normal을 넣어준다. 그리고 fragment shader에는 diffuse를 전달해야하므로 vertex output에는 diffuse를 추가해준다. diffuse는 normal과 빛의 방향벡터를 내적한 결과이다.

cos에서 음수가 나오면 안되므로 saturate로 범위를 0~1로 바꿔준다. 그리고 이것을 ouput의 diffuse에 넣어준다.

fragment shader에서 diffuse를 ceil 함수로 올림을 해준다. ceil함수는 위의 정수로 올림하는 함수인데, 값을 0.2로 자르려고 한다.

diffuse는 0~ 1사이의 값이고 이것을 5 곱해주면 0 ~ 5 사이의 값이 되고 이 값들을 모두 5로 나누면 0, 0.2, 0.4가 되므로 0.2씩 자르게 되는 것이다. 그러면 여러 색의 층이 생기는 것을 볼 수 있다.

float3 diffuse = ceil(diffuse*5)/5.0f;

'컴퓨터 그래픽스 > HLSL' 카테고리의 다른 글

normal mapping, 환경 mapping  (0) 2023.07.14
조명 셰이더  (0) 2023.04.30
텍스쳐매핑  (0) 2023.04.29
HLSL 원 그리기  (0) 2023.04.29