(유니티 빌트인 렌더 파이프라인 - Vertex&Fragment 셰이더 사용 / 언리얼 메테리얼 사용)
개요
렌즈 왜곡처럼 중앙을 기준으로 방사형으로 왜곡이 적용되는 셰이더를 만들면 연출에 잘 사용할 수 있을 것 같아, 기대하면서 왜곡 셰이더 만들기를 시작했습니다.
첫 시도
처음에는 UV값을 텍스처를 통해 증감시키기만 하면, 방사형으로 왜곡될 것이라고 생각했었습니다.
UV 좌표 0.5, 0.5를 기준으로 1사분면의 UV엔 텍스처 값을 더해 1시반 방향으로 움직이고, 3사분면의 UV에선 텍스처 값을 빼 7시 반 방향으로 이동하는 식으로요.
그렇게 만들어보니, 렌즈 왜곡이라고 하기에는 묘한 결과물이 나왔습니다.
distance() 를 사용해 왜곡 적용하기
렌즈 왜곡처럼 원형으로 왜곡을 적용하려면 어떻게 해야할까 고민하던 중에, distance() 가 생각났습니다. 중앙을 기준으로 UV에 distance 값을 잘 적용하면 만들어질 것 같아 일단 키보드를 두드리기 시작했습니다.
그러던 도중, UV 자체가 0,0 에서 시작하는 벡터라는 개념이 다시 떠올랐습니다.
벡터(UV)에 스칼라(distance)를 곱할 때 벡터의 방향은 그대로고 벡터의 크기만 바뀌니, 벡터의 시작점을 텍스처의 중앙(UV 0.5, 0.5) 로 보정한 뒤 중앙 기준의 distance 값을 곱연산하면 원형으로 왜곡이 적용될 것입니다.
첫 시도에서는 곱연산 대신에 증감연산을 사용해서 마름모 꼴로 왜곡되었던 것이었구나 라는 작은 깨달음을 얻고, UV에 distance 값을 곱해 원하던 방사형 왜곡을 만들어내는데 성공했습니다.
왜곡 효과를 조금 더 다이나믹하게 넣고 싶은데 어떻게 하면 좋을까 하며 다른 분들은 어떻게 만들었을까 찾아보았습니다. 아래 Shadertoy 코드에서는 distance 값에 pow() 를 적용해서 왜곡 효과를 과장시키더라고요. 바로 pow() 도 추가했습니다.
···
fixed4 col;
float2 uv1 = (i.uv - 0.5) * _Tiling;
float dis = distance(float2(0, 0), uv1) * _Tiling;
// 텍스처 중앙점(원래값 0.5, 0.5)에서 거리 계산
float2 distortedUV = uv1 * pow(dis, _Power);
// pow 적용해 왜곡 강도 조정
uv1 += 0.5;
distortedUV += 0.5;
// UV 이동
float2 finalUV = lerp(uv1, distortedUV, _Value);
return col = tex2D(_MainTex, finalUV);
···
distance()를 통해 원형으로 왜곡 효과를 적용하는 부분의 코드입니다.
텍스처의 중앙 (0.5, 0.5) 을 기준으로 distance()를 통해 거리를 계산하고, 계산한 거리 값을 pow()를 통해 제곱한 뒤 텍스처의 UV로 사용해서 왜곡 효과를 적용했습니다.
텍스처를 사용해 왜곡 적용하기
distance를 사용한 왜곡 효과를 만들고 나서 든 생각은, 첫 시도에서 곱연산을 사용했다면 텍스처를 사용해서도 왜곡 효과를 만들 수 있었겠구나 였습니다.
그리고, 텍스처를 사용하는 게 더 나을 것 같습니다. 아무래도 미리 정의된 텍스처 값을 사용하는게 distance로 매 픽셀마다 거리 계산을 하는 것 보단 값도 싸고, 다른 도형 형태로 왜곡할 때에도 연산을 통해 셰이더에서 도형을 만들어내는 것보다 텍스처로 해당 도형을 정의하는 게 더 간편하기도 하고요.
텍스처를 사용한 왜곡 효과도 만들어 봅시다.
···
fixed4 col;
float2 uv2 = (i.uv - 0.5) * _Tiling;
fixed4 distortionTex = tex2D(_DistortionTex, (i.uv - 0.5) * _DisTexTiling + 0.5); // 왜곡용 텍스처
float2 disTexUV = uv2 * pow(distortionTex.r, _Power) + 0.5;
uv2 += 0.5;
// pow 적용해 왜곡 강도 조정, UV 이동
float2 finalTexUV = lerp(uv2, disTexUV, _Value);
return col = tex2D(_MainTex, finalTexUV);
···
언리얼 메테리얼 노드로는 아래와 같은 모양으로 구성하게 되겠습니다.
(위의 유니티 셰이더 코드와 다르게, 왜곡 적용 방향을 반전시키기 위해 왜곡용 텍스처 옆에 1-x 노드를 추가했습니다.)
하나 만들어두면 두고두고 쓸 만한 왜곡 효과를 만들어보았습니다.
수학의 중요성을 다시금 와닿게 만들어준 작업이 아니었나 싶네요... 😂
최종적으로는 왜곡의 적용 방향 반전 옵션도 토글로 추가해서 작업을 완료했습니다.
유니티 셰이더 코드 전문은 아래 링크에서 확인하실 수 있습니다.
'Graphics' 카테고리의 다른 글
색상 간의 혼합 - 기초 블렌딩 연산 (0) | 2023.10.09 |
---|---|
SDF (Signed Distance Field) (0) | 2023.09.17 |
색체계와 색의 구성요소 (0) | 2023.07.15 |
디지털 색상과 수 (0) | 2023.06.25 |
타일별로 크기 조절이 되는 셰이더 만들기 (0) | 2023.03.30 |