Post Processing Stack과 윤곽 셰이더를 함께 사용하여 윤곽을 빛냅니다 (2)

3295 단어 ShaderUnity
지난번 은 화면 전체에 윤곽을 적용했지만 이번에는 모델 단독에 적용해 보겠습니다.


Shader "Custom/ModelEdgeEmitShader" {
    Properties {
        [HDR] _Color ("Emission Color", Color) = (2,2,2)
        _EdgeWidth ("Edge Width", Range(0, 10)) = 1
        _Sensitivity ("Depth Sensitivity", Range(0, 100)) = 1
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent+100"}
        LOD 200
        ZTest LEqual Cull Back ZWrite Off

        CGPROGRAM
        #include "UnityCG.cginc"
        #pragma surface surf Standard fullforwardshadows alpha
        #pragma target 3.0

        struct Input {
            float4 screenPos;
        };

//      sampler2D_float _CameraDepthTexture;
    sampler2D_float _LastCameraDepthTexture;
        float4 _Color;
        float _EdgeWidth;
        float _Sensitivity;

        UNITY_INSTANCING_BUFFER_START(Props)
        // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        float edgeCheck(float2 i_uv){
            float2 txSize = 1/_ScreenParams.xy*_EdgeWidth;
            float2 base_uv = i_uv - txSize*0.5;
            float2 uv0 = base_uv;
            float2 uv1 = base_uv + txSize.xy;
            float2 uv2 = base_uv + float2(txSize.x, 0);
            float2 uv3 = base_uv + float2(0, txSize.y);

            // Convert to linear depth values.
            float z0 = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_LastCameraDepthTexture, uv0));
            float z1 = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_LastCameraDepthTexture, uv1));
            float z2 = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_LastCameraDepthTexture, uv2));
            float z3 = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_LastCameraDepthTexture, uv3));

            // Roberts cross operator
            float zg1 = z1 - z0;
            float zg2 = z3 - z2;
            return saturate(sqrt(zg1 * zg1 + zg2 * zg2)*_Sensitivity);
        }

        void surf (Input IN, inout SurfaceOutputStandard o) {
            float2 uv0 = IN.screenPos.xy / IN.screenPos.w;
            uv0.x *= _ScreenParams.w;
            float z0 = edgeCheck(uv0);
            o.Emission = _Color.rgb*z0;
            o.Alpha = z0*_Color.a;
        }
        ENDCG
    }

    Fallback Off
}


위의 셰이더를 사용한 Material을 준비하고 모델의 두 번째 셰이더로 지정합니다.



전회와 같이 Unlit계의 셰이더에는 효과가 없습니다.
또한 이 방법은 다중 머티리얼을 사용하는 모델에는 사용할 수 없습니다.

모델내에서 완결하는 쉐이더로 엣지를 내는 경우, 엣지는 모델내측에 내게 되므로, 얇은 부분이 많은 모델에는 그다지 적합하지 않습니다. 그 경우는 viewDir 및 worldNormal 을 사용한 림 조명 을 병용해도 좋을지도 모릅니다.

좋은 웹페이지 즐겨찾기