Exemple #1
0
        /// <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();
                }
            }