스토리지

[5.8] 토요일 Shader 연습 본문

Unity/Shader

[5.8] 토요일 Shader 연습

ljw4104 2021. 5. 8. 16:56

1. 불 Shader

Fire.shader

Shader "Custom/Fire"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _SubTex ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }

        CGPROGRAM
        #pragma surface surf Standard alpha:fade

        sampler2D _MainTex;
        sampler2D _SubTex;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_SubTex;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 d = tex2D (_SubTex, float2(IN.uv_SubTex.x, IN.uv_SubTex.y - _Time.y));
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex + d.r);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
  • 서브 텍스쳐를 먼저 선언 후 위로 이동하는 Animation 부착
  • 메인 텍스쳐의 UV좌표에 서브 텍스쳐의 R값만큼 더하기

2. Vertex Color에 기반한 Texture 삽입

결과 및 그에따른 Vertex 색상

Shader "Custom/Vertex"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _SubTex1 ("Albedo (RGB)", 2D) = "white" {}
        _SubTex2 ("Albedo (RGB)", 2D) = "white" {}
        _SubTex3 ("Albedo (RGB)", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        sampler2D _MainTex;
        sampler2D _SubTex1;
        sampler2D _SubTex2;
        sampler2D _SubTex3;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_SubTex1;
            float2 uv_SubTex2;
            float2 uv_SubTex3;
            float4 color:COLOR;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D (_SubTex1, IN.uv_SubTex1);
            fixed4 e = tex2D (_SubTex2, IN.uv_SubTex2);
            fixed4 f = tex2D (_SubTex3, IN.uv_SubTex3);

            o.Albedo = lerp(c.rgb, d.rgb, IN.color.r);
            o.Albedo = lerp(o.Albedo, e.rgb, IN.color.g);
            o.Albedo = lerp(o.Albedo, f.rgb, IN.color.b);
            // o.Albedo = IN.color.rgb;         //Vertex 색상 확인할 때
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
  • Input 구조체에 float4 color:COLOR 선언하기
  • R 영역 이외의 부분과 합칠경우(G, B), lerp를 o.Albedo와 섞을 텍스쳐로 하기.

2-1. 바위에 Vertex Color 적용하기

Shader "Custom/VertexRock"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpTex ("Bump Texture", 2D) = "bump" {}
        _SubTex1 ("Sub Tex", 2D) = "white" {}
        _SubTex2 ("Sub Tex", 2D) = "white" {}
        _SubTex3 ("Sub Tex", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _MainTex;
        sampler2D _BumpTex;
        sampler2D _SubTex1;
        sampler2D _SubTex2;
        sampler2D _SubTex3;

        struct Input
        {
            float2 uv_MainTex;
            float2 uv_BumpTex;
            float2 uv_SubTex1;
            float2 uv_SubTex2;
            float2 uv_SubTex3;
            float4 color:COLOR;
        };

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
            fixed4 d = tex2D (_SubTex1, IN.uv_SubTex1);
            fixed4 e = tex2D (_SubTex2, IN.uv_SubTex2);
            fixed4 f = tex2D (_SubTex3, IN.uv_SubTex3);

            o.Albedo = lerp(c.rgb, d.rgb, IN.color.r);
            o.Albedo = lerp(o.Albedo, e.rgb, IN.color.g);
            o.Albedo = lerp(o.Albedo, f.rgb, IN.color.b);
            o.Normal = UnpackNormal(tex2D(_BumpTex, IN.uv_BumpTex));
            //o.Albedo = IN.color.rgb;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}
  • #pragma target 3.0 을 붙이지 않으면 너무 많은 텍스쳐가 있다고 에러를 발생시킨다.

 

 

3. HOLOGRAM

3-1 . 기본적인 Hologram 출력 ( Animation X )

Shader "Custom/Hologram"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _RimPower ("Rim Power", Float) = 3
        _Color ("Hologram Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

        sampler2D _MainTex;
        float _RimPower;
        float4 _Color;

        struct Input
        {
            float2 uv_MainTex;
            float3 viewDir;
        };

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

            o.Emission = _Color.rgb;
            float rim = dot(o.Normal, IN.viewDir);
            o.Alpha = pow(1 - rim, _RimPower);
        }
        ENDCG
    }
    FallBack "Diffuse"
}
  • Tags 및 속성(#pragma)에서 투명화 시키기
  • Lambert로 빛 바꾸기
  • 역광 구하기 : 지면벡터(o.Normal)카메라벡터(IN.viewDir)의 내적값을 Alpha값에 대입 ( ∵ 1에서 뺀 이유는 '역광'이기 때문에 )
    • float rim = dot(o.Normal, IN.viewDir) // o.Alpha = pow(1 - rim, _RimPower);
      • IN.viewDir(카메라벡터, 시선벡터는) Input 구조체 안에있다. 선언해주어야한다.
      • _RimPower는 역광의 정도를 표시한다. 수치를 높일수록 옅어진다.

 

3-2. Animation 및 각종 속성 추가

각각 worldPos.r,g,b 방향으로 홀로그램을 적용시킨 결과
모든 방향으로 값을 적용시킨 결과. 색이 반전되는 결과가 있어서 Lerp로 조절해주었다.

(해당 shader script는 마지막 홀로그램인 노란색,모든방향 홀로그램에 적용됨)

Shader "Custom/Hologram"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpTex ("Albedo (RGB)", 2D) = "bump" {}
        _RimPower ("Rim Power", Float) = 3
        _Density ("Density", Float) = 5
        _Speed ("Speed", Float) = 10
        _Thickness ("Thickness", Float) = 5
        _Color ("Hologram Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }

        CGPROGRAM
        #pragma surface surf Lambert alpha:fade

        sampler2D _MainTex;
        sampler2D _BumpTex;
        float _RimPower;
        float _Density;
        float _Speed;
        float _Thickness;
        float4 _Color;

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

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

            o.Emission = _Color.rgb;

            float rim = dot(o.Normal, IN.viewDir);
            rim = pow(1 - rim, _RimPower);
            float anim1 = pow(frac(IN.worldPos.g * _Density - _Time.y * _Speed), _Thickness);
            float anim2 = pow(frac(IN.worldPos.r * _Density - _Time.y * _Speed), _Thickness);
            float anim3 = pow(frac(IN.worldPos.b * _Density - _Time.y * _Speed), _Thickness);

            o.Alpha = lerp(rim + anim1 + anim2 + anim3, rim, 0.5);
        }
        ENDCG
    }
    FallBack "Diffuse"
}
  • rim은 역광 변수
  • anim은 애니메이션을 월드좌표를 이용해서 삽입하는 변수
  • frac은 소숫점 아래만 반환하는 함수 ex) 1.583739 => 0.583739
  • Alpha값에 Lerp를 사용한 이유는 전 방향과 역광을 더하다보면 반전효과가 모두 겹치는 부분에 나타나서 보정을 해줌.

 

여기까지만 해도 시험통과 ㄱㅇㄷ

'Unity > Shader' 카테고리의 다른 글

[5.10] Alpha Blending  (0) 2021.05.10
[5.10] Cube Map 연습  (0) 2021.05.10
[5.7] CubeMap  (0) 2021.05.07
[5.7] Warped Diffuse  (0) 2021.05.07
[5.7] 밝기에 따른 영역 나누기  (0) 2021.05.07
Comments