通过RaycastHit选择性地应用材料

时间:2018-01-20 19:58:58

标签: c# c unity3d shader

我正在尝试修改旧的Unity脚本Edge Detection,以根据是否正在查看形状边缘来应用轮廓。

到目前为止,我已将EdgeDetection.cs更改为以下代码。这是附加到场景中主摄像机的脚本,除非正在查看某些对象,否则它当前不会渲染任何叠加层。我的问题是当collectionsToShow中的单个对象悬停时,它当前检测到场景中每个对象的边缘。有没有办法将此边缘检测限制为仅覆盖当前集合?

EdgeDetection.cs

using System;
using UnityEngine;

namespace UnityStandardAssets.ImageEffects
{
    [ExecuteInEditMode]
    [RequireComponent (typeof (Camera))]
    [AddComponentMenu ("Image Effects/Edge Detection/Edge Detection")]
    public class EdgeDetection : PostEffectsBase
    {
        public enum EdgeDetectMode
        {
            TriangleDepthNormals = 0,
            RobertsCrossDepthNormals = 1,
            SobelDepth = 2,
            SobelDepthThin = 3,
            TriangleLuminance = 4,
        }

        public GameObject[] collectionsToShow;
        public EdgeDetectMode mode = EdgeDetectMode.SobelDepthThin;
        public float sensitivityDepth = 1.0f;
        public float sensitivityNormals = 1.0f;
        public float lumThreshold = 0.2f;
        public float edgeExp = 1.0f;
        public float sampleDist = 1.0f;
        [Range(0, 1)]
        public float edgesOnly = 0.0f;
        public Color edgesOnlyBgColor = Color.white;

        public Shader edgeDetectShader;
        private Material edgeDetectMaterial = null;
        private EdgeDetectMode oldMode = EdgeDetectMode.SobelDepthThin;
        private int? hitObject;

        public override bool CheckResources()
        {
            CheckSupport (true);

            edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial);
            if (mode != oldMode)
                SetCameraFlag ();

            oldMode = mode;

            if (!isSupported)
                ReportAutoDisable ();
            return isSupported;
        }


        new void Start ()
        {
            oldMode = mode;
        }

        void SetCameraFlag ()
        {
            if (mode == EdgeDetectMode.SobelDepth || mode == EdgeDetectMode.SobelDepthThin)
                GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
            else if (mode == EdgeDetectMode.TriangleDepthNormals || mode == EdgeDetectMode.RobertsCrossDepthNormals)
                GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
        }

        void OnEnable ()
        {
            SetCameraFlag();
        }

        private void LateUpdate()
        {
            hitObject = null;
            Ray ray = new Ray(transform.position, transform.forward);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit, 10))
            {
                for (int i = 0; i < collectionsToShow.Length; i++)
                {
                    if (collectionsToShow[i].transform.childCount == 0)
                    {
                        if (hit.collider == collectionsToShow[i].GetComponent<Collider>())
                        {
                            hitObject = i;
                        }
                    }
                    else
                    {
                        Component[] colliders;
                        colliders = collectionsToShow[i].GetComponentsInChildren(typeof(Collider));

                        foreach (Collider col in colliders)
                        {
                            if (hit.collider == col)
                            {
                                hitObject = i;
                            }
                        }
                    }
                }
            }

            if(hitObject != null)
            {
                //Should it be handled here?
            }
        }

        [ImageEffectOpaque]
        void OnRenderImage (RenderTexture source, RenderTexture destination)
        {
            if(hitObject != null) {
                if (CheckResources() == false)
                {
                    Graphics.Blit(source, destination);
                    return;
                }

                Vector2 sensitivity = new Vector2(sensitivityDepth, sensitivityNormals);
                edgeDetectMaterial.SetVector("_Sensitivity", new Vector4(sensitivity.x, sensitivity.y, 1.0f, sensitivity.y));
                edgeDetectMaterial.SetFloat("_BgFade", edgesOnly);
                edgeDetectMaterial.SetFloat("_SampleDistance", sampleDist);
                edgeDetectMaterial.SetVector("_BgColor", edgesOnlyBgColor);
                edgeDetectMaterial.SetFloat("_Exponent", edgeExp);
                edgeDetectMaterial.SetFloat("_Threshold", lumThreshold);

                Graphics.Blit(source, destination, edgeDetectMaterial, (int)mode);
            } else
            {
                Graphics.Blit(source, destination);
            }
        }
    }
}

来自Legacy Image Effects

的代码不变但必需

PostEffectsBase.cs

using System;
using System.Collections.Generic;
using UnityEngine;

namespace UnityStandardAssets.ImageEffects
{
    [ExecuteInEditMode]
    [RequireComponent (typeof(Camera))]
    public class PostEffectsBase : MonoBehaviour
    {
        protected bool  supportHDRTextures = true;
        protected bool  supportDX11 = false;
        protected bool  isSupported = true;

        private List<Material> createdMaterials = new List<Material> ();

        protected Material CheckShaderAndCreateMaterial ( Shader s, Material m2Create)
        {
            if (!s)
            {
                Debug.Log("Missing shader in " + ToString ());
                enabled = false;
                return null;
            }

            if (s.isSupported && m2Create && m2Create.shader == s)
                return m2Create;

            if (!s.isSupported)
            {
                NotSupported ();
                Debug.Log("The shader " + s.ToString() + " on effect "+ToString()+" is not supported on this platform!");
                return null;
            }

            m2Create = new Material (s);
            createdMaterials.Add (m2Create);
            m2Create.hideFlags = HideFlags.DontSave;

            return m2Create;
        }


        protected Material CreateMaterial (Shader s, Material m2Create)
        {
            if (!s)
            {
                Debug.Log ("Missing shader in " + ToString ());
                return null;
            }

            if (m2Create && (m2Create.shader == s) && (s.isSupported))
                return m2Create;

            if (!s.isSupported)
            {
                return null;
            }

            m2Create = new Material (s);
            createdMaterials.Add (m2Create);
            m2Create.hideFlags = HideFlags.DontSave;

            return m2Create;
        }

        void OnEnable ()
        {
            isSupported = true;
        }

        void OnDestroy ()
        {
            RemoveCreatedMaterials ();    
        }

        private void RemoveCreatedMaterials ()
        {
            while (createdMaterials.Count > 0)
            {
                Material mat = createdMaterials[0];
                createdMaterials.RemoveAt (0);
#if UNITY_EDITOR
                DestroyImmediate (mat);
#else
                Destroy(mat);
#endif
            }
        }

        protected bool CheckSupport ()
        {
            return CheckSupport (false);
        }


        public virtual bool CheckResources ()
        {
            Debug.LogWarning ("CheckResources () for " + ToString() + " should be overwritten.");
            return isSupported;
        }


        protected void Start ()
        {
            CheckResources ();
        }

        protected bool CheckSupport (bool needDepth)
        {
            isSupported = true;
            supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf);
            supportDX11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;

            if (!SystemInfo.supportsImageEffects)
            {
                NotSupported ();
                return false;
            }

            if (needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
            {
                NotSupported ();
                return false;
            }

            if (needDepth)
                GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;

            return true;
        }

        protected bool CheckSupport (bool needDepth,  bool needHdr)
        {
            if (!CheckSupport(needDepth))
                return false;

            if (needHdr && !supportHDRTextures)
            {
                NotSupported ();
                return false;
            }

            return true;
        }


        public bool Dx11Support ()
        {
            return supportDX11;
        }


        protected void ReportAutoDisable ()
        {
            Debug.LogWarning ("The image effect " + ToString() + " has been disabled as it's not supported on the current platform.");
        }

        // deprecated but needed for old effects to survive upgrading
        bool CheckShader (Shader s)
        {
            Debug.Log("The shader " + s.ToString () + " on effect "+ ToString () + " is not part of the Unity 3.2+ effects suite anymore. For best performance and quality, please ensure you are using the latest Standard Assets Image Effects (Pro only) package.");
            if (!s.isSupported)
            {
                NotSupported ();
                return false;
            }
            else
            {
                return false;
            }
        }


        protected void NotSupported ()
        {
            enabled = false;
            isSupported = false;
            return;
        }


        protected void DrawBorder (RenderTexture dest, Material material)
        {
            float x1;
            float x2;
            float y1;
            float y2;

            RenderTexture.active = dest;
            bool  invertY = true; // source.texelSize.y < 0.0ff;
            // Set up the simple Matrix
            GL.PushMatrix();
            GL.LoadOrtho();

            for (int i = 0; i < material.passCount; i++)
            {
                material.SetPass(i);

                float y1_; float y2_;
                if (invertY)
                {
                    y1_ = 1.0f; y2_ = 0.0f;
                }
                else
                {
                    y1_ = 0.0f; y2_ = 1.0f;
                }

                // left
                x1 = 0.0f;
                x2 = 0.0f + 1.0f/(dest.width*1.0f);
                y1 = 0.0f;
                y2 = 1.0f;
                GL.Begin(GL.QUADS);

                GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                // right
                x1 = 1.0f - 1.0f/(dest.width*1.0f);
                x2 = 1.0f;
                y1 = 0.0f;
                y2 = 1.0f;

                GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                // top
                x1 = 0.0f;
                x2 = 1.0f;
                y1 = 0.0f;
                y2 = 0.0f + 1.0f/(dest.height*1.0f);

                GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                // bottom
                x1 = 0.0f;
                x2 = 1.0f;
                y1 = 1.0f - 1.0f/(dest.height*1.0f);
                y2 = 1.0f;

                GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                GL.End();
            }

            GL.PopMatrix();
        }
    }
}

EdgeDetectNormals.shader

Shader "Hidden/EdgeDetect" { 
    Properties {
        _MainTex ("Base (RGB)", 2D) = "" {}
    }

    CGINCLUDE

    #include "UnityCG.cginc"

    struct v2f {
        float4 pos : SV_POSITION;
        float2 uv[5] : TEXCOORD0;
    };

    struct v2fd {
        float4 pos : SV_POSITION;
        float2 uv[2] : TEXCOORD0;
    };

    sampler2D _MainTex;
    uniform float4 _MainTex_TexelSize;
    half4 _MainTex_ST;

    sampler2D _CameraDepthNormalsTexture;
    half4 _CameraDepthNormalsTexture_ST;

    sampler2D_float _CameraDepthTexture;
    half4 _CameraDepthTexture_ST;

    uniform half4 _Sensitivity; 
    uniform half4 _BgColor;
    uniform half _BgFade;
    uniform half _SampleDistance;
    uniform float _Exponent;

    uniform float _Threshold;

    struct v2flum {
        float4 pos : SV_POSITION;
        float2 uv[3] : TEXCOORD0;
    };

    v2flum vertLum (appdata_img v)
    {
        v2flum o;
        o.pos = UnityObjectToClipPos(v.vertex);
        float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
        o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
        o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
        o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
        return o;
    }


    fixed4 fragLum (v2flum i) : SV_Target
    {
        fixed4 original = tex2D(_MainTex, i.uv[0]);

        // a very simple cross gradient filter

        half3 p1 = original.rgb;
        half3 p2 = tex2D(_MainTex, i.uv[1]).rgb;
        half3 p3 = tex2D(_MainTex, i.uv[2]).rgb;

        half3 diff = p1 * 2 - p2 - p3;
        half len = dot(diff, diff);
        len = step(len, _Threshold);
        //if(len >= _Threshold)
        //  original.rgb = 0;

        return len * lerp(original, _BgColor, _BgFade);         
    }   

    inline half CheckSame (half2 centerNormal, float centerDepth, half4 theSample)
    {
        // difference in normals
        // do not bother decoding normals - there's no need here
        half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
        int isSameNormal = (diff.x + diff.y) * _Sensitivity.y < 0.1;
        // difference in depth
        float sampleDepth = DecodeFloatRG (theSample.zw);
        float zdiff = abs(centerDepth-sampleDepth);
        // scale the required threshold by the distance
        int isSameDepth = zdiff * _Sensitivity.x < 0.09 * centerDepth;

        // return:
        // 1 - if normals and depth are similar enough
        // 0 - otherwise

        return isSameNormal * isSameDepth ? 1.0 : 0.0;
    }   

    v2f vertRobert( appdata_img v ) 
    {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);

        float2 uv = v.texcoord.xy;
        o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);

        #if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
            uv.y = 1-uv.y;
        #endif

        // calc coord for the X pattern
        // maybe nicer TODO for the future: 'rotated triangles'

        o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance, _MainTex_ST);
        o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance, _MainTex_ST);
        o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance, _MainTex_ST);
        o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1,-1) * _SampleDistance, _MainTex_ST);

        return o;
    } 

    v2f vertThin( appdata_img v )
    {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);

        float2 uv = v.texcoord.xy;
        o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);

        #if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
            uv.y = 1-uv.y;
        #endif

        o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
        o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);

        // offsets for two additional samples
        o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
        o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);

        return o;
    }     

    v2fd vertD( appdata_img v )
    {
        v2fd o;
        o.pos = UnityObjectToClipPos(v.vertex);

        float2 uv = v.texcoord.xy;
        o.uv[0] = uv;

        #if UNITY_UV_STARTS_AT_TOP
        if (_MainTex_TexelSize.y < 0)
            uv.y = 1-uv.y;
        #endif

        o.uv[1] = uv;

        return o;
    }

    float4 fragDCheap(v2fd i) : SV_Target 
    {   
        // inspired by borderlands implementation of popular "sobel filter"

        float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
        float4 depthsDiag;
        float4 depthsAxis;

        float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;

        depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist, _CameraDepthTexture_ST))); // TR
        depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(-1,1), _CameraDepthTexture_ST))); // TL
        depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(-1,1), _CameraDepthTexture_ST))); // BR
        depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist, _CameraDepthTexture_ST))); // BL

        depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(0,1), _CameraDepthTexture_ST))); // T
        depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(1,0), _CameraDepthTexture_ST))); // L
        depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(1,0), _CameraDepthTexture_ST))); // R
        depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(0,1), _CameraDepthTexture_ST))); // B

        depthsDiag -= centerDepth;
        depthsAxis /= centerDepth;

        const float4 HorizDiagCoeff = float4(1,1,-1,-1);
        const float4 VertDiagCoeff = float4(-1,1,-1,1);
        const float4 HorizAxisCoeff = float4(1,0,0,-1);
        const float4 VertAxisCoeff = float4(0,1,-1,0);

        float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
        float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;

        float SobelX = dot(SobelH, float4(1,1,1,1));
        float SobelY = dot(SobelV, float4(1,1,1,1));
        float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);

        Sobel = 1.0-pow(saturate(Sobel), _Exponent);
        return Sobel * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), _BgColor, _BgFade);
    }

    // pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
    //  which makes it compatible with other depth based post fx

    float4 fragD(v2fd i) : SV_Target 
    {   
        // inspired by borderlands implementation of popular "sobel filter"

        float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1], _CameraDepthTexture_ST)));
        float4 depthsDiag;
        float4 depthsAxis;

        float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;

        depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist, _CameraDepthTexture_ST))); // TR
        depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(-1,1), _CameraDepthTexture_ST))); // TL
        depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(-1,1), _CameraDepthTexture_ST))); // BR
        depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist, _CameraDepthTexture_ST))); // BL

        depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(0,1), _CameraDepthTexture_ST))); // T
        depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(1,0), _CameraDepthTexture_ST))); // L
        depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(1,0), _CameraDepthTexture_ST))); // R
        depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(0,1), _CameraDepthTexture_ST))); // B

        // make it work nicely with depth based image effects such as depth of field:
        depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
        depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;

        depthsDiag -= centerDepth;
        depthsAxis /= centerDepth;

        const float4 HorizDiagCoeff = float4(1,1,-1,-1);
        const float4 VertDiagCoeff = float4(-1,1,-1,1);
        const float4 HorizAxisCoeff = float4(1,0,0,-1);
        const float4 VertAxisCoeff = float4(0,1,-1,0);

        float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
        float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;

        float SobelX = dot(SobelH, float4(1,1,1,1));
        float SobelY = dot(SobelV, float4(1,1,1,1));
        float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);

        Sobel = 1.0-pow(saturate(Sobel), _Exponent);
        return Sobel * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), _BgColor, _BgFade);
    }

    half4 fragRobert(v2f i) : SV_Target {               
        half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
        half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
        half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
        half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);

        half edge = 1.0;

        edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
        edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);

        return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
    }

    half4 fragThin (v2f i) : SV_Target
    {
        half4 original = tex2D(_MainTex, i.uv[0]);

        half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
        half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
        half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[3]);

        // encoded normal
        half2 centerNormal = center.xy;
        // decoded depth
        float centerDepth = DecodeFloatRG (center.zw);

        half edge = 1.0;

        edge *= CheckSame(centerNormal, centerDepth, sample1);
        edge *= CheckSame(centerNormal, centerDepth, sample2);

        return edge * lerp(original, _BgColor, _BgFade);
    }

    ENDCG 

Subshader {
 Pass {
      ZTest Always Cull Off ZWrite Off

      CGPROGRAM
      #pragma vertex vertThin
      #pragma fragment fragThin
      ENDCG
  }
 Pass {
      ZTest Always Cull Off ZWrite Off

      CGPROGRAM
      #pragma vertex vertRobert
      #pragma fragment fragRobert
      ENDCG
  }
 Pass {
      ZTest Always Cull Off ZWrite Off

      CGPROGRAM
      #pragma target 3.0   
      #pragma vertex vertD
      #pragma fragment fragDCheap
      ENDCG
  }
 Pass {
      ZTest Always Cull Off ZWrite Off

      CGPROGRAM
      #pragma target 3.0   
      #pragma vertex vertD
      #pragma fragment fragD
      ENDCG
  }
 Pass {
      ZTest Always Cull Off ZWrite Off

      CGPROGRAM
      #pragma target 3.0   
      #pragma vertex vertLum
      #pragma fragment fragLum
      ENDCG
  }
}

Fallback off

} // shader

Sample scene download

0 个答案:

没有答案