我们创建了 Fontainebleau 演示来说明摄影photogrammetry流程和 LayeredLit 着色器的使用。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

251 行
7.9 KiB

using System.Collections.Generic;
using UnityEngine;
namespace HDRPSamples
{
[ExecuteInEditMode]
[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(CustomDepthBuffer))]
public class HDRPLensFlare : MonoBehaviour
{
[SerializeField, HideInInspector]
MeshRenderer m_MeshRenderer;
[SerializeField, HideInInspector]
MeshFilter m_MeshFilter;
[SerializeField]
Light m_Light;
CustomDepthBuffer m_CustomDepthBuffer;
[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>();
if (m_CustomDepthBuffer == null)
m_CustomDepthBuffer = GetComponent<CustomDepthBuffer>();
m_MeshFilter.hideFlags = HideFlags.None;
m_MeshRenderer.hideFlags = HideFlags.None;
if (Flares == null)
Flares = new List<FlareSettings>();
m_MeshFilter.mesh = InitMesh();
}
void OnEnable()
{
UpdateGeometry();
}
void OnValidate()
{
UpdateGeometry();
UpdateMaterials();
}
// Update is called once per frame
void Update ()
{
// Lazy!
UpdateVaryingAttributes();
// TODO optimize!
var depthBuffer = m_CustomDepthBuffer.target;
var depthBufferZParams = m_CustomDepthBuffer.zBufferParams;
if (depthBuffer != null)
{
foreach (var mat in m_MeshRenderer.materials)
{
mat.SetTexture("_CustomDepthTex", depthBuffer);
mat.SetVector("_CustomDepthZBufferParams", depthBufferZParams);
}
}
}
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;
}
}
}
}