[ 텍스쳐 한장만 출력하는 쉐이더 만들기]
[ 불필요한 코드 지우기 ]
새로운 Surface Shader를 생성한다 .
_Color / _Methalic / _Glossiness와 기타 주석 , 전처리기등을 지운 텍스쳐만을 출력하는 코드이다 .
위 코드는 앞으로 하게될 작업의 기본적인 코드가 될 것이다 .
[ 텍스쳐 출력 살펴보기 ]
1 . Properties
_MainText ("Alvedo (RGB)",2D)="White"{}
텍스쳐를 입력받는 인터페이스를 만드는 곳이다 . 각 부분을 자세히 뜯어보자면
- _MainTex : 텍스쳐를 입력받는 변수
- "Albedo (RGB)" : 이 부분은 Albedo 텍스쳐를 넣는 곳이고 , 알파를 제외한 RGB 채널만 사용한다는 의미이다 .
- 2D : 해당 인터페이스가 2D 텍스쳐를 입력 받는 부분임을 의미한다 .
- "White"{} : 해당 텍스쳐 인터페이스가 처음 생겼을때 , 흰색 택스쳐가 들어 있다 생각하고 만듬을 의미한다 .
2 . 변수
sampler2D _MainTex;
위의 인터페이스에서 받는 텍스쳐는 다음의 sampler로 받는다.
이때 , 텍스쳐는 uv와 만나 UV좌표와 함께 계산되어 출력되기전까지 메모리에 올라와 있는 텍스쳐일 뿐이다.
UV와 만나 계산되어야 색상(float4)로 표현할 수 있다 .
따라서 현재 텍스쳐는 float4 _MainTex가 아닌 sampler2D로 선언한다 .
3 . Input 구조체
float2 uv_MainTex;
UV는 vertex가 가지고 있다. 직접 만든 인터페이스가 아닌 vertex 내부에 있는것을
엔진에게 내놓으라 명령할때는 Input 구조체 안에 넣어야 한다 .
해당 구조체에는 임의의 변수를 넣을 수 없고 , 정해진 규칙대로 작성해야 한다 .
uv는 u와v 2개의 숫자로 이루어져 있으므로 float2이고 , _MainTex의 uv라는 뜻으로
uv_MainTex처럼 sampler이름 앞에 uv라는 글자를 붙인다 .
4 . surf 함수
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
surf 함수 내부에 텍스쳐를 연산하는 함수인 tex2D를 이용하여 텍스쳐의 컬러를 화면에 출력한다 .
여기서 fixed4는 float4보다 훨씬 작은 크기단위이다 . float은 하나에 32비트 영역을 가지는데 컬러를 담기에는 너무 크다 .
float의 1/2인 half (16비트) 혹은 fixed (11비트)가 필요에 따라 쓰인다 .
게임에 사용되는 대부분의 텍스쳐 컬러는 채널당 8비트 이하이므로 fixed로도 충분하기에 fixed를 사용한다.
이때 , uv_MainTex는 In put구조체 IN에 들어가 있기에 IN.uv_MainTex라 사용함을 주의하자 .
프로퍼티에 텍스쳐를 넣어보자
다음과 같이 출력됨을 볼 수 있다 .
[ 이미지 흑백으로 만들기 ]
[ 흑백처리 ]
새로운 Surface Shader를 생성한다 .
그림자 관련된 구문인 fullforwardshadows를 삭제해준다 .
해당 구문이 있다면 , 해당 쉐이더를 사용한 오브젝트는 포워드 렌더링 상태일때 ,
모든 라이트에게서 그림자를 생성한다.
삭제시 가장 가벼운 라이트인 디텍셔널 라이트에게서만 그림자를 생성, 포인트/스폿 라이트는 그림자를 생성 안한다 .
surf 함수의 Albedo를 다음과 같이 작성한다 .
흑백이미지는 두가지 속성을 가지고 있는데
- RGB모두 동일한 숫자로 이루어져 있다 .
- RGB 각 요소에 따른 강도의 평균이다 .
위를 생각하면 코드를 이해 할 수 있을 것이다 .
위 방식은 기본적이고 간단한 GrayScale 구현 방식이다 .
다음과 같이 흑백 이미지가 출력된다 .
[ RGB to YIQ 변환 매트릭스 ]
RGB to YIQ 변환 매트릭스를 활용한 다음의 공식도 가능하다 .
GrayScale= 0.2989 * R + 0.5870 * G + 0.1140* B
RGB 이미지를 Grayscale로 변환하는 함수 만들기.
[ Lerp 함수 사용해보기 ]
[ Lerp ]
직선적인 비율로 값이 변화되는 것을 의미한다 .
lerp(X,Y,S)
선형보간 (Lerp) 함수는 다음과 같이 사용된다 .
x,y는 같은 단위이어야 하고 , s는 float 이어야 한다 . s값이 0에 가까우면 X로 , s값이 1에 가까우면 Y로 출력된다 .
[ 사용해보기 ]
일단 텍스쳐 한장을 출력하는 쉐이더를 준비한다 .
Standard Asset (지금은 지원중단으로 새로 받을 수는 없다 . 전에 받았다면 여기서 받을 수 있다)
에 있는 풀 이미지를 넣어준다 .
해당 이미지는 알파채널을 가지고 있지만 , 아직 알파채널이 적용되는 쉐이더가
아니므로 해당 효과가 보여지지는 않는다 .
두개의 텍스쳐를 받을수 있게 인터페이스와 변수를 추가해준다 .
두가지 이미지를 넣어준다.
serf 함수에서 Albedo를 받는 부분에 lerp 함수를 사용하자 . 현재 lerp의 마지막 값은 0이다 .
첫번째 텍스쳐가 출력된다 .
1이라면?
두번째 텍스쳐가 출력된다 .
lerp의 마지막 값을 받는 프로퍼티를 생성해서 유니티에서 직접 조절이 가능하다 .
반반 출력이 됨을 볼 수 있다 .
[ 알파채널 적용하기 ]
첫번째 이미지에는 다음과 같이 알파채널이 포함되어 있다 .
검은색은 0 흰색은 1이다 . 중간에 보이는 회색은 0.5 이다 .
그렇다면 상단 lerp의 인자를 해당 이미지의 알파채널로 넣으면 어떨까?
위와 같이 적용해보자 .
위와 같이 적용된다 . 즉 검정 부분은 0이기에 c 이미지에 가깝게 나오고 흰색 부분은 1이기에 d 이미지에
가깝게 나온다 . 이는 두가지 방식으로 해결이 가능하다 .
1 . d와 c의 위치를 바꾼다
1에서 빼준다 .
이러한 결과물을 볼 수 있다 .
'유니티 쉐이더 스타트업' 카테고리의 다른 글
[ 유니티 쉐이더 스타트업 ] 07 . 버텍스 컬러 이용하기 (0) | 2023.08.16 |
---|---|
[ 유니티 쉐이더 스타트업 ] 06 . UV를 이용하는 법 배우기 (0) | 2023.08.10 |
[ 유니티 쉐이더 스타트업 ] 05 - 1 . 기초적인 Surface Shader (0) | 2023.08.02 |
[ 유니티 쉐이더 스타트업 ] 04 . 쉐이더랩에 관하여 (0) | 2023.07.31 |
[ 유니티 쉐이더 스타트업 ] 03 - 2 . 렌더링 파이프 라인 - 레스터라이저와 프래그먼트 셰이더 (0) | 2023.07.24 |