/// <summary> /// Bakes the <paramref name="probe" /> and updates its baked texture. /// /// Note: The update of the probe is persistent only in editor mode. /// </summary> /// <param name="probe">The probe to bake.</param> /// <param name="path">The asset path to write the baked texture to.</param> /// <param name="options">The options to use for the bake.</param> /// <returns> /// Returns <c>null</c> if successful. Otherwise, returns the error that occured. /// The error can be: /// * <see cref="ArgumentException" /> if the <paramref name="path" /> is invalid. /// * <see cref="ArgumentNullException" /> if the <paramref name="probe" /> is <c>null</c>. /// * <see cref="Exception" /> if the <paramref name="probe" /> is not supported. Only /// This functional currently only supports <see cref="HDAdditionalReflectionData" /> probes. /// </returns> public static Exception BakeProbe([NotNull] HDProbe probe, [NotNull] string path, BakeProbeOptions options) { // Check arguments if (probe == null || probe.Equals(null)) { return(new ArgumentNullException(nameof(probe))); } if (string.IsNullOrEmpty(path)) { return(new ArgumentException($"{nameof(path)} must not be empty or null.")); } // We force RGBAHalf as we don't support 11-11-10 textures (only RT) var probeFormat = GraphicsFormat.R16G16B16A16_SFloat; switch (probe) { case HDAdditionalReflectionData _: { // Get the texture size from the probe var textureSize = options.textureSize.Evaluate(probe); // Render and write var cubeRT = HDRenderUtilities.CreateReflectionProbeRenderTarget(textureSize, probeFormat); HDBakedReflectionSystem.RenderAndWriteToFile(probe, path, cubeRT, null); cubeRT.Release(); // Import asset at target location AssetDatabase.ImportAsset(path); HDBakedReflectionSystem.ImportAssetAt(probe, path); // Assign to the probe the baked texture var bakedTexture = AssetDatabase.LoadAssetAtPath <Texture>(path); probe.SetTexture(ProbeSettings.Mode.Baked, bakedTexture); // Mark probe as dirty EditorUtility.SetDirty(probe); return(null); } case PlanarReflectionProbe _: return(new Exception("Planar reflection probe baking is not supported.")); default: return(new Exception($"Cannot handle probe type: {probe.GetType()}")); } }
static void RenderInCustomAsset(HDProbe probe, bool useExistingCustomAsset) { var provider = new TProvider(); string assetPath = null; if (useExistingCustomAsset && probe.customTexture != null && !probe.customTexture.Equals(null)) { assetPath = AssetDatabase.GetAssetPath(probe.customTexture); } if (string.IsNullOrEmpty(assetPath)) { assetPath = EditorUtility.SaveFilePanelInProject( "Save custom capture", probe.name, "exr", "Save custom capture"); } if (!string.IsNullOrEmpty(assetPath)) { var target = (RenderTexture)HDProbeSystem.CreateRenderTargetForMode( probe, ProbeSettings.Mode.Custom ); HDBakedReflectionSystem.RenderAndWriteToFile( probe, assetPath, target, null, out var cameraSettings, out var cameraPositionSettings ); AssetDatabase.ImportAsset(assetPath); HDBakedReflectionSystem.ImportAssetAt(probe, assetPath); CoreUtils.Destroy(target); var assetTarget = AssetDatabase.LoadAssetAtPath <Texture>(assetPath); probe.SetTexture(ProbeSettings.Mode.Custom, assetTarget); probe.SetRenderData(ProbeSettings.Mode.Custom, new HDProbe.RenderData(cameraSettings, cameraPositionSettings)); EditorUtility.SetDirty(probe); } }
public static void DrawBakeButton(SerializedHDProbe serialized, Editor owner) { // Disable baking of multiple probes with different modes if (serialized.probeSettings.mode.hasMultipleDifferentValues) { EditorGUILayout.HelpBox( "Baking is not possible when selecting probe with different modes", MessageType.Info ); return; } // Check if current mode support baking var mode = (ProbeSettings.Mode)serialized.probeSettings.mode.intValue; var doesModeSupportBaking = mode == ProbeSettings.Mode.Custom || mode == ProbeSettings.Mode.Baked; if (!doesModeSupportBaking) { return; } // Check if all scene are saved to a file (requirement to bake probes) foreach (var target in serialized.serializedObject.targetObjects) { var comp = (Component)target; var go = comp.gameObject; var scene = go.scene; if (string.IsNullOrEmpty(scene.path)) { EditorGUILayout.HelpBox( "Baking is possible only if all open scenes are saved on disk. " + "Please save the scenes before baking.", MessageType.Info ); return; } } switch (mode) { case ProbeSettings.Mode.Custom: { if (ButtonWithDropdownList( EditorGUIUtility.TrTextContent( "Bake", "Bakes Probe's texture, overwriting the existing texture asset (if any)." ), k_BakeCustomOptionText, data => { switch ((int)data) { case 0: RenderInCustomAsset(serialized.target, false); break; } })) { RenderInCustomAsset(serialized.target, true); } break; } case ProbeSettings.Mode.Baked: { if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.OnDemand) { EditorGUILayout.HelpBox("Baking of this probe is automatic because this probe's type is 'Baked' and the Lighting window is using 'Auto Baking'. The texture created is stored in the GI cache.", MessageType.Info); break; } GUI.enabled = serialized.target.enabled; // Bake button in non-continous mode if (ButtonWithDropdownList( EditorGUIUtility.TrTextContent("Bake"), k_BakeButtonsText, data => { if ((int)data == 0) { var system = ScriptableBakedReflectionSystemSettings.system; system.BakeAllReflectionProbes(); } }, GUILayout.ExpandWidth(true))) { HDBakedReflectionSystem.BakeProbes(serialized.serializedObject.targetObjects.OfType <HDProbe>().ToArray()); GUIUtility.ExitGUI(); } GUI.enabled = true; break; } case ProbeSettings.Mode.Realtime: break; default: throw new ArgumentOutOfRangeException(); } }