using System.Reflection; using UnityEditor; #if UNITY_2020_2_OR_NEWER using UnityEditor.AssetImporters; #else using UnityEditor.Experimental.AssetImporters; #endif using UnityEngine; using UnityEngine.Rendering; namespace UnityEditor.Rendering { /// /// Common class for IES Importer Editor (currently implemented only on HDRP) /// public class IESImporterEditor { GUIStyle m_WordWrapStyle = new GUIStyle(); SerializedProperty m_FileFormatVersionProp; SerializedProperty m_IESPhotometricTypeProp; SerializedProperty m_IESMaximumIntensityProp; SerializedProperty m_IESMaximumIntensityUnitProp; SerializedProperty m_ManufacturerProp; SerializedProperty m_LuminaireCatalogNumberProp; SerializedProperty m_LuminaireDescriptionProp; SerializedProperty m_LampCatalogNumberProp; SerializedProperty m_LampDescriptionProp; SerializedProperty m_PrefabLightTypeProp; SerializedProperty m_SpotAngleProp; SerializedProperty m_IESSizeProp; SerializedProperty m_ApplyLightAttenuationProp; SerializedProperty m_UseIESMaximumIntensityProp; SerializedProperty m_CookieCompressionProp; /// /// Property to the aim axis rotation for projection /// protected SerializedProperty m_LightAimAxisRotationProp; bool m_ShowLuminaireProductInformation = true; bool m_ShowLightProperties = true; /// /// Object used to setup Preview renderer /// protected PreviewRenderUtility m_PreviewRenderUtility = null; /// /// Delegate prototype sent by the specialization of the IESImporterEditor per Render Pipeline /// public delegate void LayoutRenderPipelineUseIesMaximumIntensity(); /// /// Delegate prototype sent by the specialization of the IESImporterEditor per Render Pipeline /// /// Current camera public delegate void SetupRenderPipelinePreviewCamera(Camera camera); /// /// Delegate prototype sent by the specialization of the IESImporterEditor per Render Pipeline /// /// Light will be setuped, specialization for a given SRP public delegate void SetupRenderPipelinePreviewLight(Light light); /// /// Delegate prototype sent by the specialization of the IESImporterEditor per Render Pipeline /// /// Setup a wall for the preview public delegate void SetupRenderPipelinePreviewWallRenderer(MeshRenderer wallRenderer); /// /// Delegate prototype sent by the specialization of the IESImporterEditor per Render Pipeline /// /// Setup a floor for the preview public delegate void SetupRenderPipelinePreviewFloorRenderer(MeshRenderer floorRenderer); /// /// Delegate prototype sent by the specialization of the IESImporterEditor per Render Pipeline /// /// Light used to setup the IES /// Serialized property to the "useIESMaximumIntensity" property /// Serialized property to the "iesMaximumIntensityUnit" property /// Serialized property to the "iesMaximumIntensity" property public delegate void SetupRenderPipelinePreviewLightIntensity(Light light, SerializedProperty useIESMaximumIntensityProp, SerializedProperty iesMaximumIntensityUnitProp, SerializedProperty iesMaximumIntensityProp); /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// /// Serialized object which can be linked to IESMetadata public void CommonOnEnable(SerializedProperty serializedObject) { m_WordWrapStyle.wordWrap = true; m_FileFormatVersionProp = serializedObject.FindPropertyRelative("FileFormatVersion"); m_IESPhotometricTypeProp = serializedObject.FindPropertyRelative("IESPhotometricType"); m_IESMaximumIntensityProp = serializedObject.FindPropertyRelative("IESMaximumIntensity"); m_IESMaximumIntensityUnitProp = serializedObject.FindPropertyRelative("IESMaximumIntensityUnit"); m_ManufacturerProp = serializedObject.FindPropertyRelative("Manufacturer"); m_LuminaireCatalogNumberProp = serializedObject.FindPropertyRelative("LuminaireCatalogNumber"); m_LuminaireDescriptionProp = serializedObject.FindPropertyRelative("LuminaireDescription"); m_LampCatalogNumberProp = serializedObject.FindPropertyRelative("LampCatalogNumber"); m_LampDescriptionProp = serializedObject.FindPropertyRelative("LampDescription"); m_PrefabLightTypeProp = serializedObject.FindPropertyRelative("PrefabLightType"); m_SpotAngleProp = serializedObject.FindPropertyRelative("SpotAngle"); m_IESSizeProp = serializedObject.FindPropertyRelative("iesSize"); m_ApplyLightAttenuationProp = serializedObject.FindPropertyRelative("ApplyLightAttenuation"); m_UseIESMaximumIntensityProp = serializedObject.FindPropertyRelative("UseIESMaximumIntensity"); m_CookieCompressionProp = serializedObject.FindPropertyRelative("CookieCompression"); m_LightAimAxisRotationProp = serializedObject.FindPropertyRelative("LightAimAxisRotation"); } /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// /// The current specialized scripted importer using the common code public void CommonOnInspectorGUI(ScriptedImporterEditor scriptedImporter) { scriptedImporter.serializedObject.Update(); EditorGUILayout.LabelField("File Format Version", m_FileFormatVersionProp.stringValue); EditorGUILayout.LabelField("Photometric Type", m_IESPhotometricTypeProp.stringValue); EditorGUILayout.LabelField("Maximum Intensity", $"{m_IESMaximumIntensityProp.floatValue} {m_IESMaximumIntensityUnitProp.stringValue}"); if (m_ShowLuminaireProductInformation = EditorGUILayout.Foldout(m_ShowLuminaireProductInformation, "Luminaire Product Information")) { EditorGUILayout.LabelField(m_ManufacturerProp.displayName, m_ManufacturerProp.stringValue, m_WordWrapStyle); EditorGUILayout.LabelField(m_LuminaireCatalogNumberProp.displayName, m_LuminaireCatalogNumberProp.stringValue, m_WordWrapStyle); EditorGUILayout.LabelField(m_LuminaireDescriptionProp.displayName, m_LuminaireDescriptionProp.stringValue, m_WordWrapStyle); EditorGUILayout.LabelField(m_LampCatalogNumberProp.displayName, m_LampCatalogNumberProp.stringValue, m_WordWrapStyle); EditorGUILayout.LabelField(m_LampDescriptionProp.displayName, m_LampDescriptionProp.stringValue, m_WordWrapStyle); } if (m_ShowLightProperties = EditorGUILayout.Foldout(m_ShowLightProperties, "Light and Cookie Properties")) { EditorGUILayout.PropertyField(m_PrefabLightTypeProp, new GUIContent("Light Type")); EditorGUILayout.PropertyField(m_SpotAngleProp); EditorGUILayout.PropertyField(m_IESSizeProp, new GUIContent("IES Size")); EditorGUILayout.PropertyField(m_ApplyLightAttenuationProp); EditorGUILayout.PropertyField(m_CookieCompressionProp, new GUIContent("IES Compression")); // Before enabling this feature, more experimentation is needed with the addition of a Volume in the PreviewRenderUtility scene. EditorGUILayout.PropertyField(m_UseIESMaximumIntensityProp, new GUIContent("Use IES Maximum Intensity")); using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.PropertyField(m_LightAimAxisRotationProp, new GUIContent("Aim Axis Rotation")); if (GUILayout.Button("Reset", GUILayout.Width(44))) { m_LightAimAxisRotationProp.floatValue = -90f; } } } scriptedImporter.serializedObject.ApplyModifiedProperties(); } /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// public void CommonApply() { if (m_PreviewRenderUtility != null) { m_PreviewRenderUtility.Cleanup(); m_PreviewRenderUtility = null; } } /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// /// Delegate provided by the Render pipeline to setup the Preview Camera /// Delegate provided by the Render pipeline to setup the Preview Light /// Delegate provided by the Render pipeline to setup the Preview Wall /// Delegate provided by the Render pipeline to setup the Preview Floor /// true to specified IES has a Preview public bool CommonHasPreviewGUI(SetupRenderPipelinePreviewCamera setupRenderPipelinePreviewCamera, SetupRenderPipelinePreviewLight setupRenderPipelinePreviewLight, SetupRenderPipelinePreviewWallRenderer setupRenderPipelinePreviewWallRenderer, SetupRenderPipelinePreviewFloorRenderer setupRenderPipelinePreviewFloorRenderer) { if (m_PreviewRenderUtility == null) { m_PreviewRenderUtility = new PreviewRenderUtility(); m_PreviewRenderUtility.ambientColor = Color.black; m_PreviewRenderUtility.camera.fieldOfView = 60f; m_PreviewRenderUtility.camera.nearClipPlane = 0.1f; m_PreviewRenderUtility.camera.farClipPlane = 10f; m_PreviewRenderUtility.camera.transform.localPosition = new Vector3(1.85f, 0.71f, 0f); m_PreviewRenderUtility.camera.transform.localEulerAngles = new Vector3(15f, -90f, 0f); setupRenderPipelinePreviewCamera(m_PreviewRenderUtility.camera); m_PreviewRenderUtility.lights[0].type = (m_PrefabLightTypeProp.enumValueIndex == (int)IESLightType.Point) ? LightType.Point : LightType.Spot; m_PreviewRenderUtility.lights[0].color = Color.white; m_PreviewRenderUtility.lights[0].intensity = 1f; m_PreviewRenderUtility.lights[0].range = 10f; m_PreviewRenderUtility.lights[0].spotAngle = m_SpotAngleProp.floatValue; m_PreviewRenderUtility.lights[0].transform.localPosition = new Vector3(0.14f, 1f, 0f); m_PreviewRenderUtility.lights[0].transform.localEulerAngles = new Vector3(90f, 0f, -90f); setupRenderPipelinePreviewLight(m_PreviewRenderUtility.lights[0]); m_PreviewRenderUtility.lights[1].intensity = 0f; GameObject previewWall = GameObject.CreatePrimitive(PrimitiveType.Plane); previewWall.name = "IESPreviewWall"; previewWall.hideFlags = HideFlags.HideAndDontSave; previewWall.transform.localPosition = new Vector3(0f, 4f, 0f); previewWall.transform.localEulerAngles = new Vector3(0f, 0f, -90f); previewWall.transform.localScale = new Vector3(1f, 1f, 10f); MeshRenderer previewWallRenderer = previewWall.GetComponent(); previewWallRenderer.lightProbeUsage = LightProbeUsage.Off; previewWallRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off; previewWallRenderer.material = AssetDatabase.GetBuiltinExtraResource("Default-Material.mat"); setupRenderPipelinePreviewWallRenderer(previewWallRenderer); m_PreviewRenderUtility.AddSingleGO(previewWall); GameObject previewFloor = GameObject.CreatePrimitive(PrimitiveType.Plane); previewFloor.name = "IESPreviewFloor"; previewFloor.hideFlags = HideFlags.HideAndDontSave; previewFloor.transform.localPosition = new Vector3(4f, 0f, 0f); previewFloor.transform.localEulerAngles = new Vector3(0f, 0f, 0f); previewFloor.transform.localScale = new Vector3(1f, 1f, 10f); MeshRenderer previewFloorRenderer = previewFloor.GetComponent(); previewFloorRenderer.lightProbeUsage = LightProbeUsage.Off; previewFloorRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off; previewFloorRenderer.material = AssetDatabase.GetBuiltinExtraResource("Default-Diffuse.mat"); setupRenderPipelinePreviewFloorRenderer(previewFloorRenderer); m_PreviewRenderUtility.AddSingleGO(previewFloor); } return true; } /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// /// The title of the Preview public GUIContent CommonGetPreviewTitle() { return new GUIContent("IES Luminaire Profile"); } /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// /// Background of the Preview /// Rect of the Preview /// ScriptedImporter targeted /// Delegate provided by the Rendering Pipeline to setup the Light Intensity public void CommonOnPreviewGUI(Rect r, GUIStyle background, ScriptedImporter target, SetupRenderPipelinePreviewLightIntensity setupRenderPipelinePreviewLightIntensity) { if (Event.current.type == EventType.Repaint) { Texture cookieTexture = null; Texture previewTexture = null; if (m_PrefabLightTypeProp.enumValueIndex == (int)IESLightType.Point) { foreach (var subAsset in AssetDatabase.LoadAllAssetRepresentationsAtPath(target.assetPath)) { if (subAsset.name.EndsWith("-Cube-IES")) { cookieTexture = subAsset as Texture; break; } } } else // LightType.Spot { foreach (var subAsset in AssetDatabase.LoadAllAssetRepresentationsAtPath(target.assetPath)) { if (subAsset.name.EndsWith("-2D-IES")) { cookieTexture = subAsset as Texture; break; } } } if (cookieTexture != null) { m_PreviewRenderUtility.lights[0].transform.localEulerAngles = new Vector3(90f, 0f, m_LightAimAxisRotationProp.floatValue); setupRenderPipelinePreviewLightIntensity(m_PreviewRenderUtility.lights[0], m_UseIESMaximumIntensityProp, m_IESMaximumIntensityUnitProp, m_IESMaximumIntensityProp); m_PreviewRenderUtility.lights[0].cookie = cookieTexture; m_PreviewRenderUtility.lights[0].type = m_PrefabLightTypeProp.enumValueIndex == (int)IESLightType.Point ? LightType.Point : LightType.Spot; m_PreviewRenderUtility.BeginPreview(r, background); bool fog = RenderSettings.fog; Unsupported.SetRenderSettingsUseFogNoDirty(false); m_PreviewRenderUtility.camera.Render(); Unsupported.SetRenderSettingsUseFogNoDirty(fog); previewTexture = m_PreviewRenderUtility.EndPreview(); } if (previewTexture == null) { GUI.DrawTexture(r, Texture2D.blackTexture, ScaleMode.StretchToFill, false); } else { GUI.DrawTexture(r, previewTexture, ScaleMode.ScaleToFit, false); } } } /// /// Callback called on the Implemented IESImporterEditor (currently on HDRP Only) /// public void CommonOnDisable() { if (m_PreviewRenderUtility != null) { m_PreviewRenderUtility.Cleanup(); m_PreviewRenderUtility = null; } } } }