1. 실행 이미지

 

Shader "Custom/toon" {
    Properties {
        _MainTex("Albedo (RGB)", 2D) = "white" {} // 기본 텍스처
        _Thickness("Thickness", Range(0, 1)) = 0.01 // 외곽선의 두께
        _OutlineColor("Outline Color", Color) = (1,1,1,1) // 외곽선의 색상
        _OutlineTex("Outline Texture", 2D) = "white"{} // 외곽선 텍스처
    }

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

        // 외곽선 렌더링을 위해 프론트 페이스를 컬링(제거)
        Cull Front

        // 첫 번째 패스: 외곽선 렌더링
        CGPROGRAM
        #pragma surface surf _NoLight vertex:vert noshadow noambient // 사용자 정의 서피스 쉐이더 설정
        sampler2D _MainTex; // 기본 텍스처
        sampler2D _OutlineTex; // 외곽선 텍스처
        float _Thickness; // 외곽선 두께
        float4 _OutlineColor; // 외곽선 색상

        // 버텍스 쉐이더 함수: 각 버텍스를 외곽선 두께에 따라 이동시킴
        void vert(inout appdata_full v) {
            v.vertex.xyz = v.vertex.xyz + (v.normal.xyz * _Thickness);
        }

        // 서피스 쉐이더 입력 구조체
        struct Input {
            float4 color : COLOR;
            float2 uv_OutlineTex;
        };

        // 서피스 쉐이더 함수: 외곽선 텍스처를 사용하여 색상과 알파값을 결정
        void surf(Input IN, inout SurfaceOutput o) {
            fixed4 c = tex2D(_OutlineTex, IN.uv_OutlineTex);
            o.Emission = c.rgb + abs(sin(_Time.y)); // 시간에 따라 변하는 발광 효과
            o.Alpha = c.a;
        }

        // 사용자 정의 조명 모델: 라이트 없음
        float4 Lighting_NoLight(SurfaceOutput s, float3 lightDir, float atten) {
            float4 final;
            final.rgb = s.Emission * _OutlineColor;
            final.a = s.Alpha;
            return final;
        }
        ENDCG

        // 외곽선 렌더링 후 뒷면 컬링 복원
        Cull Back

        // 두 번째 패스: 기본 메쉬 렌더링
        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
    }
    // 쉐이더가 지원되지 않는 경우 대체 쉐이더로 "Diffuse" 사용
    FallBack "Diffuse"
}

 

 

1 pass = 외곽선

 

외곽선의 두께 색상을 정의

 

vertex 쉐이더를 사용해 모델의 외곽을 기반으로 각 버텍스를 이동시켜 외곽선을 생성

 

이 때, 외곽선의 발광 효과는 시간에 따라 변한다.

 

o.Emission = c.rgb + abs(sin(_Time.y));

 

수치가 높을수록 깜박이는 주기가 빨라진다.

 


2 pass = 물체

 

기본 메쉬를 렌더링한다.

 

반응형

+ Recent posts