Unity Shader Example 21 (Highlighting 边缘光)
来源:互联网 发布:网络编程难吗 编辑:程序博客网 时间:2024/04/25 08:56
主要参考Highlighting System 插件。
效果:
被Plane挡住:
没有被plane挡住:
HighlightableObjectSimple 组件,挂上这个组件的物体更换所有的材质,更换物体的layer。
using UnityEngine;using System.Collections;using System.Collections.Generic;public class HighlightableObjectSimple : MonoBehaviour { private List<HighlightingRendererCache> highlightableRenderers; private bool zWrite = false; private static float transparentCutoff = 0.5f; private bool materialsIsDirty = true; private int[] layersCache; public static int highlightingLayer = 7; private Color currentColor; private Material highlightingMaterial { get { return zWrite ? opaqueZMaterial : opaqueMaterial; } } // Common (for this component) replacement material for opaque geometry highlighting private Material _opaqueMaterial; private Material opaqueMaterial { get { if (_opaqueMaterial == null) { _opaqueMaterial = new Material(opaqueShader); _opaqueMaterial.hideFlags = HideFlags.HideAndDontSave; } return _opaqueMaterial; } } // Common (for this component) replacement material for opaque geometry highlighting with Z-Buffer writing enabled private Material _opaqueZMaterial; private Material opaqueZMaterial { get { if (_opaqueZMaterial == null) { _opaqueZMaterial = new Material(opaqueZShader); _opaqueZMaterial.hideFlags = HideFlags.HideAndDontSave; } return _opaqueZMaterial; } } // private static Shader _opaqueShader; private static Shader opaqueShader { get { if (_opaqueShader == null) { _opaqueShader = Shader.Find("Hidden/Highlighted/StencilOpaque"); } return _opaqueShader; } } // private static Shader _transparentShader; public static Shader transparentShader { get { if (_transparentShader == null) { _transparentShader = Shader.Find("Hidden/Highlighted/StencilTransparent"); } return _transparentShader; } } // private static Shader _opaqueZShader; private static Shader opaqueZShader { get { if (_opaqueZShader == null) { _opaqueZShader = Shader.Find("Hidden/Highlighted/StencilOpaqueZ"); } return _opaqueZShader; } } // private static Shader _transparentZShader; private static Shader transparentZShader { get { if (_transparentZShader == null) { _transparentZShader = Shader.Find("Hidden/Highlighted/StencilTransparentZ"); } return _transparentZShader; } } void Start() { InitMaterials(false); } private void InitMaterials(bool writeDepth) { highlightableRenderers = new List<HighlightingRendererCache>(); MeshRenderer[] mr = GetComponentsInChildren<MeshRenderer>(); CacheRenderers(mr); SkinnedMeshRenderer[] smr = GetComponentsInChildren<SkinnedMeshRenderer>(); CacheRenderers(smr); materialsIsDirty = false; } private void CacheRenderers(Renderer[] renderers) { for (int i = 0; i < renderers.Length; i++) { Material[] materials = renderers[i].sharedMaterials; if (materials != null) { highlightableRenderers.Add(new HighlightingRendererCache(renderers[i], materials, highlightingMaterial, zWrite)); } } } private void OnEnable() { HighlightingEffect.highlightingEvent += UpdateEventHandler; } private void OnDisable() { HighlightingEffect.highlightingEvent -= UpdateEventHandler; if (highlightableRenderers != null) { highlightableRenderers.Clear(); } // Reset highlighting parameters to default values layersCache = null; materialsIsDirty = true; zWrite = false; if (_opaqueMaterial) { DestroyImmediate(_opaqueMaterial); } if (_opaqueZMaterial) { DestroyImmediate(_opaqueZMaterial); } } private void SetColor(Color c) { if (currentColor == c) { return; } if (zWrite) { opaqueZMaterial.SetColor("_Outline", c); } else { opaqueMaterial.SetColor("_Outline", c); } for (int i = 0; i < highlightableRenderers.Count; i++) { highlightableRenderers[i].SetColorForTransparent(c); } currentColor = c; } private void UpdateEventHandler(bool trigger, bool writeDepth) { // Update and enable highlighting if (trigger) { // ZWriting state changed? if (zWrite != writeDepth) { materialsIsDirty = true; } // Initialize new materials if needed if (materialsIsDirty) { InitMaterials(writeDepth); } SetColor(Color.red); if (highlightableRenderers != null) { layersCache = new int[highlightableRenderers.Count]; for (int i = 0; i < highlightableRenderers.Count; i++) { GameObject go = highlightableRenderers[i].goCached; // cache layer layersCache[i] = go.layer; // temporary set layer to renderable by the highlighting effect camera go.layer = highlightingLayer; // 换材质 highlightableRenderers[i].SetState(true); } } } // Disable highlighting else { if (highlightableRenderers != null) { for (int i = 0; i < highlightableRenderers.Count; i++) { highlightableRenderers[i].goCached.layer = layersCache[i]; highlightableRenderers[i].SetState(false); } } } } private class HighlightingRendererCache { public Renderer rendererCached; public GameObject goCached; private Material[] sourceMaterials; private Material[] replacementMaterials; private List<int> transparentMaterialIndexes; // Constructor public HighlightingRendererCache(Renderer rend, Material[] mats, Material sharedOpaqueMaterial, bool writeDepth) { rendererCached = rend; goCached = rend.gameObject; sourceMaterials = mats; replacementMaterials = new Material[mats.Length]; transparentMaterialIndexes = new List<int>(); for (int i = 0; i < mats.Length; i++) { Material sourceMat = mats[i]; if (sourceMat == null) { continue; } string tag = sourceMat.GetTag("RenderType", true); if (tag == "Transparent" || tag == "TransparentCutout") { Material replacementMat = new Material(writeDepth ? transparentZShader : transparentShader); if (sourceMat.HasProperty("_MainTex")) { replacementMat.SetTexture("_MainTex", sourceMat.mainTexture); replacementMat.SetTextureOffset("_MainTex", sourceMat.mainTextureOffset); replacementMat.SetTextureScale("_MainTex", sourceMat.mainTextureScale); } replacementMat.SetFloat("_Cutoff", sourceMat.HasProperty("_Cutoff") ? sourceMat.GetFloat("_Cutoff") : transparentCutoff); replacementMaterials[i] = replacementMat; transparentMaterialIndexes.Add(i); } else { replacementMaterials[i] = sharedOpaqueMaterial; } } } // Based on given state variable, replaces materials of this cached renderer to the highlighted ones and back public void SetState(bool state) { rendererCached.sharedMaterials = state ? replacementMaterials : sourceMaterials; } // Sets given color as the highlighting color on all transparent materials for this cached renderer public void SetColorForTransparent(Color clr) { for (int i = 0; i < transparentMaterialIndexes.Count; i++) { replacementMaterials[transparentMaterialIndexes[i]].SetColor("_Outline", clr); } } }}
HighlightingEffect 挂在Camera上。
以上的,主要就是为了渲染stencilBuffer rendererTexture。
using UnityEngine;// Delegate for the highlighting eventpublic delegate void HighlightingEventHandler(bool state, bool zWrite);[RequireComponent(typeof(Camera))]public class HighlightingEffect : MonoBehaviour{// Event used to notify highlightable objects to change their materials before rendering to the highlighting buffer beginspublic static event HighlightingEventHandler highlightingEvent;#region Inspector Fields// Stencil (highlighting) buffer depthpublic int stencilZBufferDepth = 0;// Stencil (highlighting) buffer size downsample factorpublic int _downsampleFactor = 4;// Blur iterationspublic int iterations = 2;// Blur minimal spreadpublic float blurMinSpread = 0.65f;// Blur spread per iterationpublic float blurSpread = 0.25f;// Blurring intensity for the blur materialpublic float _blurIntensity = 0.3f;// These properties available only in Editor - we don't need them in standalone build#if UNITY_EDITOR// Z-buffer writing state getter/setterpublic bool stencilZBufferEnabled{get{return (stencilZBufferDepth > 0);}set{if (stencilZBufferEnabled != value){stencilZBufferDepth = value ? 16 : 0;}}}// Downsampling factor getter/setterpublic int downsampleFactor{get{if (_downsampleFactor == 1){return 0;}if (_downsampleFactor == 2){return 1;}return 2;}set{if (value == 0){_downsampleFactor = 1;}if (value == 1){_downsampleFactor = 2;}if (value == 2){_downsampleFactor = 4;}}}// Blur alpha intensity getter/setterpublic float blurIntensity{get{return _blurIntensity;}set{if (_blurIntensity != value){_blurIntensity = value;if (Application.isPlaying){blurMaterial.SetFloat("_Intensity", _blurIntensity);}}}}#endif#endregion#region Private Fields// Highlighting camera layers culling mask//private int layerMask = (1 << HighlightableObject.highlightingLayer); private int layerMask = (1 << HighlightableObjectSimple.highlightingLayer);// This GameObject referenceprivate GameObject go = null;// Camera for rendering stencil buffer GameObjectprivate GameObject shaderCameraGO = null;// Camera for rendering stencil bufferprivate Camera shaderCamera = null;// RenderTexture with stencil bufferprivate RenderTexture stencilBuffer = null;// Camera referenceprivate Camera refCam = null;// Blur Shaderprivate static Shader _blurShader;private static Shader blurShader{get{if (_blurShader == null){_blurShader = Shader.Find("Hidden/Highlighted/Blur");}return _blurShader;}}// Compositing Shaderprivate static Shader _compShader;private static Shader compShader {get{if (_compShader == null){_compShader = Shader.Find("Hidden/Highlighted/Composite");}return _compShader;}}// Blur Materialprivate static Material _blurMaterial = null;private static Material blurMaterial{get{if (_blurMaterial == null){_blurMaterial = new Material(blurShader);_blurMaterial.hideFlags = HideFlags.HideAndDontSave;}return _blurMaterial;}}// Compositing Materialprivate static Material _compMaterial = null;private static Material compMaterial{get{if (_compMaterial == null){_compMaterial = new Material(compShader);_compMaterial.hideFlags = HideFlags.HideAndDontSave;}return _compMaterial;}}#endregionvoid Awake(){go = gameObject;refCam = GetComponent<Camera>();}void OnDisable(){if (shaderCameraGO != null){DestroyImmediate(shaderCameraGO);}if (_blurShader){_blurShader = null;}if (_compShader){_compShader = null;}if (_blurMaterial){DestroyImmediate(_blurMaterial);}if (_compMaterial){DestroyImmediate(_compMaterial);}if (stencilBuffer != null){RenderTexture.ReleaseTemporary(stencilBuffer);stencilBuffer = null;}}void Start(){// Disable if Image Effects is not supportedif (!SystemInfo.supportsImageEffects){Debug.LogWarning("HighlightingSystem : Image effects is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if Render Textures is not supportedif (!SystemInfo.supportsRenderTextures){Debug.LogWarning("HighlightingSystem : RenderTextures is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if required Render Texture Format is not supportedif (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32)){Debug.LogWarning("HighlightingSystem : RenderTextureFormat.ARGB32 is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if HighlightingStencilOpaque shader is not supportedif (!Shader.Find("Hidden/Highlighted/StencilOpaque").isSupported){Debug.LogWarning("HighlightingSystem : HighlightingStencilOpaque shader is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if HighlightingStencilTransparent shader is not supportedif (!Shader.Find("Hidden/Highlighted/StencilTransparent").isSupported){Debug.LogWarning("HighlightingSystem : HighlightingStencilTransparent shader is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if HighlightingStencilOpaqueZ shader is not supportedif (!Shader.Find("Hidden/Highlighted/StencilOpaqueZ").isSupported){Debug.LogWarning("HighlightingSystem : HighlightingStencilOpaqueZ shader is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if HighlightingStencilTransparentZ shader is not supportedif (!Shader.Find("Hidden/Highlighted/StencilTransparentZ").isSupported){Debug.LogWarning("HighlightingSystem : HighlightingStencilTransparentZ shader is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if HighlightingBlur shader is not supportedif (!blurShader.isSupported){Debug.LogWarning("HighlightingSystem : HighlightingBlur shader is not supported on this platform! Disabling.");this.enabled = false;return;}// Disable if HighlightingComposite shader is not supportedif (!compShader.isSupported){Debug.LogWarning("HighlightingSystem : HighlightingComposite shader is not supported on this platform! Disabling.");this.enabled = false;return;}// Set the initial intensity in blur shaderblurMaterial.SetFloat("_Intensity", _blurIntensity);}// Performs one blur iterationpublic void FourTapCone(RenderTexture source, RenderTexture dest, int iteration){float off = blurMinSpread + iteration * blurSpread;blurMaterial.SetFloat("_OffsetScale", off);Graphics.Blit(source, dest, blurMaterial);}// Downsamples source textureprivate void DownSample4x(RenderTexture source, RenderTexture dest){float off = 1.0f;blurMaterial.SetFloat("_OffsetScale", off);Graphics.Blit(source, dest, blurMaterial);}// Render all highlighted objects to the stencil buffervoid OnPreRender(){#if UNITY_4_0if (this.enabled == false || go.activeInHierarchy == false)#elseif (this.enabled == false || go.active == false)#endifreturn;if (stencilBuffer != null){RenderTexture.ReleaseTemporary(stencilBuffer);stencilBuffer = null;}// Turn on highlighted shadersif (highlightingEvent != null){highlightingEvent(true, (stencilZBufferDepth > 0));}// We don't need to render the scene if there's no HighlightableObjectselse{return;}stencilBuffer = RenderTexture.GetTemporary((int)GetComponent<Camera>().pixelWidth, (int)GetComponent<Camera>().pixelHeight, stencilZBufferDepth, RenderTextureFormat.ARGB32);if (!shaderCameraGO){shaderCameraGO = new GameObject("HighlightingCamera", typeof(Camera));shaderCameraGO.GetComponent<Camera>().enabled = false;shaderCameraGO.hideFlags = HideFlags.HideAndDontSave;}if (!shaderCamera){shaderCamera = shaderCameraGO.GetComponent<Camera>();}shaderCamera.CopyFrom(refCam);//shaderCamera.projectionMatrix = refCam.projectionMatrix;// Uncomment this line if you have problems using Highlighting System with custom projection matrix on your camerashaderCamera.cullingMask = layerMask;shaderCamera.rect = new Rect(0f, 0f, 1f, 1f);shaderCamera.renderingPath = RenderingPath.VertexLit;shaderCamera.hdr = false;shaderCamera.useOcclusionCulling = false;shaderCamera.backgroundColor = new Color(0f, 0f, 0f, 0f);shaderCamera.clearFlags = CameraClearFlags.SolidColor;shaderCamera.targetTexture = stencilBuffer;shaderCamera.Render();// Turn off highlighted shadersif (highlightingEvent != null){highlightingEvent(false, false);}}// Compose final frame with highlightingvoid OnRenderImage(RenderTexture source, RenderTexture destination){// If stencilBuffer is not created by some reasonif (stencilBuffer == null){// Simply transfer framebuffer to destinationGraphics.Blit(source, destination);return;}// Create two buffers for blurring the imageint width = source.width / _downsampleFactor;int height = source.height / _downsampleFactor;RenderTexture buffer = RenderTexture.GetTemporary(width, height, stencilZBufferDepth, RenderTextureFormat.ARGB32);RenderTexture buffer2 = RenderTexture.GetTemporary(width, height, stencilZBufferDepth, RenderTextureFormat.ARGB32);// Copy stencil buffer to the 4x4 smaller textureDownSample4x(stencilBuffer, buffer);// Blur the small texturebool oddEven = true;for (int i = 0; i < iterations; i++){if (oddEven){FourTapCone(buffer, buffer2, i);}else{FourTapCone(buffer2, buffer, i);}oddEven = !oddEven;}// ComposecompMaterial.SetTexture("_StencilTex", stencilBuffer);compMaterial.SetTexture("_BlurTex", oddEven ? buffer : buffer2);Graphics.Blit(source, destination, compMaterial);// CleanupRenderTexture.ReleaseTemporary(buffer);RenderTexture.ReleaseTemporary(buffer2);if (stencilBuffer != null){RenderTexture.ReleaseTemporary(stencilBuffer);stencilBuffer = null;}}}
HighlightingInclude.cginc
#ifndef HIGHLIGHTING_CG_INCLUDED#define HIGHLIGHTING_CG_INCLUDED#include "UnityCG.cginc"// Opaqueuniform fixed4 _Outline;struct appdata_vert{float4 vertex : POSITION;};float4 vert(appdata_vert v) : POSITION{return mul(UNITY_MATRIX_MVP, v.vertex);}fixed4 frag() : COLOR{return _Outline;}// Transparentuniform sampler2D _MainTex;uniform float4 _MainTex_ST;uniform fixed _Cutoff;struct appdata_vert_tex{float4 vertex : POSITION;float2 texcoord : TEXCOORD0;};struct v2f{float4 pos : POSITION;float2 texcoord : TEXCOORD0;};v2f vert_alpha(appdata_vert_tex v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);return o;}fixed4 frag_alpha(v2f i) : COLOR{clip(tex2D(_MainTex, i.texcoord).a - _Cutoff);return _Outline;}#endif
HighlightingStencilOpaque.shader
Shader "Hidden/Highlighted/StencilOpaque"{CGINCLUDE#include "HighlightingInclude.cginc"ENDCGSubShader{Pass{ZWrite OffZTest AlwaysLighting OffFog { Mode Off }CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma fragmentoption ARB_precision_hint_fastestENDCG}}Fallback Off}
HighlightingStencilOpaqueZ.shader
Shader "Hidden/Highlighted/StencilOpaqueZ"{CGINCLUDE#include "HighlightingInclude.cginc"ENDCGSubShader{Pass{ZWrite OnZTest LEqualLighting OffFog { Mode Off }CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma fragmentoption ARB_precision_hint_fastestENDCG}}Fallback Off}
HighlightingStencilTransparent.shader
Shader "Hidden/Highlighted/StencilTransparent"{Properties{_MainTex ("", 2D) = "" {}_Cutoff ("", Float) = 0.5}CGINCLUDE#include "HighlightingInclude.cginc"ENDCGSubShader{Pass{ZWrite OffZTest AlwaysLighting OffFog { Mode Off }CGPROGRAM#pragma vertex vert_alpha#pragma fragment frag_alpha#pragma fragmentoption ARB_precision_hint_fastestENDCG}}Fallback Off}
HighlightingStencilTransparentZ.shader
Shader "Hidden/Highlighted/StencilTransparentZ"{Properties{_MainTex ("", 2D) = "" {}_Cutoff ("", Float) = 0.5}CGINCLUDE#include "HighlightingInclude.cginc"ENDCGSubShader{Pass{ZWrite OnZTest LEqualLighting OffFog { Mode Off }CGPROGRAM#pragma vertex vert_alpha#pragma fragment frag_alpha#pragma fragmentoption ARB_precision_hint_fastestENDCG}}Fallback Off}
Shader "Hidden/Highlighted/Blur"{Properties{_MainTex ("", 2D) = "" {}_Intensity ("", Range (0.25,0.5)) = 0.3}SubShader{Pass{ZTest AlwaysCull OffZWrite OffLighting OffFog { Mode Off }CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma fragmentoption ARB_precision_hint_fastest#include "UnityCG.cginc"uniform sampler2D _MainTex;uniform half4 _MainTex_TexelSize;uniform half _OffsetScale;uniform fixed _Intensity;struct v2f{float4 pos : POSITION;half2 uv[4] : TEXCOORD0;};v2f vert (appdata_img v){// Shader code optimized for the Unity shader compilerv2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);half2 offs = _MainTex_TexelSize.xy * _OffsetScale;o.uv[0].x = v.texcoord.x - offs.x;o.uv[0].y = v.texcoord.y - offs.y;o.uv[1].x = v.texcoord.x + offs.x;o.uv[1].y = v.texcoord.y - offs.y;o.uv[2].x = v.texcoord.x + offs.x;o.uv[2].y = v.texcoord.y + offs.y;o.uv[3].x = v.texcoord.x - offs.x;o.uv[3].y = v.texcoord.y + offs.y;return o;}fixed4 frag(v2f i) : COLOR{fixed4 color1 = tex2D(_MainTex, i.uv[0]);fixed4 color2 = tex2D(_MainTex, i.uv[1]);fixed4 color3 = tex2D(_MainTex, i.uv[2]);fixed4 color4 = tex2D(_MainTex, i.uv[3]);fixed4 color;color.rgb = max(color1.rgb, color2.rgb);color.rgb = max(color.rgb, color3.rgb);color.rgb = max(color.rgb, color4.rgb);color.a = (color1.a + color2.a + color3.a + color4.a) * _Intensity;return color;}ENDCG}}Fallback off}
HighlightingComposite.shader
Shader "Hidden/Highlighted/Composite"{Properties{_MainTex ("", 2D) = "" {}_BlurTex ("", 2D) = "" {}_StencilTex ("", 2D) = "" {}}SubShader{Pass{ZTest AlwaysCull OffZWrite OffLighting OffFog { Mode off }CGPROGRAM#pragma vertex vert#pragma fragment frag#pragma fragmentoption ARB_precision_hint_fastest#include "UnityCG.cginc"struct v2f{float4 pos : POSITION;half2 uv[2] : TEXCOORD0;};uniform sampler2D _MainTex;uniform sampler2D _BlurTex;uniform sampler2D _StencilTex;float4 _MainTex_TexelSize;v2f vert (appdata_img v){v2f o;o.pos = mul(UNITY_MATRIX_MVP, v.vertex);o.uv[0] = v.texcoord.xy;o.uv[1] = v.texcoord.xy;if (_MainTex_TexelSize.y < 0)o.uv[1].y = 1 - o.uv[1].y;return o;}fixed4 frag(v2f i) : COLOR{fixed4 framebuffer = tex2D(_MainTex, i.uv[0]);fixed4 stencil = tex2D(_StencilTex, i.uv[1]);if (any(stencil.rgb)){return framebuffer;}else{fixed4 blurred = tex2D(_BlurTex, i.uv[1]);fixed4 color;color.rgb = lerp(framebuffer.rgb, blurred.rgb, saturate(blurred.a - stencil.a));color.a = framebuffer.a;return color;}}ENDCG}}SubShader{Pass{SetTexture [_MainTex] {}}}Fallback Off}
0 0
- Unity Shader Example 21 (Highlighting 边缘光)
- Unity Shader-边缘光(RimLight)效果
- Unity Shader-边缘光(RimLight)效果
- Unity Shader Example 12 (Bloom 高光)
- Unity Shader Example 13 (边缘 Bloom )
- Unity Shader 表面着色器边缘光(Rim Lighting)一
- Unity Shader 表面着色器边缘光(Rim Lighting)二
- shader 边缘泛光
- shader 边缘泛光2
- unity shader-边缘检测
- unity shader-边缘发光
- 【Unity Shader实战】利用凹凸纹理和边缘光模拟全息投影的效果
- Highlighting System v4.0(Unity边缘高亮插件)
- unity自发光透明shader
- unity自发光透明shader
- [Shader 着色器]边缘高光
- Unity Shader Example 1 : Texture
- Unity Shader Example 4 (扭曲)
- 第七周—求奖金和
- Fine-tunning适用情况
- 自己总结
- Windows环境下的Android Studio使用入门:基本设置、常用快捷键及Live Templates
- R tutorial 01 - Data type 数据类型
- Unity Shader Example 21 (Highlighting 边缘光)
- C++变量命名规则
- 关于Theme的修改
- 动态和静态链接库总结
- TCMalloc的使用与源码剖析之十--------TCMalloc与APR,ptmalloc的分析比较
- AsyncTask 与Handler+Thread
- DisplayUtils
- python爬虫改进
- JZOJ3101. NOIP2012提高组 开车旅行