using NUnit.Framework; using UnityEngine.Serialization; namespace UnityEngine.Rendering { /// /// SRPLensFlareBlendMode defined the available blend mode for each LensFlareElement /// [System.Serializable] public enum SRPLensFlareBlendMode { /// /// Additive: Blend One One /// Additive, /// /// Screen: /// Blend One OneMinusSrcColor /// Screen, /// /// Premultiply: /// Blend One OneMinusSrcAlpha /// ColorMask RGB /// Premultiply, /// /// Lerp: Blend SrcAlpha OneMinusSrcAlpha /// Lerp } /// /// SRPLensFlareDistribution defined how we spread the flare element when count > 1 /// [System.Serializable] public enum SRPLensFlareDistribution { /// /// Uniformly spread /// Uniform, /// /// Controlled with curved /// Curve, /// /// Random distribution /// Random } /// /// SRPLensFlareType which can be an image of a procedural shape /// If change order or add new member, need to update preview /// shader: LensFlareDataDrivenPreview.shader /// [System.Serializable] [GenerateHLSL] public enum SRPLensFlareType { /// /// Image from a file or a RenderTexture /// Image, /// /// Procedural Circle /// Circle, /// /// Polygon /// Polygon, /// /// shape as a ring /// Ring, /// /// Hoop /// LensFlareDataSRP } /// /// SRPLensFlareColorType describe how to colorize LensFlare /// [System.Serializable] [GenerateHLSL] public enum SRPLensFlareColorType { /// /// Constant Color /// Constant = 0, /// /// Radial Gradient /// RadialGradient, /// /// Angular Gradient /// AngularGradient } /// /// LensFlareDataElementSRP defines collection of parameters describing the behavior a Lens Flare Element. /// [System.Serializable] public sealed class LensFlareDataElementSRP { /// Initialize default values public LensFlareDataElementSRP() { lensFlareDataSRP = null; visible = true; localIntensity = 1.0f; position = 0.0f; positionOffset = new Vector2(0.0f, 0.0f); angularOffset = 0.0f; translationScale = new Vector2(1.0f, 1.0f); lensFlareTexture = null; uniformScale = 1.0f; sizeXY = Vector2.one; allowMultipleElement = false; count = 5; rotation = 0.0f; preserveAspectRatio = false; // Ring ringThickness = 0.25f; // Hoop hoopFactor = 1.0f; // Shimmer noiseAmplitude = 1.0f; noiseFrequency = 1; noiseSpeed = 0; shapeCutOffSpeed = 0.0f; shapeCutOffRadius = 10.0f; tintColorType = SRPLensFlareColorType.Constant; tint = new Color(1.0f, 1.0f, 1.0f, 0.5f); tintGradient = new TextureGradient( new GradientColorKey[] { new GradientColorKey(Color.black, 0.0f), new GradientColorKey(Color.white, 1.0f) }, new GradientAlphaKey[] { new GradientAlphaKey(0.0f, 0.0f), new GradientAlphaKey(1.0f, 1.0f) }); blendMode = SRPLensFlareBlendMode.Additive; autoRotate = false; isFoldOpened = true; flareType = SRPLensFlareType.Circle; distribution = SRPLensFlareDistribution.Uniform; lengthSpread = 1f; colorGradient = new Gradient(); colorGradient.SetKeys(new GradientColorKey[] { new GradientColorKey(Color.white, 0.0f), new GradientColorKey(Color.white, 1.0f) }, new GradientAlphaKey[] { new GradientAlphaKey(1.0f, 0.0f), new GradientAlphaKey(1.0f, 1.0f) }); positionCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f, 1.0f, 1.0f), new Keyframe(1.0f, 1.0f, 1.0f, -1.0f)); scaleCurve = new AnimationCurve(new Keyframe(0.0f, 1.0f), new Keyframe(1.0f, 1.0f)); uniformAngle = 0.0f; uniformAngleCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f), new Keyframe(1.0f, 0.0f)); // Random seed = 0; intensityVariation = 0.75f; positionVariation = new Vector2(1.0f, 0.0f); scaleVariation = 1.0f; rotationVariation = 180.0f; // Distortion enableRadialDistortion = false; targetSizeDistortion = Vector2.one; distortionCurve = new AnimationCurve(new Keyframe(0.0f, 0.0f, 1.0f, 1.0f), new Keyframe(1.0f, 1.0f, 1.0f, -1.0f)); distortionRelativeToCenter = false; // Parameters for Procedural fallOff = 1.0f; edgeOffset = 0.1f; sdfRoundness = 0.0f; sideCount = 6; inverseSDF = false; } /// /// Clone the current LensFlareDataElementSRP. /// /// Cloned LensFlareDataElementSRP. public LensFlareDataElementSRP Clone() { LensFlareDataElementSRP clone = new LensFlareDataElementSRP(); clone.lensFlareDataSRP = lensFlareDataSRP; clone.visible = visible; clone.localIntensity = localIntensity; clone.position = position; clone.positionOffset = positionOffset; clone.angularOffset = angularOffset; clone.translationScale = translationScale; clone.lensFlareTexture = lensFlareTexture; clone.uniformScale = uniformScale; clone.sizeXY = sizeXY; clone.allowMultipleElement = allowMultipleElement; clone.count = count; clone.rotation = rotation; clone.preserveAspectRatio = preserveAspectRatio; clone.ringThickness = ringThickness; clone.hoopFactor = hoopFactor; clone.noiseAmplitude = noiseAmplitude; clone.noiseFrequency = noiseFrequency; clone.noiseSpeed = noiseSpeed; clone.shapeCutOffSpeed = shapeCutOffSpeed; clone.shapeCutOffRadius = shapeCutOffRadius; clone.tintColorType = tintColorType; clone.tint = tint; clone.tintGradient = new TextureGradient(tintGradient.colorKeys, tintGradient.alphaKeys, tintGradient.mode, tintGradient.colorSpace, tintGradient.textureSize); clone.tintGradient = new TextureGradient(tintGradient.colorKeys, tintGradient.alphaKeys); clone.blendMode = blendMode; clone.autoRotate = autoRotate; clone.isFoldOpened = isFoldOpened; clone.flareType = flareType; clone.distribution = distribution; clone.lengthSpread = lengthSpread; clone.colorGradient = new Gradient(); clone.colorGradient.SetKeys(colorGradient.colorKeys, colorGradient.alphaKeys); clone.colorGradient.mode = colorGradient.mode; clone.colorGradient.colorSpace = colorGradient.colorSpace; clone.positionCurve = new AnimationCurve(positionCurve.keys); clone.scaleCurve = new AnimationCurve(scaleCurve.keys); clone.uniformAngle = uniformAngle; clone.uniformAngleCurve = new AnimationCurve(uniformAngleCurve.keys); clone.seed = seed; clone.intensityVariation = intensityVariation; clone.positionVariation = positionVariation; clone.scaleVariation = scaleVariation; clone.rotationVariation = rotationVariation; clone.enableRadialDistortion = enableRadialDistortion; clone.targetSizeDistortion = targetSizeDistortion; clone.distortionCurve = new AnimationCurve(distortionCurve.keys); clone.distortionRelativeToCenter = distortionRelativeToCenter; clone.fallOff = fallOff; clone.edgeOffset = edgeOffset; clone.sdfRoundness = sdfRoundness; clone.sideCount = sideCount; clone.inverseSDF = inverseSDF; return clone; } /// Current Element is himselft another LensFlareDataSRP public LensFlareDataSRP lensFlareDataSRP; /// Visibility checker for current element public bool visible; /// Position public float position; /// Position offset public Vector2 positionOffset; /// Angular offset public float angularOffset; /// Translation Scale public Vector2 translationScale; // For Hoop /// Ring thickness [Range(0.0f, 1.0f)] public float ringThickness; /// Hoop thickness [Range(-1.0f, 1.0f)] public float hoopFactor; // For Ring /// Noise parameter amplitude public float noiseAmplitude; /// Noise parameter frequency public int noiseFrequency; /// Noise parameter Speed public float noiseSpeed; /// To simulate the cutoff of the flare by the circular shape of the lens. How quickly this cutoff happen. public float shapeCutOffSpeed; /// To simulate the cutoff of the flare by the circular shape of the lens. public float shapeCutOffRadius; [Min(0), SerializeField, FormerlySerializedAs("localIntensity")] float m_LocalIntensity; /// Intensity of this element public float localIntensity { get => m_LocalIntensity; set => m_LocalIntensity = Mathf.Max(0, value); } /// Texture used to for this Lens Flare Element public Texture lensFlareTexture; /// Uniform scale applied public float uniformScale; /// Scale size on each dimension public Vector2 sizeXY; /// Enable multiple elements public bool allowMultipleElement; [Min(1), SerializeField, FormerlySerializedAs("count")] int m_Count; /// Element can be repeated 'count' times public int count { get => m_Count; set => m_Count = Mathf.Max(1, value); } /// Preserve Aspect Ratio public bool preserveAspectRatio; /// Local rotation of the texture public float rotation; /// Specify how to tint flare. public SRPLensFlareColorType tintColorType; /// Tint of the texture can be modulated by the light we are attached to public Color tint; /// Tint radially of the texture can be modulated by the light we are attached to . public TextureGradient tintGradient; /// Blend mode used public SRPLensFlareBlendMode blendMode; /// Rotate the texture relative to the angle on the screen (the rotation will be added to the parameter 'rotation') public bool autoRotate; /// FlareType used public SRPLensFlareType flareType; /// Modulate by light color if the asset is used in a 'SRP Lens Flare Source Override' public bool modulateByLightColor; #pragma warning disable 0414 // never used (editor state) /// Internal value use to store the state of minimized or maximized LensFlareElement [SerializeField] bool isFoldOpened; #pragma warning restore 0414 /// SRPLensFlareDistribution defined how we spread the flare element when count > 1 public SRPLensFlareDistribution distribution; /// Length to spread the distribution of flares, spread start at 'starting position' public float lengthSpread; /// Curve describing how to place flares distribution (Used only for Uniform and Curve 'distribution') public AnimationCurve positionCurve; /// Curve describing how to scale flares distribution (Used only for Uniform and Curve 'distribution') public AnimationCurve scaleCurve; /// Seed used to seed randomness public int seed; /// Colors used uniformly for Uniform or Curve Distribution and Random when the distribution is 'Random'. public Gradient colorGradient; [Range(0, 1), SerializeField, FormerlySerializedAs("intensityVariation")] float m_IntensityVariation; /// Scale factor applied on the variation of the intensities. public float intensityVariation { get => m_IntensityVariation; set => m_IntensityVariation = Mathf.Max(0, value); } /// Scale factor applied on the variation of the positions. public Vector2 positionVariation; /// Coefficient applied on the variation of the scale (relative to the current scale). public float scaleVariation; /// Scale factor applied on the variation of the rotation (relative to the current rotation or auto-rotate). public float rotationVariation; /// True to use or not the radial distortion. public bool enableRadialDistortion; /// Target size used on the edge of the screen. public Vector2 targetSizeDistortion; /// Curve blending from screen center to the edges of the screen. public AnimationCurve distortionCurve; /// If true the distortion is relative to center of the screen otherwise relative to lensFlare source screen position. public bool distortionRelativeToCenter; [Range(0, 1), SerializeField, FormerlySerializedAs("fallOff")] float m_FallOff; /// Fall of the gradient used for the Procedural Flare. public float fallOff { get => m_FallOff; set => m_FallOff = Mathf.Clamp01(value); } [Range(0, 1), SerializeField, FormerlySerializedAs("edgeOffset")] float m_EdgeOffset; /// Gradient Offset used for the Procedural Flare. public float edgeOffset { get => m_EdgeOffset; set => m_EdgeOffset = Mathf.Clamp01(value); } [Min(3), SerializeField, FormerlySerializedAs("sideCount")] int m_SideCount; /// Side count of the regular polygon generated. public int sideCount { get => m_SideCount; set => m_SideCount = Mathf.Max(3, value); } [Range(0, 1), SerializeField, FormerlySerializedAs("sdfRoundness")] float m_SdfRoundness; /// Roundness of the polygon flare (0: Sharp Polygon, 1: Circle). public float sdfRoundness { get => m_SdfRoundness; set => m_SdfRoundness = Mathf.Clamp01(value); } /// Inverse the gradient direction. public bool inverseSDF; /// Uniform angle (in degrees) used with multiple element enabled with Uniform distribution. public float uniformAngle; /// Uniform angle (remap from -180.0f to 180.0f) used with multiple element enabled with Curve distribution. public AnimationCurve uniformAngleCurve; } /// LensFlareDataSRP defines a Lens Flare with a set of LensFlareDataElementSRP [System.Serializable] public sealed class LensFlareDataSRP : ScriptableObject { /// Initialize default value public LensFlareDataSRP() { elements = null; } /// /// Check if we have at last one 'modulatedByLightColor' enabled. /// /// true if we have at least one 'modulatedByLightColor' on the asset. public bool HasAModulateByLightColorElement() { if (elements != null) { foreach (LensFlareDataElementSRP e in elements) { if (e.modulateByLightColor) return true; } } return false; } /// List of LensFlareDataElementSRP public LensFlareDataElementSRP[] elements; } }