이번 포스팅은 ScreenPosUV를 응용한 쉐이더 이펙트입니다.

 

 

ScreenPos는 일반적으로 메쉬의 UV정보를 사용하는 것이 아닌 스크린UV를 기반으로 텍셀값을 가져오는 방식으로 

 

위와 같은 결과를 가져옵니다.

 

이를 이용해 코스믹 우주 쉐이더 이펙트를 만들었습니다.

 

 

Shader "JH/Sh_ScreenPos"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
		_BandTex("Band Texture", 2D) = "white" {}
	
		_FresnelMul("FresnelMul", float) = 1
		_FresnelPow("FresnelPow", float) = 1

    }
    SubShader
    {
		Tags { "RenderType" = "Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
           
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
				float3 normal : NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
				half3 worldnormal : TEXCOORD1;
				half3 viewDir : TEXCOORD2;
				float4 screenPosition : TEXCOORD3;
            };

            
			sampler2D _BandTex;
			float4 _BandTex_ST;

			sampler2D _MainTex;
			float4 _MainTex_ST;

			float _FresnelMul;
			float _FresnelPow;

			//! Fresnel 계산 함수
			fixed Fuc_Fresnel(float fNDotV, float fPow)
			{
				float fInverseRim = 1 - abs(fNDotV);
				return saturate((pow(fInverseRim, fPow)));
			}

            v2f vert (appdata v)
            {
                v2f o;
				
                o.vertex = UnityObjectToClipPos(v.vertex);

                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.worldnormal = UnityObjectToWorldNormal(v.normal);	//! WorldNormal 게산
				o.viewDir = normalize(WorldSpaceViewDir(v.vertex));	//! 카메라 벡터 계산
				o.screenPosition = ComputeScreenPos(o.vertex);		//! 스크린 UV 좌표 계산

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				half2 fScreenUV = i.screenPosition.xy / i.screenPosition.w;	//! 카메라 거리(w) 나눠준다
				fixed4 fTexture = tex2D(_MainTex, fScreenUV.rg * 4.0f + float2(_Time.y*0.03f, 0.0f));	//! 우주 텍스처를 스크린UV로 색상값 가져온다

				half fNDotV = dot(i.worldnormal, i.viewDir);		//! Fresnel 계산
				fixed fFresnel = Fuc_Fresnel(fNDotV, _FresnelPow);
				
				half4 fBand = tex2D(_BandTex, fixed2(fFresnel, 0.5f));	//! BandTexture를 FresnelUV로 색상값 가져온다
				half3 fFresnelColor = fBand * fFresnel * _FresnelMul;
		
				float4 fFinalColor = 1;			//! 최종 출력
				fFinalColor.rgb = fFresnelColor + fTexture.rgb;

				return fFinalColor;
            }
            ENDCG
        }
    }
}

WRITTEN BY
CatDarkGame
Technical Artist dhwlgn12@gmail.com

,