0506 쉐이더 Rim Light + Hologram

2021. 5. 6. 15:17unity/쉐이더

역광 Rim Light
프레넬 공식을 이용해서 빛의 반사율을 계산한다.

Shader "Custom/test"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("Normal", 2D) = "bump" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
       
        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpMap;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpMap;
            float3 viewDir;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal=UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Albedo = 0;

            float rim = dot(o.Normal, IN.viewDir);
            o.Albedo = pow(1 - rim, 5);

            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

메터리얼에 일단 블랙을 깔고 Rim 라이트 효과를 준다. 왼쪽은 림 라이트 원본, 오른쪽은 1-로 림 라이트 반전

void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Albedo = 0;

            float ndotv = saturate(dot(o.Normal, IN.viewDir));

            o.Emission = pow(1-ndotv, _RimPower) * _RimColor.rgb;
            o.Alpha = c.a;
        }
        ENDCG

왼쪽: 주변광 효과 킨 것, 오른쪽: 주변광 효과 끈 것

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

        CGPROGRAM
        
        #pragma surface surf Lambert noambient

        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpMap;
        float4 _RimColor;
        float _RimPower;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
            float2 uv_BumpMap;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
            o.Albedo = c.rgb;

            float ndotv = dot(o.Normal, IN.viewDir); //saturate(dot(o.Normal, IN.viewDir));

            o.Emission = pow(1-ndotv, _RimPower) * _RimColor.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 


 

 

Shader "Custom/Holo"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _RimPower("Rim Power",Range(1,10)) = 1
        _HoloColor("Holo Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        LOD 200

        CGPROGRAM
        
        #pragma surface surf Lambert alpha:fade

        #pragma target 3.0

        sampler2D _MainTex;
        float _RimPower;
        float4 _HoloColor;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {

            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = 0;

            float rim = dot(o.Normal, IN.viewDir);
            rim = pow(1 - rim, _RimPower);
            o.Emission = rim*_HoloColor;
            o.Alpha = rim;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

렌더 타입을 Transparent로, 옵션은 alpha : fade로 설정
알파에다 rim 값을 넣어주면 된다.

 

Shader "Custom/Holo"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _RimPower("Rim Power",Range(1,10)) = 1
        _Power("Power",Range(10,100)) = 10          
    }
    SubShader
    {
        //Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        Tags { "RenderType" = "Opaque"}
        LOD 200

        CGPROGRAM

        #pragma surface surf Lambert alpha:fade

        #pragma target 3.0

        sampler2D _MainTex;
        float _RimPower;
        float _Power;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
            float3 worldPos;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

            float rim = dot(o.Normal, IN.viewDir);
            rim = pow(1 - rim, _RimPower);
            o.Emission =pow(frac(IN.worldPos.g*5),_Power);
            o.Alpha = 1;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

worldPos : 월드 포지션에 따라 색상 값이 바뀌는 변수. 각 컬러는 벡터와 똑같이 방향, 속도, 시간을 가지고 있다는 점에서 가져왔다.

 

그린값을 변경하면 가로줄의 갯수가 달라지고
frac에 제곱을 주는 값을 변경하면 색의 그라데이션 값이 변경된다.

 

void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            o.Albedo = float3(0, 1, 0);

            float rim = dot(o.Normal, IN.viewDir);
            rim = pow(1 - rim, _RimPower);
            o.Emission = pow(frac(IN.worldPos.g * _Interval- _Time.y), 10);
            o.Alpha = rim;
        }
        ENDCG

_Interval로 흰줄의 갯수를 조정하고 _RimPower로 투명도를 조정했다.

Shader "Custom/Holo"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _RimPower("Rim Power",Range(1,10)) = 1
        _Power("Power",Range(10,100)) = 10
        _Speed("Speed",Range(1,10)) = 1
        _Interval ("Interval",Range(1,10))=1
    }
    SubShader
    {
        //Tags { "RenderType"="Transparent" "Queue"="Transparent"}
        Tags { "RenderType" = "Opaque"}
        LOD 200

        CGPROGRAM

        #pragma surface surf Lambert alpha:fade

        #pragma target 3.0

        sampler2D _MainTex;
        float _RimPower;
        float _Power;
        float _Speed;
        float _Interval;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
            float3 worldPos;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);

            o.Emission = float3(0, 1, 0);
            float rim = dot(o.Normal, IN.viewDir);

            rim = pow(1 - rim, _RimPower) 
                + pow(frac(IN.worldPos.g * _Interval - (_Time.y * _Speed)), _Power);

            o.Alpha = rim;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 

월드 좌표에서 r=x g=y, b=z이다. 각각 b,r,g값을 넣어보았다.