본문 바로가기
Computer Graphics/ShaderLab, HLSL

[ShaderLab] Cubemap (with MaskMap)

by 진현개발일기 2024. 3. 5.

■ CubeMap

리얼타임으로 반사(Reflection) 렌더링을 하는 것은 매우 무겁다.  그래서 많이 사용하는 방식은 CubeMap(큐브맵)이라는 환경 텍스처를 이용해 주변 이미지를 텍스처로 만든 뒤 오브젝트에 씌우는 것이 있다.

 

먼저 아래와 같이 cubemap을 만들어줬다. 고화질의 텍스처의 설정 모습이다.

위에서 만든 Cubemap을 아래 쉐이더 코드를 작성한 뒤 삽입해주면 된다.

 

 

그러면  해당 쉐이더를 적용받고있는 오브젝트가 마치 skybox의 전경을 반사하고 있는 것처럼 보인다.

여기에 디테일함을 추가하기 위해 노말맵을 추가할려고했다.

 

일반적인 노말 적용 방식으로 하려고한다면 아래와 같이 에러가 검출된다.

 

위와 같은 에러가 발생하는 이유는 Surface Shader의 Input 구조체에 내포되어있는 worldRefl이나 worldNormal같은 애들은 '버텍스 월드 노멀'에 관련된 데이터이다. worldRefl같은 경우 월드 반사 벡터를 포함하고있고, worldNormal은 월드 법선 벡터를 포함하고있다.

 

이렇게 월드좌표계를 기준으로한 벡터들과 UnpackNormal을 통해 탄젠트 노멀이 된 데이터 o.Normal을 같이 사용하려다보니 에러가 뜨는 것이다.

 

* 모든 픽셀이 자신을 중심축으로 한 좌표계를 탄젠트 좌표계라고 한다.

 

그러므로 NormalMap을 사용하기 위해선 NormalMap에 대응되는 반사 벡터가 필요한데 이를 픽셀 월드 노멀로 변경해줘야한다.

 

방법은 간단하다

(1) 사용하고자 하는 버텍스 월드 노멀 데이터 아래에 INTERNAL_DATA를 추가해준다.

(2) o.Normal을 맨위에서 UnpackNormal을 통해 먼저 대입해주고 반사데이터에 대입할 때는 WorldReflectionVector 함수를 사용해야한다.

 

[참고 문서: 링크]

 

위와 같이 코드를 수정해주고 몸, 팔, 다리에 맞는 머테리얼을 각각 캐릭터에 씌워줬다.

노말맵을 추가하니 훨씬 선명해진 것을 확인할 수 있다.

이제 반사100%가 아니라 보여주고자 하는 모델에 반사를 한스푼 추가한 느낌으로 표현하고자 한다.

이럴 때는 Albedo값을 희미하게 설정해주고 반사를 표현하는 Emission에도 reflection의 수치를 희석시켜 대입해줘야한다.

이렇게 한다면 아래와 같이 기존 모델에 반사를 추가한 느낌을 줄 수 있다.

 

하지만, 전체적으로 모두 반사를 받고있다. 반사를 주고싶은 부위만 타겟팅을 하고싶다면 MaskMap을 활용하면 된다.

 

[평범한 MainTexture]

[MaskMap: 표현해주고 싶은 영역은 흰색(1) 그 외 지역은 검은색(0)으로 설정]

 

 

[Maskmap 추가코드]

 

[적용 후]

위와 같이 관절 쪽에만 빛이 반사되는 것을 확인할 수 있다. 개인적으로 얼굴에도 반사를 표현하고싶어서

그림판으로 힘들지만 대충 흰색으로 칠해줬다.

 

 

 

뭔가 낡아서 반사물질이 벗겨진듯한 표현이 되어버렸는데 나쁘지 않은 것 같다. 다음에 사용할 수 있도록 원리만 이해하면 됐다.

 

 

728x90