PostEffectsBase.cs
using UnityEngine; using System.Collections; [ExecuteInEditMode] [RequireComponent (typeof(Camera))] public class PostEffectsBase : MonoBehaviour { // Called when start protected void CheckResources() { bool isSupported = CheckSupport(); if (isSupported == false) { NotSupported(); } } // Called in CheckResources to check support on this platform protected bool CheckSupport() { if (SystemInfo.supportsImageEffects == false || SystemInfo.supportsRenderTextures == false) { Debug.LogWarning("This platform does not support image effects or render textures."); return false; } return true; } // Called when the platform doesn't support this effect protected void NotSupported() { enabled = false; } protected void Start() { CheckResources(); } // Called when need to create the material used by this effect protected Material CheckShaderAndCreateMaterial(Shader shader, Material material) { if (shader == null) { return null; } if (shader.isSupported && material && material.shader == shader) return material; if (!shader.isSupported) { return null; } else { material = new Material(shader); material.hideFlags = HideFlags.DontSave; if (material) return material; else return null; } } }
EdgeDetection.cs
using UnityEngine; using System.Collections; public class EdgeDetection : PostEffectsBase { public Shader edgeDetectShader; private Material edgeDetectMaterial = null; public Material material { get { edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial); return edgeDetectMaterial; } } [Range(0.0f, 1.0f)] public float edgesOnly = 0.0f; public Color edgeColor = Color.black; public Color backgroundColor = Color.white; void OnRenderImage (RenderTexture src, RenderTexture dest) { if (material != null) { material.SetFloat("_EdgeOnly", edgesOnly); material.SetColor("_EdgeColor", edgeColor); material.SetColor("_BackgroundColor", backgroundColor); Graphics.Blit(src, dest, material); } else { Graphics.Blit(src, dest); } } }
内置渲染管线
Shader "SunY/C12-EdgeDetection" { Properties { _MainTex("Main Tex" , 2D) = "white"{} _EdgeOnly("Edge Only", float) = 1 _EdgeColor("Edge Color", Color) = (1, 1, 1, 1) _BackgroundColor("Background Color", Color) = (1, 1, 1, 1) } SubShader { Pass { ZTest Always ZWrite Off Cull Off CGPROGRAM #include "UnityCG.cginc" #pragma vertex vert #pragma fragment frag sampler2D _MainTex; half4 _MainTex_TexelSize; float _EdgeOnly; fixed4 _EdgeColor; fixed4 _BackgroundColor; struct v2f { float4 pos : SV_POSITION; half2 uv[9] : TEXCOORD0; }; v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); half2 uv = v.texcoord; // 顶点着色器计算邻域采样纹理坐标可以减少运算,提高性能,顶点着色器到片元着色器是线性插件,不会影响最终结果 o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-1, -1); o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1); o.uv[2] = uv + _MainTex_TexelSize.xy * half2(1, -1); o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1, 0); o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0); o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, 0); o.uv[6] = uv + _MainTex_TexelSize.xy * half2(-1, 1); o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1); o.uv[8] = uv + _MainTex_TexelSize.xy * half2(1, 1); return o; } fixed luminance(fixed4 color) { return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; } half Sobel(v2f i) { const half Gx[9] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; const half Gy[9] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; half texColor; half edgeX = 0; half edgeY = 0; for(int it = 0; it < 9; it++) { texColor = luminance(tex2D(_MainTex, i.uv[it])); edgeX += texColor * Gx[it]; edgeY += texColor * Gy[it]; } half edge = 1 - abs(edgeX) - abs(edgeY); return edge; } fixed4 frag(v2f i): SV_Target { half edge = Sobel(i); fixed4 withEdgeColor = lerp(_EdgeColor, tex2D(_MainTex, i.uv[4]), edge); fixed4 onlyEdgeColor = lerp(_EdgeColor, _BackgroundColor, edge); return lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly); } ENDCG } } FallBack Off }
浙公网安备 33010602011771号