하라는 일은 안 하고 멍 때리고 김도님 방송 보다가 보라는 게임은 안 보고 직업병인지 배경의 비 때문에 빛이 굴절되어 보이는 효과는 어떻게 만들었을까 혼자 막 생각하다가 비슷하게 만들어보고 싶어서 생각나는 데로 만들기 시작했습니다.
처음에는 배경만 저런 줄 알았는데 캐릭터와 적(이 맞는지 모르겠지만)들 스프라이트도 저렇게 울렁거리는 걸 보니 필요한 레이어만 따로 떼서 전체 화면을 후처리를 하는 것 같네요. 단순히 효과만 보려는 거라 저렇게까지 할 생각은 없으니 그냥 텍스처 몇 개로 해보기로 합니다. 영상이 계속 움직여서 알아보기 힘든데 한 프레임씩 보면 내리고 있는 비와 울렁거리고 있는 부분은 따로 움직이고 있습니다. 그렇게까지 디테일하게 만들 필요는 없어서 그런 것 같네요. 먼저 울렁이는 효과를 만들어 보기로 합니다.
먼저 쿼드를 하나 만들고 텍스처를 하나 띄우는 간단한 셰이더를 만들었습니다. 영상을 보면 화면을 세로로 잘게 잘라서 살짝 올리고 내리고 이걸 계속하고 있는데 노이즈를 쓴 건지 그래프를 쓴 건지 뭔지는 모르겠는데 귀찮으니(사실 할 줄 몰라서) 그냥 룩업 텍스처로 해서 먼저 화면을 잘라서 올리고 내리고를 해보기로 합니다.

전체가 기본 중간 회색인 이미지를 잘게 부분을 나눈 뒤 밝기를 약간 올리고 내린 텍스처를 만들고 이 색상 값을 기본 텍스처의 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"
}
