LoginSignup
5
1

More than 5 years have passed since last update.

Post Processing Stackと輪郭シェーダー併用で輪郭を光らせる(2)

Last updated at Posted at 2018-01-18

前回はスクリーン全体に対して輪郭を適用していましたが、今回はモデル単体に適用してみます。

スクリーンショット 2018-01-18 10.03.15.png

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を用意し、モデルの2つ目のシェーダーに指定します

スクリーンショット 2018-01-18 10.33.28.png

前回同様Unlit系のシェーダーには効果がありません。
またこの方法は複数マテリアルを使用しているモデルには使用できません。

モデル内で完結するシェーダーでエッジを出す場合、エッジはモデル内側に出すことになるので、細い部分が多いモデルにはあまり向いていません。その場合はviewDirとworldNormalを使ったリムライティングを併用しても良いかもしれません。

5
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1