Notifications
Article
Unity HDRP | 镜头光晕LensFlare 分享
Updated a year ago
3.7 K
27
又来了~又来了~ 兔纸我又来了~~今天呢,给大家分享一个HDRP管线的Lens Flare组件,记得哦~ 评论~! 点赞~! 转发~!(●'◡'●)以及收藏~~
镜头光晕的Unity Package下载地址见文章最后哦~
Lens Flare 又称为”镜头光晕“~ 在游戏中镜头指的是经过视椎体做可视裁剪过后将可视物体渲染到RenderTarget中所呈现出来的画面。RenderTarget可以简单理解成当前游戏窗口的画面。光晕则指的是当镜头中存在光源时,光源会在镜头中会产生一种带有颜色的连续”光圈“特效

Builtin管线下,Unity内置了这个组件,Object上挂上Lens Flare组件,然后Camera上挂上Flare layer组件就能实现这个效果,这里我就不过多介绍啦~
但是,在HDRP管线下这个功能已经处于Not supported状态了,详细很多小伙伴都想要,因为这个组件其实可以用在很多地方,比如呢:强化环境氛围,强化Bloom效果,转场通特效,所以呢,今天,就给大家分享一个HDRP下的Lens Flare组件~~
原理很简单,代码如下:
using System.Collections.Generic; using UnityEngine; namespace HDRPSamples { [ExecuteInEditMode] [RequireComponent(typeof(MeshRenderer))] [RequireComponent(typeof(MeshFilter))] public class HDRPLensFlare : MonoBehaviour { [SerializeField, HideInInspector] MeshRenderer m_MeshRenderer; [SerializeField, HideInInspector] MeshFilter m_MeshFilter; [SerializeField] Light m_Light; [Header("Global Settings")] public float OcclusionRadius = 1.0f; public float NearFadeStartDistance = 1.0f; public float NearFadeEndDistance = 3.0f; public float FarFadeStartDistance = 10.0f; public float FarFadeEndDistance = 50.0f; [Header("Flare Element Settings")] [SerializeField] public List<FlareSettings> Flares; void Awake() { if (m_MeshFilter == null) m_MeshFilter = GetComponent<MeshFilter>(); if (m_MeshRenderer == null) m_MeshRenderer = GetComponent<MeshRenderer>(); m_Light = GetComponent<Light>(); m_MeshFilter.hideFlags = HideFlags.None; m_MeshRenderer.hideFlags = HideFlags.None; if (Flares == null) Flares = new List<FlareSettings>(); m_MeshFilter.mesh = InitMesh(); } void OnEnable() { UpdateGeometry(); } // Use this for initialization void Start () { m_Light = GetComponent<Light>(); } void OnValidate() { UpdateGeometry(); UpdateMaterials(); } // Update is called once per frame void Update () { // Lazy! UpdateVaryingAttributes(); } Mesh InitMesh() { Mesh m = new Mesh(); m.MarkDynamic(); return m; } void UpdateMaterials() { Material[] mats = new Material[Flares.Count]; int i = 0; foreach(FlareSettings f in Flares) { mats[i] = f.Material; i++; } m_MeshRenderer.sharedMaterials = mats; } void UpdateGeometry() { Mesh m = m_MeshFilter.sharedMesh; // Positions List<Vector3> vertices = new List<Vector3>(); foreach (FlareSettings s in Flares) { vertices.Add(new Vector3(-1, -1, 0)); vertices.Add(new Vector3(1, -1, 0)); vertices.Add(new Vector3(1, 1, 0)); vertices.Add(new Vector3(-1, 1, 0)); } m.SetVertices(vertices); // UVs List<Vector2> uvs = new List<Vector2>(); foreach (FlareSettings s in Flares) { uvs.Add(new Vector2(0, 1)); uvs.Add(new Vector2(1, 1)); uvs.Add(new Vector2(1, 0)); uvs.Add(new Vector2(0, 0)); } m.SetUVs(0, uvs); // Variable Data m.SetColors(GetLensFlareColor()); m.SetUVs(1, GetLensFlareData()); m.SetUVs(2, GetWorldPositionAndRadius()); m.SetUVs(3, GetDistanceFadeData()); m.subMeshCount = Flares.Count; // Tris for (int i = 0; i < Flares.Count; i++) { int[] tris = new int[6]; tris[0] = (i * 4) + 0; tris[1] = (i * 4) + 1; tris[2] = (i * 4) + 2; tris[3] = (i * 4) + 2; tris[4] = (i * 4) + 3; tris[5] = (i * 4) + 0; m.SetTriangles(tris, i); } Bounds b = m.bounds; b.extents = new Vector3(OcclusionRadius, OcclusionRadius, OcclusionRadius); m.bounds = b; m.UploadMeshData(false); } void UpdateVaryingAttributes() { Mesh m = m_MeshFilter.sharedMesh; m.SetColors(GetLensFlareColor()); m.SetUVs(1, GetLensFlareData()); m.SetUVs(2, GetWorldPositionAndRadius()); m.SetUVs(3, GetDistanceFadeData()); Bounds b = m.bounds; b.extents = new Vector3(OcclusionRadius, OcclusionRadius, OcclusionRadius); m.bounds = b; m.name = "LensFlare (" + gameObject.name + ")"; } List<Color> GetLensFlareColor() { List<Color> colors = new List<Color>(); foreach (FlareSettings s in Flares) { Color c = (s.MultiplyByLightColor && m_Light != null)? s.Color * m_Light.color * m_Light.intensity : s.Color; colors.Add(c); colors.Add(c); colors.Add(c); colors.Add(c); } return colors; } List<Vector4> GetLensFlareData() { List<Vector4> lfData = new List<Vector4>(); foreach(FlareSettings s in Flares) { Vector4 data = new Vector4(s.RayPosition, s.AutoRotate? -1 : Mathf.Abs(s.Rotation), s.Size.x, s.Size.y); lfData.Add(data); lfData.Add(data); lfData.Add(data); lfData.Add(data); } return lfData; } List<Vector4> GetDistanceFadeData() { List<Vector4> fadeData = new List<Vector4>(); foreach (FlareSettings s in Flares) { Vector4 data = new Vector4(NearFadeStartDistance,NearFadeEndDistance, FarFadeStartDistance, FarFadeEndDistance); fadeData.Add(data); fadeData.Add(data); fadeData.Add(data); fadeData.Add(data); } return fadeData; } List<Vector4> GetWorldPositionAndRadius() { List<Vector4> worldPos = new List<Vector4>(); Vector3 pos = transform.position; Vector4 value = new Vector4(pos.x,pos.y,pos.z, OcclusionRadius); foreach (FlareSettings s in Flares) { worldPos.Add(value); worldPos.Add(value); worldPos.Add(value); worldPos.Add(value); } return worldPos; } void OnDrawGizmosSelected() { Gizmos.color = new Color(1, 0, 0, 0.3f); Gizmos.DrawSphere(transform.position, OcclusionRadius); Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, OcclusionRadius); } [System.Serializable] public class FlareSettings { public float RayPosition; public Material Material; [ColorUsage(true,true)] public Color Color; public bool MultiplyByLightColor; public Vector2 Size; public float Rotation; public bool AutoRotate; public FlareSettings() { RayPosition = 0.0f; Color = Color.white; MultiplyByLightColor = true; Size = new Vector2(0.3f, 0.3f); Rotation = 0.0f; AutoRotate = false; } } } }
里面有几个参数:
  • Ray Position:这个参数是调整Lens距离模拟光源的生成位置
  • Color:这个参数是调整Lens呈现的颜色
  • Multiply by light color:选择是否乘以灯关的颜色调整亮度
  • Size:这个参数是设置Lens的图片大小
  • Rotation:这个参数是调整Lens的角度参数
  • Auto Rotate:是否开启Lens的模拟视差旋转

今天就到这里吧~~(●'◡'●)记得评论~点赞~转发哦~~~

微云下载地址:https://share.weiyun.com/5x9N9VU

Unity支持的版本:
- Unity 2019.1 HDRP 5.7+
- Unity 2019.2 HDRP 6.9+
- Unity 2019.3 HDRP 7.1+
樱花兔
一个做单机游戏的美少女,商务合作Q:262745567 - Producer
15
Comments
D
Dagouzi
5 months ago
现在用4.2TLS片片变粉红了
0
D
Dagouzi
5 months ago
巨巨i了i了~
0
AP
Aroma Pixel
5 months ago
谢谢兔兔大佬分享。
0
D
Dagouzi
8 months ago
谢谢兔兔大佬
0
萝薇
9 months ago
谢谢兔兔分享
0