Unity中实现网格轮廓效果,选中边框效果(附带高斯模糊实现模式,处理了锯齿情况)

更新时间:2023-06-29 21:10:39 阅读: 评论:0

Unity中实现⽹格轮廓效果,选中边框效果(附带⾼斯模糊实现模
式,处理了锯齿情况)
问题背景:
最近要实现选中实体的⾼亮效果,要那种类似于unity中Outline的效果,⽹格轮廓⾼亮效果。
效果图:
具体代码:
OutlineEffect.cs
实体⾼亮效果类:
轮廓边总控制类,该脚本需要挂载到场景相机上
1using UnityEngine;
2using System.Collections.Generic;
3using UnityEngine.Rendering;
4
5namespace Tx3d.Framework
6 {
7    [DisallowMultipleComponent]
8    [RequireComponent(typeof(Camera))]
9    [ExecuteInEditMode]
10public class OutlineEffect : MonoBehaviour
11    {
12public static OutlineEffect Instance { get; private t; }
13
14private readonly LinkedSet<Outline> outlines = new LinkedSet<Outline>();
15
16        [Range(1.0f, 6.0f)]
17public float lineThickness = 1.0f;
18        [Range(0, 10)]
19public float lineIntensity = 1.2f;
20        [Range(0, 1)]
21public float fillAmount = 0.108f;
22
23public Color lineColor0 = llow;
24public Color lineColor1 = ;
25public Color lineColor2 = Color.blue;
26public Color lineColor3 = an;
27
28public bool additiveRendering = fal;
29
30public bool backfaceCulling = true;
31
32        [Header("The ttings can affect performance!")]
33public bool cornerOutlines = fal;
34public bool addLinesBetweenColors = fal;
35
36        [Header("Advanced ttings")]
37public bool scaleWithScreenSize = true;
38        [Range(0.1f, .9f)]
39public float alphaCutoff = .5f;
40public bool flipY = fal;
41public Camera sourceCamera;
42public bool autoEnableOutlines = true;
43
44        [HideInInspector]
45public Camera outlineCamera;
46        Material outline1Material;
47        Material outline2Material;
48        Material outline3Material;
49        Material outline4Material;
50        Material outlineEraMaterial;
51        Shader outlineShader;
52        Shader outlineBufferShader;
53        [HideInInspector]
54public Material outlineShaderMaterial;
55        [HideInInspector]
56public RenderTexture renderTexture;
57        [HideInInspector]
60        CommandBuffer commandBuffer;
61
62        Material GetMaterialFromID(int ID)
63        {
64if (ID == 0)
65return outline1Material;
66el if (ID == 1)
67return outline2Material;
个人总结学生68el if (ID == 2)
69return outline3Material;
70el if (ID == 3)
71return outline4Material;
72el
73return outline1Material;
74        }
75        List<Material> materialBuffer = new List<Material>();
76        Material CreateMaterial(Color emissionColor)
77        {
78            Material m = new Material(outlineBufferShader);
79            m.SetColor("_Color", emissionColor);
80            m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
81            m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
82            m.SetInt("_ZWrite", 0);
83            m.DisableKeyword("_ALPHATEST_ON");
84            m.EnableKeyword("_ALPHABLEND_ON");
85            m.DisableKeyword("_ALPHAPREMULTIPLY_ON");
86            m.renderQueue = 3000;
87return m;
88        }
89
90private void Awake()
91        {
92if (Instance != null)
93            {
94                Destroy(this);
95throw new System.Exception("you can only have one outline camera in the scene");
96            }
97
98            Instance = this;
99        }
100
101void Start()
102        {
103            CreateMaterialsIfNeeded();
104            UpdateMaterialsPublicProperties();
105
106if (sourceCamera == null)
107            {
108                sourceCamera = GetComponent<Camera>();
109
110if (sourceCamera == null)
111                    sourceCamera = Camera.main;
112            }
113
114if (outlineCamera == null)
115            {
116foreach (Camera c in GetComponentsInChildren<Camera>())
117                {
118if (c.name == "Outline Camera")
119                    {
120                        outlineCamera = c;飞信群发
121                        c.enabled = fal;
122
123break;
124                    }
125                }
126
127if (outlineCamera == null)
128                {
129                    GameObject cameraGameObject = new GameObject("Outline Camera");
130                    ansform.parent = ansform;
131                    outlineCamera = cameraGameObject.AddComponent<Camera>();
132                    abled = fal;
133                }
134            }
135
136            renderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 16, RenderTextureFormat.Default);
137            extraRenderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 16, RenderTextureFormat.Default); 138            UpdateOutlineCameraFromSource();
139
140            commandBuffer = new CommandBuffer();
141            outlineCamera.AddCommandBuffer(CameraEvent.BeforeImageEffects, commandBuffer);
142        }
143
144bool RenderTheNextFrame;
145public void OnPreRender()
146        {
147if (commandBuffer == null)
149
150// the first frame during which there are no outlines, we still need to render
151// to clear out any outlines that were being rendered on the previous frame
152if (outlines.Count == 0)
153            {
154if (!RenderTheNextFrame)
155return;
156
157                RenderTheNextFrame = fal;
158            }
159el
160            {
161                RenderTheNextFrame = true;
162            }
163
164            CreateMaterialsIfNeeded();
165
166if (renderTexture == null || renderTexture.width != sourceCamera.pixelWidth || renderTexture.height != sourceCamera.pixelHeight)
167            {
168                renderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.pixelHeight, 16, RenderTextureFormat.Default);
169                extraRenderTexture = new RenderTexture(sourceCamera.pixelWidth, sourceCamera.p
ixelHeight, 16, RenderTextureFormat.Default); 170                outlineCamera.targetTexture = renderTexture;
171            }
172            UpdateMaterialsPublicProperties();
173            UpdateOutlineCameraFromSource();
174            outlineCamera.targetTexture = renderTexture;
175            commandBuffer.SetRenderTarget(renderTexture);
176
177            commandBuffer.Clear();
178
179foreach (Outline outline in outlines)
180            {
181                LayerMask l = sourceCamera.cullingMask;
182
183// if (outline != null && l == (l | (1 << outline.gameObject.layer)))
184if (outline != null)
185                {
186for (int v = 0; v < outline.SharedMaterials.Length; v++)
187                    {
188                        Material m = null;
189
190if (outline.SharedMaterials[v].mainTexture != null && outline.SharedMaterials[v])
191                        {
192foreach (Material g in materialBuffer)
193                            {
194if (g.mainTexture == outline.SharedMaterials[v].mainTexture)
195                                {
196if (aRenderer && g.color == lor)
197                                        m = g;
198el if (g.color == lor).color)
199                                        m = g;
200                                }
201                            }
202
203if (m == null)
204                            {
205if (aRenderer)
206                                    m = new Material(outlineEraMaterial);
207el
208                                    m = new Material(lor));
209                                m.mainTexture = outline.SharedMaterials[v].mainTexture;
210                                materialBuffer.Add(m);
211                            }
212                        }
213el
小白兔怎么画214                        {
215if (aRenderer)
216                                m = outlineEraMaterial;
217el
218                                m = lor);
219                        }
220
221if (backfaceCulling)
222                            m.SetInt("_Culling", (int)UnityEngine.Rendering.CullMode.Back);
223el
224                            m.SetInt("_Culling", (int)UnityEngine.Rendering.CullMode.Off);
225
226                        commandBuffer.DrawRenderer(outline.Renderer, m, 0, 0);
227                        MeshFilter mL = outline.MeshFilter;
228if (mL)
229                        {
230if (mL.sharedMesh != null)
231                            {
232for (int i = 1; i < mL.sharedMesh.subMeshCount; i++)
233                                    commandBuffer.DrawRenderer(outline.Renderer, m, i, 0);
234                            }
235                        }
236                        SkinnedMeshRenderer sMR = outline.SkinnedMeshRenderer;
238                        {
239if (sMR.sharedMesh != null)
240                            {
愤怒图片241for (int i = 1; i < sMR.sharedMesh.subMeshCount; i++)骆驼祥子感悟
242                                    commandBuffer.DrawRenderer(outline.Renderer, m, i, 0);
243                            }
244                        }
245                    }
246                }
247            }
248
249            outlineCamera.Render();
250        }
251
252private void OnEnable()
253        {
254//if (autoEnableOutlines)
255//{
256//    Outline[] o = FindObjectsOfType<Outline>();
257
258//    foreach (Outline oL in o)
259//    {
260//        oL.enabled = fal;
261//        oL.enabled = true;
262//    }
263//}
264        }
265
266void OnDestroy()
267        {
268if (renderTexture != null)
269                renderTexture.Relea();
270if (extraRenderTexture != null)
271                extraRenderTexture.Relea();
272            DestroyMaterials();
预防煤气中毒273        }
274
275void OnRenderImage(RenderTexture source, RenderTexture destination)
276        {
277if (outlineShaderMaterial != null)
278            {
279                outlineShaderMaterial.SetTexture("_OutlineSource", renderTexture);
280
281if (addLinesBetweenColors)
282                {
283                    Graphics.Blit(source, extraRenderTexture, outlineShaderMaterial, 0);
284                    outlineShaderMaterial.SetTexture("_OutlineSource", extraRenderTexture);
285                }
286                Graphics.Blit(source, destination, outlineShaderMaterial, 1);
287            }
288        }
289
290private void CreateMaterialsIfNeeded()
291        {
292if (outlineShader == null)
293                outlineShader = Resources.Load<Shader>("Shaders/Outline/OutlineShader");
294if (outlineBufferShader == null)
295            {
296                outlineBufferShader = Resources.Load<Shader>("Shaders/Outline/OutlineBufferShader"); 297            }
298if (outlineShaderMaterial == null)
299            {
300                outlineShaderMaterial = new Material(outlineShader);
301                outlineShaderMaterial.hideFlags = HideFlags.HideAndDontSave;
302                UpdateMaterialsPublicProperties();
303            }
304if (outlineEraMaterial == null)
305                outlineEraMaterial = CreateMaterial(new Color(0, 0, 0, 0));
306if (outline1Material == null)
307                outline1Material = CreateMaterial(new Color(1, 0, 0, 0));
308if (outline2Material == null)
309                outline2Material = CreateMaterial(new Color(0, 1, 0, 0));
310if (outline3Material == null)
311                outline3Material = CreateMaterial(new Color(0, 0, 1, 0));
312if (outline4Material == null)
313                outline4Material = CreateMaterial(new Color(0, 0, 0, 1));
314        }
315
316private void DestroyMaterials()
317        {
318foreach (Material m in materialBuffer)
319                DestroyImmediate(m);
320            materialBuffer.Clear();
321            DestroyImmediate(outlineShaderMaterial);
322            DestroyImmediate(outlineEraMaterial);
323            DestroyImmediate(outline1Material);
324            DestroyImmediate(outline2Material);
325            DestroyImmediate(outline3Material);
327            outlineBufferShader = null;
328            outlineShaderMaterial = null;
329            outlineEraMaterial = null;
330            outline1Material = null;
331            outline2Material = null;
332            outline3Material = null;
333            outline4Material = null;
334        }
335
336public void UpdateMaterialsPublicProperties()
337        {
338if (outlineShaderMaterial)
339            {
340float scalingFactor = 1;
341if (scaleWithScreenSize)
342                {
小班找朋友教案343// If Screen.height gets bigger, outlines gets thicker
344                    scalingFactor = Screen.height / 360.0f;
345                }
346
347// If scaling is too small (height less than 360 pixels), make sure you still render the outlines, but render them with 1 thickness
348if (scaleWithScreenSize && scalingFactor < 1)
349                {
350if (UnityEngine.XR.XRSettings.isDeviceActive && sourceCamera.stereoTargetEye != StereoTargetEyeMask.None)
351                    {
352                        outlineShaderMaterial.SetFloat("_LineThicknessX", (1 / 1000.0f) * (1.0f / UnityEngine.TextureWidth) * 1000.0f);
353                        outlineShaderMaterial.SetFloat("_LineThicknessY", (1 / 1000.0f) * (1.0f / UnityEngine.TextureHeight) * 1000.0f);
354                    }
355el
356                    {
357                        outlineShaderMaterial.SetFloat("_LineThicknessX", (1 / 1000.0f) * (1.0f / Screen.width) * 1000.0f);
358                        outlineShaderMaterial.SetFloat("_LineThicknessY", (1 / 1000.0f) * (1.0f / Screen.height) * 1000.0f);
359                    }
可爱熊猫图片360                }
361el
362                {
363if (UnityEngine.XR.XRSettings.isDeviceActive && sourceCamera.stereoTargetEye != StereoTargetEyeMask.None)
364                    {
365                        outlineShaderMaterial.SetFloat("_LineThicknessX", scalingFactor * (lineThickness / 1000.0f) * (1.0f / UnityEngine.TextureWidth) * 1000.0f); 366                        outlineShaderMaterial.SetFloat("_LineThicknessY", scalingFactor * (lineThickness / 1000.0f) * (1.0f / UnityEngine.TextureHeight) * 1000.0f); 367                    }
368el
369                    {
370                        outlineShaderMaterial.SetFloat("_LineThicknessX", scalingFactor * (lineThickness / 1000.0f) * (1.0f / Screen.width) * 1000.0f);
371                        outlineShaderMaterial.SetFloat("_LineThicknessY", scalingFactor * (lineThickness / 1000.0f) * (1.0f / Screen.height) * 1000.0f);
372                    }
373                }
374                outlineShaderMaterial.SetFloat("_LineIntensity", lineIntensity);
375                outlineShaderMaterial.SetFloat("_FillAmount", fillAmount);
376                outlineShaderMaterial.SetColor("_LineColor1", lineColor0 * lineColor0);
377                outlineShaderMaterial.SetColor("_LineColor2", lineColor1 * lineColor1);
378                outlineShaderMaterial.SetColor("_LineColor3", lineColor2 * lineColor2);
379                outlineShaderMaterial.SetColor("_LineColor4", lineColor3 * lineColor3);
380if (flipY)
381                    outlineShaderMaterial.SetInt("_FlipY", 1);
382el
383                    outlineShaderMaterial.SetInt("_FlipY", 0);
384if (!additiveRendering)
385                    outlineShaderMaterial.SetInt("_Dark", 1);
386el
387                    outlineShaderMaterial.SetInt("_Dark", 0);
388if (cornerOutlines)
389                    outlineShaderMaterial.SetInt("_CornerOutlines", 1);
390el
391                    outlineShaderMaterial.SetInt("_CornerOutlines", 0);
392
393                Shader.SetGlobalFloat("_OutlineAlphaCutoff", alphaCutoff);
394            }
395        }
396
397void UpdateOutlineCameraFromSource()
398        {
399            outlineCamera.CopyFrom(sourceCamera);
400            deringPath = RenderingPath.Forward;
401            outlineCamera.backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.0f);
402            outlineCamera.clearFlags = CameraClearFlags.SolidColor;
403            = new Rect(0, 0, 1, 1);
404            outlineCamera.cullingMask = 0;
405            outlineCamera.targetTexture = renderTexture;
406            abled = fal;
407#if UNITY_EDITOR
408            outlineCamera.allowHDR = fal;
409#el
410            outlineCamera.allowHDR = fal;
411#endif
412        }
413
414public void AddOutline(Outline outline)

本文发布于:2023-06-29 21:10:39,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1069014.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:效果   图片   轮廓
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图