失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Unity Shader学习笔记(5)基于摄像机深度和法线的后处理描边效果

Unity Shader学习笔记(5)基于摄像机深度和法线的后处理描边效果

时间:2021-03-15 09:30:48

相关推荐

Unity Shader学习笔记(5)基于摄像机深度和法线的后处理描边效果

文章目标 :

主要参考书籍为《Unity Shader入门精要》,本文主要注重于整理,方便后续直接调用。

渲染效果图:

主要相关代码:

摄像机脚本文件:

using System.Collections;using System.Collections.Generic;using UnityEngine;namespace UnityShaderLearnPostImageEffects{class EdgeDetectNormalsAndDepth : PostEffectsBase{public Shader edgeDectectShader = null;private Material edgeDectectMaterial = null;[Range(0, 1)]public float edgesOnly = 0f;public Color edgeColor = Color.black;public Color backgroundColor = Color.white;[Range(0f, 0.004f)]public float sampleDistance = 0.001f;public float sensitivityDepth = 1.0f;public float sensitivityNormals = 1.0f;private void OnEnable(){GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;}public Material material{get{edgeDectectMaterial = CheckShaderAndCreateMaterial(edgeDectectShader, edgeDectectMaterial);return edgeDectectMaterial;}}//[ImageEffectOpaque] //仅对不透明物体产生作用,在透明物体渲染之前执行 OnRenderImage 函数;private void OnRenderImage(RenderTexture src, RenderTexture dest){if (material != null){material.SetFloat("_EdgeOnly", edgesOnly);material.SetColor("_EdgeColor", edgeColor);material.SetColor("_BackgroundColor", backgroundColor);material.SetFloat("_SampleDistance", sampleDistance);material.SetVector("_Sensitivity", new Vector4(sensitivityNormals, sensitivityDepth, 0, 0));Graphics.Blit(src, dest, material);}else{Graphics.Blit(src, dest);}}}}

Shader 文件代码:

//参考文件:《Unity Shader 入门精要》//整理制作:嘿皮土豆//渲染管线:默认渲染管线Shader "UnityShaderLearn/EdgeDetectNormalsAndDepth"{Properties{_MainTex("MainTex", 2D) = ""{}_EdgeOnly("EdgeOnly", float) = 1_EdgeColor("EdgeColor", color) = (0,0,0,1)_BackgroundColor("BackgroundColor", Color) = (1,1,1,1)_SampleDistance("SampleDistance", Range(0,0.004)) = 0.001_Sensitivity("Sensitivity", vector) = (1,1,1,1)}Subshader{CGINCLUDE#include "UnityCG.cginc"sampler2D _MainTex;float4 _MainTex_ST;fixed _EdgeOnly;fixed4 _EdgeColor;fixed4 _BackgroundColor;float _SampleDistance;float4 _Sensitivity;sampler2D _CameraDepthNormalsTexture;struct v2f{float4 pos : SV_POSITION;half2 uv[5] : TEXCOORD0;};half CheckSame(half4 center, half4 sample){float2 centerNormal = center.xy;float2 centerDepth = DecodeFloatRG(center.zw);float2 sampleNormal = sample.xy;float2 sampleDepth = DecodeFloatRG(sample.zw);float2 diffNormal = abs(centerNormal - sampleNormal) * _Sensitivity.x;int isSameNormal = (diffNormal.x + diffNormal.y) < 0.1;float2 diffDepth = abs(centerDepth - sampleDepth) * _Sensitivity;int isSameDepth = diffDepth < 0.1 * centerDepth;return isSameDepth * isSameNormal ? 1 : 0;}v2f vert (appdata_img v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);half2 uv = v.texcoord;o.uv[0] = uv;#if UNITY_UV_STARTS_AT_TOPif(_MainTex_ST.y < 0)uv.y = 1-uv.y;#endifo.uv[1] = uv+_MainTex_ST.xy* half2(1,1) * _SampleDistance;o.uv[2] = uv+_MainTex_ST.xy* half2(-1,-1) * _SampleDistance;o.uv[3] = uv+_MainTex_ST.xy* half2(-1,1) * _SampleDistance;o.uv[4] = uv+_MainTex_ST.xy* half2(1,-1) * _SampleDistance;return o;}fixed4 frag (v2f i) : SV_TARGET{half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1]);half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2]);half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3]);half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4]);half edge = 1;edge *= CheckSame(sample1, sample2);edge *= CheckSame(sample3, sample4);fixed4 withEdgeColor = lerp(_EdgeColor, tex2D(_MainTex,i.uv[0]), edge);fixed4 onlyEdgeColor = lerp(_EdgeColor, _BackgroundColor, edge);return lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly);}ENDCGpass{ZTest AlwaysCull OffZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment fragENDCG}}}

如果觉得《Unity Shader学习笔记(5)基于摄像机深度和法线的后处理描边效果》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。