하라는 일은 안 하고 멍 때리고 김도님 방송 보다가 보라는 게임은 안 보고 직업병인지 배경의 비 때문에 빛이 굴절되어 보이는 효과는 어떻게 만들었을까 혼자 막 생각하다가 비슷하게 만들어보고 싶어서 생각나는 데로 만들기 시작했습니다.
처음에는 배경만 저런 줄 알았는데 캐릭터와 적(이 맞는지 모르겠지만)들 스프라이트도 저렇게 울렁거리는 걸 보니 필요한 레이어만 따로 떼서 전체 화면을 후처리를 하는 것 같네요. 단순히 효과만 보려는 거라 저렇게까지 할 생각은 없으니 그냥 텍스처 몇 개로 해보기로 합니다. 영상이 계속 움직여서 알아보기 힘든데 한 프레임씩 보면 내리고 있는 비와 울렁거리고 있는 부분은 따로 움직이고 있습니다. 그렇게까지 디테일하게 만들 필요는 없어서 그런 것 같네요. 먼저 울렁이는 효과를 만들어 보기로 합니다.
먼저 쿼드를 하나 만들고 텍스처를 하나 띄우는 간단한 셰이더를 만들었습니다. 영상을 보면 화면을 세로로 잘게 잘라서 살짝 올리고 내리고 이걸 계속하고 있는데 노이즈를 쓴 건지 그래프를 쓴 건지 뭔지는 모르겠는데 귀찮으니(사실 할 줄 몰라서) 그냥 룩업 텍스처로 해서 먼저 화면을 잘라서 올리고 내리고를 해보기로 합니다.
전체가 기본 중간 회색인 이미지를 잘게 부분을 나눈 뒤 밝기를 약간 올리고 내린 텍스처를 만들고 이 색상 값을 기본 텍스처의 uv의 y 값에 더해 줍니다. 일단 원하는 대로 잘려서 나오는군요. 이걸 이제 혼자 움직이게 해보면 되겠네요.
무식하게 그냥 sin 그래프로 흔들었더니 계속 보고 있으니 너무 어지럽네요. 원본 영상을 찬찬히 보니 무식하게 계속 흔드는 게 아니고 흔들릴 때도 있고 아닐 때도 있고 그렇군요. sin 그래프는 빼고 시간 값하고 룩업 텍스처를 하나 더 추가해서 다시 고쳐 봅니다.
아직 비 텍스처가 없어서 조금 어설퍼 보이기는 하는데 아까보다는 괜찮아졌네요. 이제 비 텍스처를 추가하고 스크롤 시키면 될 것 같습니다.
원본은 바닥에 물이 튀는 파티클도 있고 한데 거기까지는 할 필요가 없을 거 같고 아주 똑같지는 않지만, 간단히 보려고 한 거니 이 정도면 된 것 같네요.
(응용편)
셰이더 전체 코드
shader "newbieCAT/test" { properties{ _MainTex("main texture", 2d) = "white" {} _RainTex("rain texture", 2d) = "white" {} _ShiftTex("shift texture", 2d) = "white" {} _NoiseTex("noise texture", 2d) = "white" {} _RainColour("rain colour", Color) = (0.25, 0.25, 0.25, 1) _RainSpeed("rain speed", float) = 1.0 _ShiftWidth("shift width", float) = 2.0 _ShiftStrength("shift strength", float) = 0.015 _NoisePickSpeedX("noise pick speed x", float) = 5.0 _NoisePickSpeedY("noise pick speed y", float) = 0.5 } subShader{ tags { "RenderType" = "Transparent" "Queue" = "Geometry" "IgnoreProjector" = "True" } pass { CGPROGRAM #include "UnityCG.cginc" #pragma vertex vs #pragma fragment fs sampler2D _MainTex; sampler2D _RainTex; sampler2D _ShiftTex; sampler2D _NoiseTex; float4 _RainColour; float _RainSpeed; float _ShiftWidth; float _ShiftStrength; float _NoisePickSpeedX; float _NoisePickSpeedY; struct appdata { float4 vertex : POSITION; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 texcoord : TEXCOORD0; }; v2f vs(appdata i) { v2f o; o.vertex = UnityObjectToClipPos(i.vertex); o.texcoord = i.texcoord; return o; } fixed4 fs(v2f i) : SV_TARGET { float shift = tex2D(_ShiftTex, i.texcoord * _ShiftWidth).r; float noise = tex2D(_NoiseTex, float2(shift + _Time.x * _NoisePickSpeedX, _Time.x * _NoisePickSpeedY)).r * _ShiftStrength; fixed4 rain = tex2D(_RainTex, float2(i.texcoord.x + sin(_Time.x), i.texcoord.y * 0.5 + _Time.y * _RainSpeed)) * _RainColour; fixed4 main = tex2D(_MainTex, float2(i.texcoord.x, i.texcoord.y + noise)); return main + rain; } ENDCG } } fallBack "Diffuse" }