이번엔 이와 같은 Shader를 만들었기 때문에, 소스를 공개. 해설, 코멘트도 올렸습니다!




원래, 움짤과 같이 파티클이 붕괴하는 것과 같은 연출이 목적이었습니다. 그렇게 때문에, 뚝뚝 아래로 액체가 떨어지는 듯한 베리어 같은 표현으로 했습니다.



참고가 된다면 좋겠군요!




MEMO

-파티클의 감쇠는, 컴포넌트 Aera Effector 2D를 어태치해서 실현하고 있습니다!




소스


Shader "Barrier" { Properties { _Color ("Color", Color) = (1,1,1,1) _DistortionTex ("Disortion Texture(RG)", 2D) = "grey" {} _DistortionPower ("Distortion Power", Range(0, 0.1)) = 0 _width ("Width", Range(0, 0.2)) = 0.05 } SubShader { Tags {"Queue"="Transparent" "RenderType"="Transparent" } GrabPass { "_GrabPassTexture" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" //矩形パルス関数 #define pulse(a, b, x) (step((a),(x)) - step((b),(x))) struct appdata { half4 vertex : POSITION; half4 texcoord : TEXCOORD0; }; struct v2f { half4 vertex : SV_POSITION; half2 uv : TEXCOORD0; half4 grabPos : TEXCOORD1; }; sampler2D _DistortionTex; half4 _DistortionTex_ST; sampler2D _GrabPassTexture; half _DistortionPower; fixed4 _Color; float _width; v2f vert (appdata v) { v2f o = (v2f)0; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _DistortionTex); o.grabPos = ComputeGrabScreenPos(o.vertex); return o; } fixed4 frag (v2f i) : SV_Target { half2 uv = i.grabPos.xy / i.grabPos.w; //歪み用テクスチャをuvスクロール float2 uvTmp = i.uv ; uvTmp.y += _Time.x * 2; //rgは0~1の範囲にあるので、-0.5~0.5にずらす half2 distortion = tex2D(_DistortionTex, uvTmp).rg - 0.5; //歪みの強さ distortion *= _DistortionPower; //円外(uv座標内の半径0.5の外)のピクセルは破棄 float dst = distance(float2(0.5, 0.5), i.uv); if (dst > 0.5) discard; //円の内側の半径 float insideRad = 0.5 - _width; //背面の歪み uv += distortion; fixed4 distortColor = tex2D(_GrabPassTexture, uv)* step(dst,insideRad); //円縁 fixed4 circleOutline = _Color * pulse(insideRad,0.5,dst); return distortColor + circleOutline; } ENDCG } }

}





주요 처리의 흐름


STEP.1

-grapPass로 후면을 취득


STEP.2

-노멀맵으로 후면을 왜곡


STEP.3

-원형틀을 추가하여 완성!




STEP.1 : grapPass로 후면을 취득


일단 grapPass로 후면화면을 취득합니다.

관련 소스는 이하에 쓰여있는 대로입니다.


Tags {"Queue"="Transparent" "RenderType"="Transparent" } GrabPass { "_GrabPassTexture" } Pass { sampler2D _GrabPassTexture;


}


GrabPass {}라고 명기하면, 후면 화면을 얻을 수 있습니다. 다만, 주의할 점도 있는데, Tags{"Queue"="Transparent"}라고 할 필요가 있습니다.


불투명한 모든 오브젝트를 그린 후에 후면을 얻어야하기 때문에, "Queue"="Transparent"로 쓰고 있습니다!



그리고 이하의 소스에서는, 후면 화면의 UV좌표를 얻고 있습니다. 사영 공간에서 텍스쳐 좌표로 변환하는 것입니다. "그러한 것"이라고 이해하면 되겠네요 (웃음)


v2f vert (appdata v) { o.grabPos = ComputeGrabScreenPos(o.vertex); } fixed4 frag (v2f i) : SV_Target { half2 uv = i.grabPos.xy / i.grabPos.w;


}



여기서의 해설은 생략하겠지만, 흥미가 있으신 분은 이쪽의 관련 링크를 체크해주세요!


http://edom18.hateblo.jp/entry/2016/11/28/210605

http://asura.iaigiri.com/OpenGL/gl45.html





STEP2 : 노멀맵으로 후면을 왜곡시키자


다음은 노멀맵의 RG요소로 후면을 왜곡시키겠습니다. 매우 심플합니다! 텍스쳐로 왜곡시키는 이미나 구조는, 제가 기재한 Qiita의 기사를 봐주세요!(https://qiita.com/guru_taka/items/c0292fd25b4e739816b6)



초 간단히 설명하자면, 노멀맵의 울퉁불퉁(RG요소)에 의해, UV좌표가 변화합니다.

그 결과, 후면이 왜곡되듯이 비치는 이미지입니다!


그리고는 UV에 스크롤을 줘서, 노멀맵이 아래를 향해 흐르듯이 했습니다. distortion*=_DistortionPower;는 왜곡의 강함을 나타냅니다. 이런 느낌으로 왜곡 강도가 변화합니다.




이번에 사용한 노말맵은 이쪽입니다.




STEP3 : 원테를 추가해서 완성!


마지막으로, 원테를 추가합니다. 흐름은 이런 느낌!


1. UV좌표계에 반경 0.5이외의 픽셀을 전부 파기

2.원테를 단경 펄스 함수로 작성

3.왜곡 후면과 원테를 더하여 완성!



//1. 円外(uv座標内の半径0.5の外)のピクセルは破棄 float dst = distance(float2(0.5, 0.5), i.uv); if (dst > 0.5) discard; //円の内側の半径 float insideRad = 0.5 - _width; //背面の歪み uv += distortion; fixed4 distortColor = tex2D(_GrabPassTexture, uv)* step(dst,insideRad); //2. 円縁 fixed4 circleOutline = _Color * pulse(insideRad,0.5,dst); //3. 背面+円縁

return distortColor + circleOutline;


단경 펄스 함수는 #define pulse(a, b, x) (step((a), (x)) - step((b), (x))로 정의되고 있습니다.




인용:Shader(HLSL), 手続き的にテクスチャ生成など行うとき使用頻度の高い関数




마지막으로


그리고는, 2D Spirte를 작성하여, 적당한 정방형의 Sprite 이미지를 어태치. 그리고, 상기 shader에 따른 머테리얼을 어태치하면 완성입니다!