0507 쉐이더 툰 그래픽 만들기

2021. 5. 7. 14:30unity/쉐이더

☆투 패스로 외곽선 만들기

Shader "Custom/toon"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _LineThickness("Line Thickness",Range(0.001,0.01)) = 0.01
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Cull Front

        CGPROGRAM

        #pragma surface surf _NoLight vertex:vert noshadow noambient

        sampler2D _MainTex;
        float _LineThickness;

        void vert(inout appdata_full v) 
        {
            //노말의 방향으로 늘어났다.
            v.vertex.xyz = v.vertex.xyz + v.normal.xyz * _LineThickness;
        }

        struct Input
        {
            float4 color:COLOR;
        };

        void surf(Input IN, inout SurfaceOutput o)
        {
           
        }

        float4 Lighting_NoLight(SurfaceOutput s, float3 lightDir, float atten) 
        {
            //텍스쳐 받는 것 없이 그냥 검은색만 반환
            return float4 (0, 0, 0, 1);
        }
        ENDCG

        Cull Back
    //2pass
    CGPROGRAM
        #pragma surface surf Lambert 

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf(Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
    ENDCG
    }
    FallBack "Diffuse"
}

 

외곽선 색 조정 가능하도록 설정

Shader "Custom/toon"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _LineThickness("Line Thickness",Range(0.001,0.01)) = 0.01
        _LineColor("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Cull Front

        CGPROGRAM

        #pragma surface surf _NoLight vertex:vert noshadow noambient

        sampler2D _MainTex;
        float _LineThickness;
        float4 _LineColor;

        void vert(inout appdata_full v) 
        {
            //노말의 방향으로 늘어났다.
            v.vertex.xyz = v.vertex.xyz + v.normal.xyz * _LineThickness;
        }

        struct Input
        {
            float4 color:COLOR;
        };

        void surf(Input IN, inout SurfaceOutput o)
        {

        }

        float4 Lighting_NoLight(SurfaceOutput s, float3 lightDir, float atten) 
        {
            float4 final;
            final.rgb = _LineColor.rgb;
            final.a = s.Alpha;
            return final;
        }
        ENDCG

 

선에 텍스쳐를 입혀서 애니메이션 적용

Shader "Custom/toon"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _MainTexOutLine("Albedo (RGB)",2D) = "white" {}
        _BumpMap("Bump Map",2D) = "bump"{}
        _LineThickness("Line Thickness",Range(0.001,0.01)) = 0.01
        _LineColor("Color",Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Cull Front

        CGPROGRAM

        #pragma surface surf _NoLight vertex:vert noshadow noambient 

        float _LineThickness;
        float4 _LineColor;
        sampler2D _MainTexOutLine;

        void vert(inout appdata_full v) 
        {
            //노말의 방향으로 늘어났다.
            v.vertex.xyz = v.vertex.xyz + v.normal.xyz * _LineThickness;

        }

        struct Input
        {
            float4 color:COLOR;
            float3 viewDir;
            float3 worldPos;
            float2 uv_MainTexOutLine;

        };

        void surf(Input IN, inout SurfaceOutput o)
        {
            fixed4 c = tex2D(_MainTexOutLine, IN.uv_MainTexOutLine-_Time.y);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

        float4 Lighting_NoLight(SurfaceOutput s, float3 lightDir, float atten) 
        {
            float4 final;
            final.rgb = s.Albedo;
            final.a = s.Alpha;
            return final;
        }
        ENDCG


        Cull Back
    //2pass
    CGPROGRAM
        #pragma surface surf Lambert 

        sampler2D _MainTex;
        sampler2D _BumpMap;

        struct Input
        {
            float2 uv_MainTex;
            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;
            o.Alpha = c.a;
        }
    ENDCG
    }
    FallBack "Diffuse"

 


 

float4 Lighting_Toon(SurfaceOutput s, float3 lightDir, float atten)
        {
            float ndotl = dot(s.Normal, lightDir) * 0.5 + 0.5;
            
            if (ndotl > 0.7)
            {
                ndotl = 1;
            }
            else if(ndotl>0.4)
            {
                ndotl = 0.3;
            }
            else 
            {
                ndotl = 0;
            }
            //ndotl = ndotl * 5;
            //ndotl = ceil(ndotl) / 5;
            return ndotl;
        }

float4 Lighting_Toon(SurfaceOutput s, float3 lightDir, float atten)
        {
            float ndotl = dot(s.Normal, lightDir) * 0.5 + 0.5;
            
            //if (ndotl > 0.7)
            //{
                //ndotl = 1;
            //}
            //else if(ndotl>0.4)
            //{
                //ndotl = 0.3;
            //}
            //else 
            //{
                //ndotl = 0;
            //}
            ndotl = ndotl * 10;
            ndotl = ceil(ndotl) / 10;
            return ndotl;
        }

음영 구역을 선명하게 했다.

 

음영과 아웃라인을 동시에 주었다.

Shader "Custom/toon2"
{
    Properties
    {
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _BumpMap("Normal Map", 2D) = "bump" {}
        _LineThickness("Line Thickness",Range(0.001,0.01)) = 0.01
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Cull Front

        CGPROGRAM

        #pragma surface surf _OutLine vertex:vert noambient
        #pragma target 3.0

        sampler2D _MainTex;
        float _LineThickness;

        void vert(inout appdata_full v)
        {
            v.vertex.xyz = v.vertex.xyz + v.normal.xyz * _LineThickness;
        }

        struct Input
        {
            float4 color:COLOR;
        };

        void surf (Input IN, inout SurfaceOutput o)
        {

        }
        
        float4 Lighting_OutLine(SurfaceOutput s, float3 lightDir, float atten)
        {
            return float4(0,0,0,1);
        }
        ENDCG


        Cull Back

        CGPROGRAM
        #pragma surface surf _Toon noambient

        sampler2D _MainTex;
        sampler2D _BumpMap;

        struct Input
        {
            float2 uv_MainTex;
            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;
            o.Alpha = c.a;
        }

        float4 Lighting_Toon(SurfaceOutput s, float3 lightDir, float atten)
        {
            float ndotl = dot(s.Normal, lightDir) * 0.5 + 0.5;
            ndotl = ndotl * 5;
            //ceil = 반올림
            ndotl = ceil(ndotl) / 5;
            return float4(ndotl * s.Albedo.rgb, 1);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

 


 

☆원 패스로 외곽선 따기

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

        CGPROGRAM
        #pragma surface surf _Toon noambient


        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

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

            o.Alpha = c.a;
        }

        float4 Lighting_Toon (SurfaceOutput s, float3 lightDir, float3 viewDir, float atten)
        {
            float ndotl = dot(s.Normal, lightDir)*0.5+0.5;
            ndotl=ndotl * 5;
            ndotl = ceil(ndotl) / 5;

            //Rim
            //abs = 절대값
            float rim = abs(dot(s.Normal, viewDir));
            if (rim > 0.3) 
            {
                rim = 1;
            }
            else 
            {
                rim = 0;
            }

            float4 final;
            final.rgb = ndotl * s.Albedo*rim;
            final.a = s.Alpha;

            return final;
        }
        ENDCG
    }
    FallBack "Diffuse"
}