Exemplo n.º 1
0
        static public void CreateInfluenceVolumes(Vector3Int cellPos,
                                                  Renderer[] renderers, ProbeVolume[] probeVolumes,
                                                  ProbeReferenceVolumeAuthoring settings, Matrix4x4 cellTrans, out List <Volume> culledVolumes, out Dictionary <Scene, int> sceneRefs)
        {
            Volume cellVolume = new Volume();

            cellVolume.corner = new Vector3(cellPos.x * settings.cellSize, cellPos.y * settings.cellSize, cellPos.z * settings.cellSize);
            cellVolume.X      = new Vector3(settings.cellSize, 0, 0);
            cellVolume.Y      = new Vector3(0, settings.cellSize, 0);
            cellVolume.Z      = new Vector3(0, 0, settings.cellSize);
            cellVolume.Transform(cellTrans);

            // Keep track of volumes and which scene they originated from
            sceneRefs = new Dictionary <Scene, int>();

            // Extract all influencers inside the cell
            List <Volume> influenceVolumes = new List <Volume>();

            RenderersToVolumes(ref renderers, ref cellVolume, ref influenceVolumes, ref sceneRefs);
            NavPathsToVolumes(ref cellVolume, ref influenceVolumes, ref sceneRefs);
            ImportanceVolumesToVolumes(ref cellVolume, ref influenceVolumes, ref sceneRefs);
            LightsToVolumes(ref cellVolume, ref influenceVolumes, ref sceneRefs);

            // Extract all ProbeVolumes inside the cell
            List <Volume> indicatorVolumes = new List <Volume>();

            ProbeVolumesToVolumes(ref probeVolumes, ref cellVolume, ref indicatorVolumes, ref sceneRefs);

            // Cull all influencers against ProbeVolumes
            culledVolumes = new List <Volume>();
            CullVolumes(ref influenceVolumes, ref indicatorVolumes, ref culledVolumes);
        }
Exemplo n.º 2
0
        public void OnSceneGUI()
        {
            ProbeReferenceVolumeAuthoring pvra = target as ProbeReferenceVolumeAuthoring;

            if (Event.current.type == EventType.Layout)
            {
                pvra.DrawProbeGizmos();
            }
        }
Exemplo n.º 3
0
        private static void OnBakeStarted()
        {
            if (ShaderConfig.s_EnableProbeVolumes == 1)
            {
                bakingReferenceVolumeAuthoring = GetCardinalAuthoringComponent();

                if (bakingReferenceVolumeAuthoring == null)
                {
                    Debug.Log("Scene(s) have multiple inconsistent ProbeReferenceVolumeAuthoring components. Please ensure they use identical profiles and transforms before baking.");
                    return;
                }

                RunPlacement();
            }
        }
Exemplo n.º 4
0
        private static void OnAdditionalProbesBakeCompleted()
        {
            UnityEditor.Experimental.Lightmapping.additionalBakedProbesCompleted -= OnAdditionalProbesBakeCompleted;

            var numCells = bakingCells.Count;

            // Fetch results of all cells
            for (int c = 0; c < numCells; ++c)
            {
                var cell = bakingCells[c];

                if (cell.probePositions == null)
                {
                    continue;
                }

                int numProbes = cell.probePositions.Length;
                Debug.Assert(numProbes > 0);

                var sh       = new NativeArray <SphericalHarmonicsL2>(numProbes, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
                var validity = new NativeArray <float>(numProbes, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
                var bakedProbeOctahedralDepth = new NativeArray <float>(numProbes * 64, Allocator.Temp, NativeArrayOptions.UninitializedMemory);

                UnityEditor.Experimental.Lightmapping.GetAdditionalBakedProbes(cell.index, sh, validity, bakedProbeOctahedralDepth);

                cell.sh       = new SphericalHarmonicsL1[numProbes];
                cell.validity = new float[numProbes];
                for (int i = 0; i < numProbes; ++i)
                {
                    Vector4[] channels = new Vector4[3];

                    // compare to SphericalHarmonicsL2::GetShaderConstantsFromNormalizedSH
                    channels[0] = new Vector4(sh[i][0, 3], sh[i][0, 1], sh[i][0, 2], sh[i][0, 0]);
                    channels[1] = new Vector4(sh[i][1, 3], sh[i][1, 1], sh[i][1, 2], sh[i][1, 0]);
                    channels[2] = new Vector4(sh[i][2, 3], sh[i][2, 1], sh[i][2, 2], sh[i][2, 0]);

                    // It can be shown that |L1_i| <= |2*L0|
                    // Precomputed Global Illumination in Frostbite by Yuriy O'Donnell.
                    // https://media.contentapi.ea.com/content/dam/eacom/frostbite/files/gdc2018-precomputedgiobalilluminationinfrostbite.pdf
                    //
                    // So divide by L0 brings us to [-2, 2],
                    // divide by 4 brings us to [-0.5, 0.5],
                    // and plus by 0.5 brings us to [0, 1].
                    for (int channel = 0; channel < 3; ++channel)
                    {
                        var l0 = channels[channel][3];

                        if (l0 != 0.0f)
                        {
                            for (int axis = 0; axis < 3; ++axis)
                            {
                                channels[channel][axis] = channels[channel][axis] / (l0 * 4.0f) + 0.5f;
                                Debug.Assert(channels[channel][axis] >= 0.0f && channels[channel][axis] <= 1.0f);
                            }
                        }
                    }

                    SphericalHarmonicsL1 sh1 = new SphericalHarmonicsL1();
                    sh1.shAr = channels[0];
                    sh1.shAg = channels[1];
                    sh1.shAb = channels[2];

                    cell.sh[i]       = sh1;
                    cell.validity[i] = validity[i];
                }

                // Reset index
                UnityEditor.Experimental.Lightmapping.SetAdditionalBakedProbes(cell.index, null);

                DilateInvalidProbes(cell.probePositions, cell.bricks, cell.sh, cell.validity, bakingReferenceVolumeAuthoring.GetDilationSettings());

                ProbeReferenceVolume.instance.cells[cell.index] = cell;
            }

            // Map from each scene to an existing reference volume
            var scene2RefVol = new Dictionary <Scene, ProbeReferenceVolumeAuthoring>();

            foreach (var refVol in GameObject.FindObjectsOfType <ProbeReferenceVolumeAuthoring>())
            {
                if (refVol.enabled)
                {
                    scene2RefVol[refVol.gameObject.scene] = refVol;
                }
            }

            // Map from each reference volume to its asset
            var refVol2Asset = new Dictionary <ProbeReferenceVolumeAuthoring, ProbeVolumeAsset>();

            foreach (var refVol in scene2RefVol.Values)
            {
                refVol2Asset[refVol] = ProbeVolumeAsset.CreateAsset(refVol.gameObject.scene);
            }

            // Put cells into the respective assets
            foreach (var cell in ProbeReferenceVolume.instance.cells.Values)
            {
                foreach (var scene in cellIndex2SceneReferences[cell.index])
                {
                    // This scene has a reference volume authoring component in it?
                    ProbeReferenceVolumeAuthoring refVol = null;
                    if (scene2RefVol.TryGetValue(scene, out refVol))
                    {
                        var asset = refVol2Asset[refVol];
                        asset.cells.Add(cell);
                    }
                }
            }

            // Connect the assets to their components
            foreach (var pair in refVol2Asset)
            {
                var refVol = pair.Key;
                var asset  = pair.Value;

                refVol.volumeAsset = asset;

                if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.Iterative)
                {
                    UnityEditor.EditorUtility.SetDirty(refVol);
                    UnityEditor.EditorUtility.SetDirty(refVol.volumeAsset);
                }
            }

            UnityEditor.AssetDatabase.SaveAssets();
            UnityEditor.AssetDatabase.Refresh();

            foreach (var refVol in refVol2Asset.Keys)
            {
                if (refVol.enabled && refVol.gameObject.activeSelf)
                {
                    refVol.QueueAssetLoading();
                }
            }
        }
Exemplo n.º 5
0
        public override void OnInspectorGUI()
        {
            if (ShaderConfig.s_EnableProbeVolumes == 0)
            {
                EditorGUILayout.HelpBox("Warning: Probe Volumes are not enabled.\nIt is an highly experimental feature and disabled by default for this reason.\n Its functionality is subject to breaking changes and whole sale removal.\nIt is not recommended for use outside of for providing feedback.\n" +
                                        "It should not be used in production.\nTo enable, set:\nEnableProbeVolumes = 1\ninside of ShaderConfig.cs\and inside of the editor run:" +
                                        "\nEdit->Render Pipeline->Generate Shader Includes\nProbe Volumes feature must also be enabled here.",
                                        MessageType.Warning, wide: true);

                return;
            }

            serializedObject.Update();

            var  probeReferenceVolumes = FindObjectsOfType <ProbeReferenceVolumeAuthoring>();
            bool foundInconsistency    = false;

            if (probeReferenceVolumes.Length > 1)
            {
                foreach (var o1 in probeReferenceVolumes)
                {
                    foreach (var o2 in probeReferenceVolumes)
                    {
                        if (!o1.profile.IsEquivalent(o2.profile) && !foundInconsistency)
                        {
                            EditorGUILayout.HelpBox("Multiple Probe Reference Volume components are loaded, but they have different profiles. "
                                                    + "This is unsupported, please make sure all loaded Probe Reference Volume have the same profile or profiles with equal values.", MessageType.Error, wide: true);
                            foundInconsistency = true;
                        }
                        if (foundInconsistency)
                        {
                            break;
                        }
                    }
                }
            }

            EditorGUI.BeginChangeCheck();

            // The layout system breaks alignment when mixing inspector fields with custom layout'd
            // fields, do the layout manually instead
            int   buttonWidth   = 60;
            float indentOffset  = EditorGUI.indentLevel * 15f;
            var   lineRect      = EditorGUILayout.GetControlRect();
            var   labelRect     = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
            var   fieldRect     = new Rect(labelRect.xMax, lineRect.y, lineRect.width - labelRect.width - buttonWidth, lineRect.height);
            var   buttonNewRect = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height);

            GUIContent guiContent = EditorGUIUtility.TrTextContent("Profile", "A reference to a profile asset.");

            EditorGUI.PrefixLabel(labelRect, guiContent);

            using (var scope = new EditorGUI.ChangeCheckScope())
            {
                EditorGUI.BeginProperty(fieldRect, GUIContent.none, m_Profile);

                m_Profile.objectReferenceValue = (ProbeReferenceVolumeProfile)EditorGUI.ObjectField(fieldRect, m_Profile.objectReferenceValue, typeof(ProbeReferenceVolumeProfile), false);

                EditorGUI.EndProperty();
            }

            if (GUI.Button(buttonNewRect, EditorGUIUtility.TrTextContent("New", "Create a new profile."), EditorStyles.miniButton))
            {
                // By default, try to put assets in a folder next to the currently active
                // scene file. If the user isn't a scene, put them in root instead.
                var targetName = actualTarget.name;
                var scene      = actualTarget.gameObject.scene;
                var asset      = ProbeReferenceVolumeAuthoring.CreateReferenceVolumeProfile(scene, targetName);
                m_Profile.objectReferenceValue = asset;
            }

            m_VolumeAsset.objectReferenceValue = EditorGUILayout.ObjectField(s_DataAssetLabel, m_VolumeAsset.objectReferenceValue, typeof(ProbeVolumeAsset), false);

            DebugVisualizationGroupEnabled = EditorGUILayout.BeginFoldoutHeaderGroup(DebugVisualizationGroupEnabled, "Debug Visualization");
            if (DebugVisualizationGroupEnabled)
            {
                m_DrawCells.boolValue  = EditorGUILayout.Toggle("Draw Cells", m_DrawCells.boolValue);
                m_DrawBricks.boolValue = EditorGUILayout.Toggle("Draw Bricks", m_DrawBricks.boolValue);
                m_DrawProbes.boolValue = EditorGUILayout.Toggle("Draw Probes", m_DrawProbes.boolValue);
                EditorGUI.BeginDisabledGroup(!m_DrawProbes.boolValue);
                m_ProbeShading.enumValueIndex = EditorGUILayout.Popup("Probe Shading Mode", m_ProbeShading.enumValueIndex, ProbeShadingModes);
                EditorGUI.BeginDisabledGroup(m_ProbeShading.enumValueIndex != 1);
                m_Exposure.floatValue = EditorGUILayout.FloatField("Probe exposure", m_Exposure.floatValue);
                EditorGUI.EndDisabledGroup();
                EditorGUI.EndDisabledGroup();
                m_CullingDistance.floatValue = EditorGUILayout.FloatField("Culling Distance", m_CullingDistance.floatValue);
            }
            EditorGUILayout.EndFoldoutHeaderGroup();

            DilationGroupEnabled = EditorGUILayout.BeginFoldoutHeaderGroup(DilationGroupEnabled, "Dilation");
            if (DilationGroupEnabled)
            {
                m_Dilate.boolValue = EditorGUILayout.Toggle("Dilate", m_Dilate.boolValue);
                EditorGUI.BeginDisabledGroup(!m_Dilate.boolValue);
                m_MaxDilationSamples.intValue          = EditorGUILayout.IntField("Max Dilation Samples", m_MaxDilationSamples.intValue);
                m_MaxDilationSampleDistance.floatValue = EditorGUILayout.FloatField("Max Dilation Sample Distance", m_MaxDilationSampleDistance.floatValue);
                DilationValidityThresholdInverted      = EditorGUILayout.Slider("Dilation Validity Threshold", DilationValidityThresholdInverted, 0f, 1f);
                m_GreedyDilation.boolValue             = EditorGUILayout.Toggle("Greedy Dilation", m_GreedyDilation.boolValue);
                EditorGUI.EndDisabledGroup();
            }
            EditorGUILayout.EndFoldoutHeaderGroup();

            if (EditorGUI.EndChangeCheck())
            {
                Constrain();
                serializedObject.ApplyModifiedProperties();
            }
        }