Question by
Vusa360 · Jan 31, 2018 at 08:19 PM ·
c#shaderrendertextureedge detection
Selectively apply material via RaycastHit
I am trying to modify the old Unity script Edge Detection to apply an outline to the edges of shapes based on whether or not they are being looked at.
So far I have changed EdgeDetection.cs
to the code below. This is the script that is attached to the main camera in the scene and it currently doesn't render any overlay unless certain objects are being looked at. My problem is it currently detects edges on every object in the scene when a single object in collectionsToShow
is hovered over. Is there any way to restrict this edge detection to only the current collection being hovered over?
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);
}
}
}
}
Unchanged, but required, code from 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
Comment