/// <summary> /// Effective Job of drawing the set of Lens Flare registered /// </summary> /// <param name="lensFlareShader">Lens Flare material (HDRP or URP shader)</param> /// <param name="lensFlares">Set of Lens Flare</param> /// <param name="cam">Camera</param> /// <param name="actualWidth">Width actually used for rendering after dynamic resolution and XR is applied.</param> /// <param name="actualHeight">Height actually used for rendering after dynamic resolution and XR is applied.</param> /// <param name="usePanini">Set if use Panani Projection</param> /// <param name="paniniDistance">Distance used for Panini projection</param> /// <param name="paniniCropToFit">CropToFit parameter used for Panini projection</param> /// <param name="cmd">Command Buffer</param> /// <param name="colorBuffer">Source Render Target which contains the Color Buffer</param> /// <param name="GetLensFlareLightAttenuation">Delegate to which return return the Attenuation of the light based on their shape which uses the functions ShapeAttenuation...(...), must reimplemented per SRP</param> /// <param name="_FlareTex">ShaderID for the FlareTex</param> /// <param name="_FlareColorValue">ShaderID for the FlareColor</param> /// <param name="_FlareData0">ShaderID for the FlareData0</param> /// <param name="_FlareData1">ShaderID for the FlareData1</param> /// <param name="_FlareData2">ShaderID for the FlareData2</param> /// <param name="_FlareData3">ShaderID for the FlareData3</param> /// <param name="_FlareData4">ShaderID for the FlareData4</param> /// <param name="_FlareData5">ShaderID for the FlareData5</param> /// <param name="debugView">Debug View which setup black background to see only Lens Flare</param> static public void DoLensFlareDataDrivenCommon(Material lensFlareShader, LensFlareCommonSRP lensFlares, Camera cam, float actualWidth, float actualHeight, bool usePanini, float paniniDistance, float paniniCropToFit, Rendering.CommandBuffer cmd, Rendering.RenderTargetIdentifier colorBuffer, System.Func <Light, Camera, Vector3, float> GetLensFlareLightAttenuation, int _FlareTex, int _FlareColorValue, int _FlareData0, int _FlareData1, int _FlareData2, int _FlareData3, int _FlareData4, int _FlareData5, bool debugView) { Vector2 vScreenRatio; if (lensFlares.IsEmpty()) { return; } Vector2 screenSize = new Vector2(actualWidth, actualHeight); float screenRatio = screenSize.x / screenSize.y; vScreenRatio = new Vector2(screenRatio, 1.0f); Rendering.CoreUtils.SetRenderTarget(cmd, colorBuffer); if (debugView) { // Background pitch black to see only the Flares cmd.ClearRenderTarget(false, true, Color.black); } foreach (LensFlareComponentSRP comp in lensFlares.GetData()) { if (comp == null) { continue; } LensFlareDataSRP data = comp.lensFlareData; if (!comp.enabled || !comp.gameObject.activeSelf || !comp.gameObject.activeInHierarchy || data == null || data.elements == null || data.elements.Length == 0) { continue; } Light light = comp.GetComponent <Light>(); Vector3 positionWS; Vector3 viewportPos; bool isDirLight = false; if (light != null && light.type == LightType.Directional) { positionWS = -light.transform.forward * cam.farClipPlane; isDirLight = true; } else { positionWS = comp.transform.position; } viewportPos = cam.WorldToViewportPoint(positionWS); if (usePanini && cam == Camera.main) { viewportPos = DoPaniniProjection(viewportPos, actualWidth, actualHeight, cam.fieldOfView, paniniCropToFit, paniniDistance); } if (viewportPos.z < 0.0f) { continue; } if (!comp.allowOffScreen) { if (viewportPos.x < 0.0f || viewportPos.x > 1.0f || viewportPos.y < 0.0f || viewportPos.y > 1.0f) { continue; } } Vector4 modulationByColor = Vector4.one; Vector4 modulationAttenuation = Vector4.one; Vector3 diffToObject = positionWS - cam.transform.position; float distToObject = diffToObject.magnitude; float coefDistSample = distToObject / comp.maxAttenuationDistance; float coefScaleSample = distToObject / comp.maxAttenuationScale; float distanceAttenuation = !isDirLight && comp.distanceAttenuationCurve.length > 0 ? comp.distanceAttenuationCurve.Evaluate(coefDistSample) : 1.0f; float scaleByDistance = !isDirLight && comp.scaleByDistanceCurve.length >= 1 ? comp.scaleByDistanceCurve.Evaluate(coefScaleSample) : 1.0f; Color globalColorModulation = Color.white; if (light != null) { if (comp.attenuationByLightShape) { globalColorModulation *= GetLensFlareLightAttenuation(light, cam, -diffToObject.normalized); } } globalColorModulation *= distanceAttenuation; Vector3 dir = (cam.transform.position - comp.transform.position).normalized; Vector3 screenPosZ = cam.WorldToViewportPoint(positionWS + dir * comp.occlusionOffset); Vector2 occlusionRadiusEdgeScreenPos0 = (Vector2)cam.WorldToViewportPoint(positionWS); Vector2 occlusionRadiusEdgeScreenPos1 = (Vector2)cam.WorldToViewportPoint(positionWS + cam.transform.up * comp.occlusionRadius); float occlusionRadius = (occlusionRadiusEdgeScreenPos1 - occlusionRadiusEdgeScreenPos0).magnitude; cmd.SetGlobalVector(_FlareData1, new Vector4(occlusionRadius, comp.sampleCount, screenPosZ.z, actualHeight / actualWidth)); if (comp.useOcclusion) { cmd.EnableShaderKeyword("FLARE_OCCLUSION"); } else { cmd.DisableShaderKeyword("FLARE_OCCLUSION"); } foreach (LensFlareDataElementSRP element in data.elements) { if (element == null || (element.lensFlareTexture == null && element.flareType == SRPLensFlareType.Image) || element.localIntensity <= 0.0f || element.count <= 0) { continue; } Color colorModulation = globalColorModulation; if (light != null && element.modulateByLightColor) { if (light.useColorTemperature) { colorModulation *= light.color * Mathf.CorrelatedColorTemperatureToRGB(light.colorTemperature); } else { colorModulation *= light.color; } } Color curColor = colorModulation; Vector2 screenPos = new Vector2(2.0f * viewportPos.x - 1.0f, 1.0f - 2.0f * viewportPos.y); Vector2 translationScale = new Vector2(element.translationScale.x, element.translationScale.y); Texture texture = element.lensFlareTexture; float elemAspectRatio = element.sizeXY.x / element.sizeXY.y; float usedAspectRatio; if (element.flareType == SRPLensFlareType.Image) { usedAspectRatio = element.preserveAspectRatio ? ((((float)texture.height) / (float)texture.width)) : 1.0f; } else { usedAspectRatio = 1.0f; } float rotation = element.rotation; Vector4 tint = Vector4.Scale(element.tint, curColor); Vector2 radPos = new Vector2(Mathf.Abs(screenPos.x), Mathf.Abs(screenPos.y)); float radius = Mathf.Max(radPos.x, radPos.y); // l1 norm (instead of l2 norm) float radialsScaleRadius = comp.radialScreenAttenuationCurve.length > 0 ? comp.radialScreenAttenuationCurve.Evaluate(radius) : 1.0f; Vector2 elemSizeXY; if (element.preserveAspectRatio) { if (usedAspectRatio >= 1.0f) { elemSizeXY = new Vector2(element.sizeXY.x / usedAspectRatio, element.sizeXY.y); } else { elemSizeXY = new Vector2(element.sizeXY.x, element.sizeXY.y * usedAspectRatio); } } else { elemSizeXY = new Vector2(element.sizeXY.x, element.sizeXY.y); } float scaleSize = 0.1f; // Arbitrary value Vector2 size = new Vector2(elemSizeXY.x, elemSizeXY.y); float combinedScale = scaleByDistance * scaleSize * element.uniformScale * comp.scale; size *= combinedScale; Vector4 gradientModulation = new Vector4(1.0f, 1.0f, 1.0f, 1.0f); float currentIntensity = comp.intensity * element.localIntensity * radialsScaleRadius * distanceAttenuation; if (currentIntensity <= 0.0f) { continue; } curColor *= element.tint; curColor *= currentIntensity; float globalCos0 = Mathf.Cos(-element.angularOffset * Mathf.Deg2Rad); float globalSin0 = Mathf.Sin(-element.angularOffset * Mathf.Deg2Rad); float position = 2.0f * element.position; SRPLensFlareBlendMode blendMode = element.blendMode; int materialPass; if (blendMode == SRPLensFlareBlendMode.Additive) { materialPass = 0; } else if (blendMode == SRPLensFlareBlendMode.Screen) { materialPass = 1; } else if (blendMode == SRPLensFlareBlendMode.Premultiply) { materialPass = 2; } else if (blendMode == SRPLensFlareBlendMode.Lerp) { materialPass = 3; } else { materialPass = 0; } if (element.flareType == SRPLensFlareType.Image) { cmd.DisableShaderKeyword("FLARE_CIRCLE"); cmd.DisableShaderKeyword("FLARE_POLYGON"); } else if (element.flareType == SRPLensFlareType.Circle) { cmd.EnableShaderKeyword("FLARE_CIRCLE"); cmd.DisableShaderKeyword("FLARE_POLYGON"); } else if (element.flareType == SRPLensFlareType.Polygon) { cmd.DisableShaderKeyword("FLARE_CIRCLE"); cmd.EnableShaderKeyword("FLARE_POLYGON"); } if (element.flareType == SRPLensFlareType.Circle || element.flareType == SRPLensFlareType.Polygon) { if (element.inverseSDF) { cmd.EnableShaderKeyword("FLARE_INVERSE_SDF"); } else { cmd.DisableShaderKeyword("FLARE_INVERSE_SDF"); } } else { cmd.DisableShaderKeyword("FLARE_INVERSE_SDF"); } if (element.lensFlareTexture != null) { cmd.SetGlobalTexture(_FlareTex, element.lensFlareTexture); } float usedGradientPosition = Mathf.Clamp01((1.0f - element.edgeOffset) - 1e-6f); if (element.flareType == SRPLensFlareType.Polygon) { usedGradientPosition = Mathf.Pow(usedGradientPosition + 1.0f, 5); } Vector2 ComputeLocalSize(Vector2 rayOff, Vector2 rayOff0, Vector2 curSize, AnimationCurve distortionCurve) { Vector2 rayOffZ = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localRadPos; float localRadius; if (!element.distortionRelativeToCenter) { localRadPos = (rayOff - rayOff0) * 0.5f; localRadius = Mathf.Clamp01(Mathf.Max(Mathf.Abs(localRadPos.x), Mathf.Abs(localRadPos.y))); // l1 norm (instead of l2 norm) } else { localRadPos = screenPos + (rayOff + new Vector2(element.positionOffset.x, -element.positionOffset.y)) * element.translationScale; localRadius = Mathf.Clamp01(localRadPos.magnitude); // l2 norm (instead of l1 norm) } float localLerpValue = Mathf.Clamp01(distortionCurve.Evaluate(localRadius)); return(new Vector2(Mathf.Lerp(curSize.x, element.targetSizeDistortion.x * combinedScale / usedAspectRatio, localLerpValue), Mathf.Lerp(curSize.y, element.targetSizeDistortion.y * combinedScale, localLerpValue))); } float usedSDFRoundness = element.sdfRoundness; cmd.SetGlobalVector(_FlareData5, new Vector4(comp.allowOffScreen ? 1.0f : -1.0f, usedGradientPosition, Mathf.Exp(Mathf.Lerp(0.0f, 4.0f, Mathf.Clamp01(1.0f - element.fallOff))), 0.0f)); if (element.flareType == SRPLensFlareType.Polygon) { float invSide = 1.0f / (float)element.sideCount; float rCos = Mathf.Cos(Mathf.PI * invSide); float roundValue = rCos * usedSDFRoundness; float r = rCos - roundValue; float an = 2.0f * Mathf.PI * invSide; float he = r * Mathf.Tan(0.5f * an); cmd.SetGlobalVector(_FlareData4, new Vector4(usedSDFRoundness, r, an, he)); } else { cmd.SetGlobalVector(_FlareData4, new Vector4(usedSDFRoundness, 0.0f, 0.0f, 0.0f)); } if (!element.allowMultipleElement || element.count == 1) { Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, element.rotation, position, element.angularOffset, element.positionOffset, element.autoRotate); Vector2 rayOff = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); } else { float dLength = 2.0f * element.lengthSpread / ((float)(element.count - 1)); if (element.distribution == SRPLensFlareDistribution.Uniform) { for (int elemIdx = 0; elemIdx < element.count; ++elemIdx) { Vector2 rayOff = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } float timeScale = element.count >= 2 ? ((float)elemIdx) / ((float)(element.count - 1)) : 0.5f; Color col = element.colorGradient.Evaluate(timeScale); Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, element.rotation, position, element.angularOffset, element.positionOffset, element.autoRotate); cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor * col); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); position += dLength; } } else if (element.distribution == SRPLensFlareDistribution.Random) { Random.State backupRandState = UnityEngine.Random.state; Random.InitState(element.seed); Vector2 side = new Vector2(Mathf.Sin(-element.angularOffset * Mathf.Deg2Rad), Mathf.Cos(-element.angularOffset * Mathf.Deg2Rad)); side *= element.positionVariation.y; float RandomRange(float min, float max) { return(Random.Range(min, max)); } for (int elemIdx = 0; elemIdx < element.count; ++elemIdx) { float localIntensity = RandomRange(-1.0f, 1.0f) * element.intensityVariation + 1.0f; Vector2 rayOff = GetLensFlareRayOffset(screenPos, position, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } localSize += localSize * (element.scaleVariation * RandomRange(-1.0f, 1.0f)); Color randCol = element.colorGradient.Evaluate(RandomRange(0.0f, 1.0f)); Vector2 localPositionOffset = element.positionOffset + RandomRange(-1.0f, 1.0f) * side; float localRotation = element.rotation + RandomRange(-Mathf.PI, Mathf.PI) * element.rotationVariation; if (localIntensity > 0.0f) { Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, localRotation, position, element.angularOffset, localPositionOffset, element.autoRotate); cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor * randCol * localIntensity); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); } position += dLength; position += 0.5f * dLength * RandomRange(-1.0f, 1.0f) * element.positionVariation.x; } Random.state = backupRandState; } else if (element.distribution == SRPLensFlareDistribution.Curve) { for (int elemIdx = 0; elemIdx < element.count; ++elemIdx) { float timeScale = element.count >= 2 ? ((float)elemIdx) / ((float)(element.count - 1)) : 0.5f; Color col = element.colorGradient.Evaluate(timeScale); float positionSpacing = element.positionCurve.length > 0 ? element.positionCurve.Evaluate(timeScale) : 1.0f; float localPos = position + 2.0f * element.lengthSpread * positionSpacing; Vector2 rayOff = GetLensFlareRayOffset(screenPos, localPos, globalCos0, globalSin0); Vector2 localSize = size; if (element.enableRadialDistortion) { Vector2 rayOff0 = GetLensFlareRayOffset(screenPos, 0.0f, globalCos0, globalSin0); localSize = ComputeLocalSize(rayOff, rayOff0, localSize, element.distortionCurve); } float sizeCurveValue = element.scaleCurve.length > 0 ? element.scaleCurve.Evaluate(timeScale) : 1.0f; localSize *= sizeCurveValue; Vector4 flareData0 = GetFlareData0(screenPos, element.translationScale, vScreenRatio, element.rotation, localPos, element.angularOffset, element.positionOffset, element.autoRotate); cmd.SetGlobalVector(_FlareData0, flareData0); cmd.SetGlobalVector(_FlareData2, new Vector4(screenPos.x, screenPos.y, localSize.x, localSize.y)); cmd.SetGlobalVector(_FlareData3, new Vector4(rayOff.x * element.translationScale.x, rayOff.y * element.translationScale.y, 1.0f / (float)element.sideCount, 0.0f)); cmd.SetGlobalVector(_FlareColorValue, curColor * col); UnityEngine.Rendering.Blitter.DrawQuad(cmd, lensFlareShader, materialPass); } } } } } }
/// <summary> /// Override this method to make your own IMGUI based GUI for the property. /// Draw for one element one the list of SRPLensFlareElement /// </summary> /// <param name="position">Rectangle on the screen to use for the property GUI</param> /// <param name="property">The SerializedProperty to make the custom GUI for.</param> /// <param name="label">The label of this property.</param> public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { float originX = position.x; float offsetHeight = 1.75f * (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing); InitFirstRect(position); SerializedProperty intensityProp = property.FindPropertyRelative("localIntensity"); SerializedProperty positionProp = property.FindPropertyRelative("position"); SerializedProperty positionOffsetProp = property.FindPropertyRelative("positionOffset"); SerializedProperty angularOffsetProp = property.FindPropertyRelative("angularOffset"); SerializedProperty translationScaleProp = property.FindPropertyRelative("translationScale"); SerializedProperty lensFlareProp = property.FindPropertyRelative("lensFlareTexture"); SerializedProperty tintProp = property.FindPropertyRelative("tint"); SerializedProperty blendModeProp = property.FindPropertyRelative("blendMode"); SerializedProperty countProp = property.FindPropertyRelative("count"); SerializedProperty allowMultipleElementProp = property.FindPropertyRelative("allowMultipleElement"); SerializedProperty rotationProp = property.FindPropertyRelative("rotation"); SerializedProperty speedProp = property.FindPropertyRelative("speed"); SerializedProperty autoRotateProp = property.FindPropertyRelative("autoRotate"); SerializedProperty preserveAspectRatioProp = property.FindPropertyRelative("preserveAspectRatio"); SerializedProperty modulateByLightColor = property.FindPropertyRelative("modulateByLightColor"); SerializedProperty isFoldOpenedProp = property.FindPropertyRelative("isFoldOpened"); SerializedProperty flareTypeProp = property.FindPropertyRelative("flareType"); SerializedProperty uniformScaleProp = property.FindPropertyRelative("uniformScale"); SerializedProperty sizeXYProp = property.FindPropertyRelative("sizeXY"); // SerializedProperty distributionProp = property.FindPropertyRelative("distribution"); SerializedProperty lengthSpreadProp = property.FindPropertyRelative("lengthSpread"); SerializedProperty colorGradientProp = property.FindPropertyRelative("colorGradient"); SerializedProperty positionCurveProp = property.FindPropertyRelative("positionCurve"); SerializedProperty scaleCurveProp = property.FindPropertyRelative("scaleCurve"); // Random SerializedProperty seedProp = property.FindPropertyRelative("seed"); SerializedProperty intensityVariationProp = property.FindPropertyRelative("intensityVariation"); SerializedProperty positionVariationProp = property.FindPropertyRelative("positionVariation"); SerializedProperty scaleVariationProp = property.FindPropertyRelative("scaleVariation"); SerializedProperty sizeVariationProp = property.FindPropertyRelative("sizeVariation"); SerializedProperty rotationVariationProp = property.FindPropertyRelative("rotationVariation"); // Distortion SerializedProperty enableDistortionProp = property.FindPropertyRelative("enableRadialDistortion"); SerializedProperty targetSizeDistortionProp = property.FindPropertyRelative("targetSizeDistortion"); SerializedProperty distortionCurveProp = property.FindPropertyRelative("distortionCurve"); SerializedProperty distortionRelativeToCenterProp = property.FindPropertyRelative("distortionRelativeToCenter"); SRPLensFlareType flareType = (UnityEngine.SRPLensFlareType)flareTypeProp.enumValueIndex; Texture texture = lensFlareProp.objectReferenceValue ? lensFlareProp.objectReferenceValue as Texture : null; float localAspectRatio = sizeXYProp.vector2Value.x / Mathf.Max(sizeXYProp.vector2Value.y, 1e-6f); float imgWidth = 1.5f * 35.0f; float usedAspectRatio; if (flareType == SRPLensFlareType.Image) { usedAspectRatio = (lensFlareProp.objectReferenceValue && preserveAspectRatioProp.boolValue) ? (((float)texture.width) / ((float)texture.height)) : localAspectRatio; } else { usedAspectRatio = 1.0f; } if (isFoldOpenedProp.boolValue) { Rect imgRect = new Rect(m_CurrentRect.x + 0.5f * (position.width - imgWidth), m_CurrentRect.y + GUIStyle.none.lineHeight + 5.0f, imgWidth, imgWidth); if (flareType == SRPLensFlareType.Image) { EditorGUI.DrawTextureTransparent(imgRect, lensFlareProp.objectReferenceValue as Texture, ScaleMode.ScaleToFit, usedAspectRatio); m_CurrentRect.y += 1.5f * 35.0f; } } else { float imgOffY = 0.5f * (GetPropertyHeight(property, label) - imgWidth - GUIStyle.none.lineHeight); Rect imgRect = new Rect(position.x - 35.0f + 15.0f, position.y + imgOffY + GUIStyle.none.lineHeight, imgWidth, imgWidth); if (flareType == SRPLensFlareType.Image) { EditorGUI.DrawTextureTransparent(imgRect, lensFlareProp.objectReferenceValue as Texture, ScaleMode.ScaleToFit, usedAspectRatio); } else if (flareType == SRPLensFlareType.Circle) { EditorGUI.DrawTextureTransparent(imgRect, Styles.circleIcon.image, ScaleMode.ScaleToFit, usedAspectRatio); } else //if (flareType != SRPLensFlareType.Polygon) { EditorGUI.DrawTextureTransparent(imgRect, Styles.polygonIcon.image, ScaleMode.ScaleToFit, usedAspectRatio); } } Rect rect = m_CurrentRect; EditorGUI.BeginProperty(new Rect(rect.x, rect.y, rect.width, 2.0f * rect.height), label, property); float lineHeight = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing; Color tmpCol; bool tmpBool; float tmp; int iTmp; Vector2 tmpVec2; Rect localRect = new Rect(position.x, position.y, position.width, GUIStyle.none.lineHeight); if (EditorGUI.BeginFoldoutHeaderGroup(localRect, isFoldOpenedProp.boolValue, Styles.lensFlareElement)) { rect = GetNextRect(); EditorGUI.TextArea(rect, Styles.typeElement.text, style: EditorStyles.boldLabel); { rect = GetNextRect(); SRPLensFlareType newType; SRPLensFlareType typeValue = (UnityEngine.SRPLensFlareType)flareTypeProp.enumValueIndex; if ((newType = ((SRPLensFlareType)(EditorGUI.EnumPopup(rect, Styles.flareType, typeValue)))) != typeValue) { flareTypeProp.enumValueIndex = (int)newType; } if (newType == SRPLensFlareType.Image) { Texture tmpTex; rect = GetNextRect(); if ((tmpTex = (EditorGUI.ObjectField(rect, Styles.flareTexture, lensFlareProp.objectReferenceValue, typeof(Texture), false) as Texture)) != (lensFlareProp.objectReferenceValue as Texture)) { lensFlareProp.objectReferenceValue = tmpTex; lensFlareProp.serializedObject.ApplyModifiedProperties(); } rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.preserveAspectRatio, preserveAspectRatioProp.boolValue)) != preserveAspectRatioProp.boolValue) { preserveAspectRatioProp.boolValue = tmpBool; } } else if (newType == SRPLensFlareType.Circle || newType == SRPLensFlareType.Polygon) { SerializedProperty fallOffProp = property.FindPropertyRelative("fallOff"); SerializedProperty edgeOffsetProp = property.FindPropertyRelative("edgeOffset"); SerializedProperty sdfRoundnessProp = property.FindPropertyRelative("sdfRoundness"); SerializedProperty sideCountProp = property.FindPropertyRelative("sideCount"); SerializedProperty inverseSDFProp = property.FindPropertyRelative("inverseSDF"); rect = GetNextRect(); if ((tmp = EditorGUI.Slider(rect, Styles.edgeOffset, edgeOffsetProp.floatValue, 0.0f, 1.0f)) != edgeOffsetProp.floatValue) { edgeOffsetProp.floatValue = Mathf.Clamp01(tmp); } rect = GetNextRect(); if ((tmp = EditorGUI.Slider(rect, Styles.fallOff, fallOffProp.floatValue, 0.0f, 1.0f)) != fallOffProp.floatValue) { fallOffProp.floatValue = Mathf.Max(tmp, 0.0f); } if (newType == SRPLensFlareType.Polygon) { rect = GetNextRect(); if ((tmp = EditorGUI.IntSlider(rect, Styles.sideCount, sideCountProp.intValue, 3, 32)) != sideCountProp.intValue) { sideCountProp.intValue = (int)Mathf.Max(tmp, 0); } rect = GetNextRect(); if ((tmp = EditorGUI.Slider(rect, Styles.sdfRoundness, sdfRoundnessProp.floatValue, 0.0f, 1.0f)) != sdfRoundnessProp.floatValue) { sdfRoundnessProp.floatValue = Mathf.Clamp01(tmp); } } rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.inverseSDF, inverseSDFProp.boolValue)) != inverseSDFProp.boolValue) { inverseSDFProp.boolValue = tmpBool; } } } rect = GetNextRect(); EditorGUI.TextArea(rect, Styles.colorElement.text, EditorStyles.boldLabel); { rect = GetNextRect(); if ((tmpCol = EditorGUI.ColorField(rect, Styles.tint, tintProp.colorValue)) != tintProp.colorValue) { tintProp.colorValue = tmpCol; } rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.modulateByLightColor, modulateByLightColor.boolValue)) != modulateByLightColor.boolValue) { modulateByLightColor.boolValue = tmpBool; } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.intensity, intensityProp.floatValue)) != intensityProp.floatValue) { intensityProp.floatValue = Mathf.Max(tmp, 0.0f); } rect = GetNextRect(); SRPLensFlareBlendMode newBlendMode; SRPLensFlareBlendMode blendModeValue = (UnityEngine.SRPLensFlareBlendMode)blendModeProp.enumValueIndex; if ((newBlendMode = ((SRPLensFlareBlendMode)(EditorGUI.EnumPopup(rect, Styles.blendMode, blendModeValue)))) != blendModeValue) { blendModeProp.enumValueIndex = (int)newBlendMode; } } rect = GetNextRect(); EditorGUI.TextArea(rect, Styles.transformElement.text, EditorStyles.boldLabel); { rect = GetNextRect(); if ((tmpVec2 = EditorGUI.Vector2Field(rect, Styles.positionOffset, positionOffsetProp.vector2Value)) != positionOffsetProp.vector2Value) { positionOffsetProp.vector2Value = tmpVec2; } rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.autoRotate, autoRotateProp.boolValue)) != autoRotateProp.boolValue) { autoRotateProp.boolValue = tmpBool; } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.rotation, rotationProp.floatValue)) != rotationProp.floatValue) { rotationProp.floatValue = tmp; } rect = GetNextRect(); if ((tmpVec2 = EditorGUI.Vector2Field(rect, Styles.sizeXY, sizeXYProp.vector2Value)) != sizeXYProp.vector2Value) { sizeXYProp.vector2Value = new Vector2(Mathf.Max(tmpVec2.x, 1e-6f), Mathf.Max(tmpVec2.y, 1e-6f)); } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.uniformScale, uniformScaleProp.floatValue)) != uniformScaleProp.floatValue) { uniformScaleProp.floatValue = Mathf.Max(tmp, 0.0f); } } rect = GetNextRect(); EditorGUI.TextArea(rect, Styles.axisTransformElement.text, EditorStyles.boldLabel); { rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.position, positionProp.floatValue)) != positionProp.floatValue) { positionProp.floatValue = tmp; } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.angularOffset, angularOffsetProp.floatValue)) != angularOffsetProp.floatValue) { angularOffsetProp.floatValue = tmp; } rect = GetNextRect(); if ((tmpVec2 = EditorGUI.Vector2Field(rect, Styles.translationScale, translationScaleProp.vector2Value)) != translationScaleProp.vector2Value) { translationScaleProp.vector2Value = tmpVec2; } } rect = GetNextRect(); EditorGUI.TextArea(rect, Styles.radialDistortionElement.text, EditorStyles.boldLabel); { rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.enableDistortion, enableDistortionProp.boolValue)) != enableDistortionProp.boolValue) { enableDistortionProp.boolValue = tmpBool; } if (enableDistortionProp.boolValue == true) { rect = GetNextRect(); if ((tmpVec2 = EditorGUI.Vector2Field(rect, Styles.targetSizeDistortion, targetSizeDistortionProp.vector2Value)) != targetSizeDistortionProp.vector2Value) { targetSizeDistortionProp.vector2Value = tmpVec2; } rect = GetNextRect(); EditorGUI.PropertyField(rect, distortionCurveProp, Styles.distortionCurve); rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.distortionRelativeToCenter, distortionRelativeToCenterProp.boolValue)) != distortionRelativeToCenterProp.boolValue) { distortionRelativeToCenterProp.boolValue = tmpBool; } } } rect = GetNextRect(); EditorGUI.TextArea(rect, Styles.multipleElementsElement.text, EditorStyles.boldLabel); { rect = GetNextRect(); if ((tmpBool = EditorGUI.Toggle(rect, Styles.allowMultipleElement, allowMultipleElementProp.boolValue)) != allowMultipleElementProp.boolValue) { allowMultipleElementProp.boolValue = tmpBool; } if (allowMultipleElementProp.boolValue) { rect = GetNextRect(); if ((iTmp = EditorGUI.IntField(rect, Styles.count, countProp.intValue)) != countProp.intValue) { countProp.intValue = Mathf.Clamp(iTmp, 2, 4096); // 4096 is large enough for all imaginable use case (I hope) } } if (allowMultipleElementProp.boolValue) { rect = GetNextRect(); SRPLensFlareDistribution newDistribution; SRPLensFlareDistribution distributionValue = (UnityEngine.SRPLensFlareDistribution)distributionProp.enumValueIndex; if ((newDistribution = ((SRPLensFlareDistribution)(EditorGUI.EnumPopup(rect, Styles.distribution, distributionValue)))) != distributionValue) { distributionProp.enumValueIndex = (int)newDistribution; } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.lengthSpread, lengthSpreadProp.floatValue)) != lengthSpreadProp.floatValue) { lengthSpreadProp.floatValue = tmp; } if (newDistribution == SRPLensFlareDistribution.Uniform) { rect = GetNextRect(); EditorGUI.PropertyField(rect, colorGradientProp, Styles.colors); } else if (newDistribution == SRPLensFlareDistribution.Random) { rect = GetNextRect(); if ((iTmp = EditorGUI.IntField(rect, Styles.seed, seedProp.intValue)) != seedProp.intValue) { seedProp.intValue = Mathf.Max(iTmp, 0); } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.intensityVariation, intensityVariationProp.floatValue)) != intensityVariationProp.floatValue) { intensityVariationProp.floatValue = Mathf.Clamp01(tmp); } rect = GetNextRect(); EditorGUI.PropertyField(rect, colorGradientProp, Styles.colors); rect = GetNextRect(); if ((tmpVec2 = EditorGUI.Vector2Field(rect, Styles.positionVariation, positionVariationProp.vector2Value)) != positionVariationProp.vector2Value) { positionVariationProp.vector2Value = tmpVec2; } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.rotationVariation, rotationVariationProp.floatValue)) != rotationVariationProp.floatValue) { rotationVariationProp.floatValue = Mathf.Max(tmp, 0.0f); } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.scaleVariation, scaleVariationProp.floatValue)) != scaleVariationProp.floatValue) { scaleVariationProp.floatValue = Mathf.Max(tmp, 0.0f); } } else if (newDistribution == SRPLensFlareDistribution.Curve) { rect = GetNextRect(); EditorGUI.PropertyField(rect, colorGradientProp, Styles.colors); rect = GetNextRect(); EditorGUI.PropertyField(rect, positionCurveProp, Styles.positionCurve); rect = GetNextRect(); EditorGUI.PropertyField(rect, scaleCurveProp, Styles.scaleCurve); } } } isFoldOpenedProp.boolValue = true; } else { rect = GetNextRect(35.0f); SRPLensFlareType newType; SRPLensFlareType typeValue = (UnityEngine.SRPLensFlareType)flareTypeProp.enumValueIndex; if ((newType = ((SRPLensFlareType)(EditorGUI.EnumPopup(rect, Styles.flareType, typeValue)))) != typeValue) { flareTypeProp.enumValueIndex = (int)newType; } rect = GetNextRect(); if ((tmpCol = EditorGUI.ColorField(rect, Styles.tint, tintProp.colorValue)) != tintProp.colorValue) { tintProp.colorValue = tmpCol; } rect = GetNextRect(); if ((tmp = EditorGUI.FloatField(rect, Styles.intensity, intensityProp.floatValue)) != intensityProp.floatValue) { intensityProp.floatValue = Mathf.Max(tmp, 0.0f); } if (allowMultipleElementProp.boolValue) { rect = GetNextRect(); if ((iTmp = EditorGUI.IntField(rect, Styles.count, countProp.intValue)) != countProp.intValue) { countProp.intValue = Mathf.Max(iTmp, 2); } } isFoldOpenedProp.boolValue = false; } EditorGUI.EndFoldoutHeaderGroup(); EditorGUI.EndProperty(); }