diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/AssetsConverter.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/AssetsConverter.cs index cb27aafa418..9f1b51c9221 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/AssetsConverter.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/AssetsConverter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using UnityEngine; namespace UnityEditor.Rendering.Converter { @@ -24,16 +25,42 @@ void OnSearchFinish() onScanFinish?.Invoke(returnList); } + var processedIds = new HashSet(); + SearchServiceUtils.RunQueuedSearch ( SearchServiceUtils.IndexingOptions.DeepSearch, contextSearchQueriesAndIds, (item, description) => { - var assetItem = new RenderPipelineConverterAssetItem(item.id) + // Direct conversion - works for both assets and scene objects + var unityObject = item.ToObject(); + + if (unityObject == null) + return; + + // Ensure we're always working with GameObjects + GameObject go = null; + + if (unityObject is GameObject gameObject) + go = gameObject; + else if (unityObject is Component component) + go = component.gameObject; + else + return; // Not a GameObject or Component + + var gid = GlobalObjectId.GetGlobalObjectIdSlow(go); + if (!processedIds.Add(gid.ToString())) + return; + + int type = gid.identifierType; // 1=Asset, 2=SceneObject + + var assetItem = new RenderPipelineConverterAssetItem(gid.ToString()) { - info = description + name = $"{unityObject.name} ({(type == 1 ? "Prefab" : "SceneObject")})", + info = type == 1 ? AssetDatabase.GetAssetPath(unityObject) : go.scene.path, }; + assets.Add(assetItem); }, OnSearchFinish diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs index de8db770eb8..6ea909ec366 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterAssetItem.cs @@ -30,7 +30,13 @@ public string guid public string GlobalObjectId => m_GlobalObjectId; - public string name => System.IO.Path.GetFileNameWithoutExtension(assetPath); + [SerializeField] + private string m_Name; + public string name + { + get => string.IsNullOrEmpty(m_Name) ? System.IO.Path.GetFileNameWithoutExtension(assetPath) : m_Name; + set => m_Name = value; + } [SerializeField] private string m_Info; diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs index d4c0681e554..d8abea0461c 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/RenderPipelineConverterMaterialUpgrader.cs @@ -76,6 +76,9 @@ public void OnClicked() [Serializable] internal abstract class RenderPipelineConverterMaterialUpgrader : IRenderPipelineConverter { + public virtual bool isEnabled => m_UpgradersCache != null && m_UpgradersCache.Count > 0; + public virtual string isDisabledMessage => "No material upgraders specified for this converter."; + /// /// List of material upgraders to use for this converter. /// diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs index c2fa84830db..144174199d2 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConverterVisualElement.cs @@ -37,6 +37,18 @@ internal class RenderPipelineConverterVisualElement : VisualElement public Action converterSelected; + private bool m_IsEnabled; + + private void SetEnabled(bool value, bool force = false) + { + if (m_IsEnabled != value || force) + { + m_IsEnabled = value; + m_HeaderFoldout.tooltip = (m_IsEnabled) ? description : converter.isDisabledMessage; + m_HeaderFoldout.SetEnabled(m_IsEnabled); + } + } + public RenderPipelineConverterVisualElement(Node converterInfo) { m_ConverterInfo = converterInfo; @@ -47,8 +59,10 @@ public RenderPipelineConverterVisualElement(Node converterInfo) m_HeaderFoldout = m_RootVisualElement.Q("conveterFoldout"); m_HeaderFoldout.text = displayName; - m_HeaderFoldout.tooltip = (converter.isEnabled) ? description : converter.isDisabledMessage; - m_HeaderFoldout.SetEnabled(converter.isEnabled); + + SetEnabled(converter.isEnabled, true); + m_HeaderFoldout.schedule.Execute(() => SetEnabled(converter.isEnabled)).Every(500); + m_HeaderFoldout.value = state.isExpanded; m_HeaderFoldout.RegisterCallback>((evt) => { diff --git a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConvertersEditor.cs b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConvertersEditor.cs index d457e54e824..c915ff2de74 100644 --- a/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConvertersEditor.cs +++ b/Packages/com.unity.render-pipelines.core/Editor-PrivateShared/Tools/Converter/Window/RenderPipelineConvertersEditor.cs @@ -82,7 +82,16 @@ public static void ShowWindow() [MenuItem("Window/Rendering/Render Pipeline Converter", true, 50)] public static bool CanShowWindow() { - return !EditorApplication.isPlaying; + if (EditorApplication.isPlaying) + return false; + + foreach (var converterType in TypeCache.GetTypesDerivedFrom()) + { + if (!converterType.IsAbstract && !converterType.IsInterface) + return true; + } + + return false; } internal static void DontSaveToLayout(EditorWindow wnd) @@ -212,7 +221,8 @@ public void CreateGUI() if (converterNodeCategory.name == to.label) currentContainer = converterNodeCategory; } - HideUnhideConverters(); + + ConfigureUI(); }; m_SourcePipelineDropDown.RegisterCallback>((evt) => @@ -225,40 +235,51 @@ public void CreateGUI() HideUnhideConverters(); }); + ConfigureUI(); + + UpdateUiForPlayMode(EditorApplication.isPlaying); + } + + private void ConfigureUI() + { HideUnhideConverters(); EnableOrDisableScanButton(); EnableOrDisableConvertButton(); - - UpdateUiForPlayMode(EditorApplication.isPlaying); } private bool CanEnableScan() { - foreach (var kvp in m_ConvertersVisualElements) + foreach (var child in currentContainer.children) { - var ve = kvp.Value; - if (ve.isSelectedAndEnabled && - !ve.state.isInitialized) + if (m_ConvertersVisualElements.TryGetValue(child, out var ve)) { - return true; + if (ve.isSelectedAndEnabled && + !ve.state.isInitialized) + { + return true; + } } } + return false; } private bool CanEnableConvert() { - foreach (var kvp in m_ConvertersVisualElements) + foreach (var child in currentContainer.children) { - var ve = kvp.Value; - if (ve.isSelectedAndEnabled && - ve.state.isInitialized && - ve.state.selectedItemsCount > 0 && - ve.state.pending > 0) + if (m_ConvertersVisualElements.TryGetValue(child, out var ve)) { - return true; + if (ve.isSelectedAndEnabled && + ve.state.isInitialized && + ve.state.selectedItemsCount > 0 && + ve.state.pending > 0) + { + return true; + } } } + return false; } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchSelectors.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs similarity index 93% rename from Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchSelectors.cs rename to Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs index bff90e1c5fd..fb5500a16c0 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchSelectors.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs @@ -6,7 +6,7 @@ namespace UnityEditor.Lighting { - static class CoreLightingSearchSelectors + static class CoreLightingSearchColumnProviders { internal const string k_SceneProvider = "scene"; internal const string k_BakingSetPath = "BakingSets/"; @@ -18,8 +18,7 @@ static class CoreLightingSearchSelectors internal const string k_VolumeModePath = k_VolumePath + "Mode"; internal const string k_VolumeProfilePath = k_VolumePath + "Profile"; - const string k_StyleSheetPath = "StyleSheets/LightingSearchSelectors.uss"; - const int k_DefaultSearchSelectorPriority = 99; + const string k_StyleSheetPath = "StyleSheets/LightingSearchColumnProviders.uss"; const int k_MinBakingSamples = 1; const int k_MaxBakingSamples = 8192; static StyleSheet s_StyleSheet; @@ -33,26 +32,6 @@ static StyleSheet LoadStyleSheet() return s_StyleSheet; } - [SearchSelector(k_VolumeModePath, provider: k_SceneProvider, priority: k_DefaultSearchSelectorPriority)] - static object VolumeModeSearchSelector(SearchSelectorArgs args) - { - var go = args.current.ToObject(); - if (go == null) - return null; - - return LightingSearchDataAccessors.GetVolumeMode(go); - } - - [SearchSelector(k_VolumeProfilePath, provider: k_SceneProvider, priority: k_DefaultSearchSelectorPriority)] - static object VolumeProfileSearchSelector(SearchSelectorArgs args) - { - var go = args.current.ToObject(); - if (go == null) - return null; - - return LightingSearchDataAccessors.GetVolumeProfile(go); - } - [SearchColumnProvider(k_BakingModePath)] public static void BakingModeSearchColumnProvider(SearchColumn column) { @@ -396,7 +375,7 @@ internal static void SetLightShape(GameObject go, LightType value) internal static bool IsLightShapeApplicable(LightType lightType) { - return IsAreaLight(lightType); + return lightType is LightType.Rectangle or LightType.Disc; } static bool IsAreaLight(LightType lightType) @@ -407,8 +386,7 @@ static bool IsAreaLight(LightType lightType) enum AreaLightShape { Rectangle = LightType.Rectangle, - Disc = LightType.Disc, - Tube = LightType.Tube + Disc = LightType.Disc } class LightShapeField : EnumField @@ -452,7 +430,9 @@ void UpdateEnumField() { if (IsAreaLight(m_Value)) { - Init((AreaLightShape)m_Value, false); + // Tube is not offered as an option; display as Rectangle + var displayType = m_Value == LightType.Tube ? LightType.Rectangle : m_Value; + Init((AreaLightShape)displayType, false); } } } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchSelectors.cs.meta b/Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs.meta similarity index 100% rename from Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchSelectors.cs.meta rename to Packages/com.unity.render-pipelines.core/Editor/Lighting/LightingSearchColumnProviders.cs.meta diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs index 2dd1f2683fb..99062ec5ef0 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs @@ -241,11 +241,13 @@ public void Create(ProbeVolumeBakingSet bakingSet, LightingSettings lightingSett skyOcclusionBakingSamples = bakingSet != null ? bakingSet.skyOcclusionBakingSamples : 0; skyOcclusionBakingBounces = bakingSet != null ? bakingSet.skyOcclusionBakingBounces : 0; -#if UNIFIED_BAKER - int indirectSampleCount = lightingSettings.indirectSampleCount; -#else - int indirectSampleCount = Math.Max(lightingSettings.indirectSampleCount, lightingSettings.environmentSampleCount); -#endif + var usingComputeLightBaker = UnityEditor.Rendering.EditorGraphicsSettings.defaultLightBaker == UnityEditor.Rendering.LightBaker.UnityComputeLightBaker; + int indirectSampleCount = 0; + if (usingComputeLightBaker) + indirectSampleCount = lightingSettings.indirectSampleCount; + else + indirectSampleCount = Math.Max(lightingSettings.indirectSampleCount, lightingSettings.environmentSampleCount); + Create(lightingSettings, ignoreEnvironement, lightingSettings.directSampleCount, indirectSampleCount, lightingSettings.environmentSampleCount, (int)lightingSettings.lightProbeSampleCountMultiplier, lightingSettings.maxBounces); } @@ -670,7 +672,7 @@ internal static void BakeAdjustmentVolume(ProbeVolumeBakingSet bakingSet, ProbeA failed |= !layerMaskJob.Step(); // Bake probe SH - s_BakeData.InitLightingJob(m_BakingSet, uniquePositions, BakeType.ApvOnly); + s_BakeData.InitLightingJob(bakingSet, touchup, uniquePositions, BakeType.ApvOnly); LightingBaker lightingJob = s_BakeData.lightingJob; while (!failed && lightingJob.currentStep < lightingJob.stepCount) failed |= !lightingJob.Step(); @@ -680,7 +682,7 @@ internal static void BakeAdjustmentVolume(ProbeVolumeBakingSet bakingSet, ProbeA foreach ((int uniqueProbeIndex, int cellIndex, int i) in bakedProbes) { ref var cell = ref bakingCells[cellIndex]; - cell.SetBakedData(m_BakingSet, m_BakingBatch, cellVolumes[cellIndex], i, uniqueProbeIndex, + cell.SetBakedData(bakingSet, m_BakingBatch, cellVolumes[cellIndex], i, uniqueProbeIndex, lightingJob.irradiance[uniqueProbeIndex], lightingJob.validity[uniqueProbeIndex], layerMaskJob.renderingLayerMasks, virtualOffsetJob.offsets, skyOcclusionJob.occlusion, skyOcclusionJob.encodedDirections, lightingJob.occlusion); @@ -696,8 +698,8 @@ internal static void BakeAdjustmentVolume(ProbeVolumeBakingSet bakingSet, ProbeA { // Validate baking cells size before any global state modifications var chunkSizeInProbes = ProbeBrickPool.GetChunkSizeInProbeCount(); - var hasVirtualOffsets = m_BakingSet.settings.virtualOffsetSettings.useVirtualOffset; - var hasRenderingLayers = m_BakingSet.useRenderingLayers; + var hasVirtualOffsets = bakingSet.settings.virtualOffsetSettings.useVirtualOffset; + var hasRenderingLayers = bakingSet.useRenderingLayers; if (ValidateBakingCellsSize(bakingCells, chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers)) { @@ -707,8 +709,8 @@ internal static void BakeAdjustmentVolume(ProbeVolumeBakingSet bakingSet, ProbeA ComputeValidityMasks(cell); } - // Attempt to write the result to disk - if (WriteBakingCells(bakingCells)) + // Attempt to write the result to disk. + if (WriteBakingCells(bakingSet, bakingCells)) { // Reload everything AssetDatabase.SaveAssets(); diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs index 150525aeff7..a83ed59c3ef 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs @@ -740,8 +740,8 @@ static int CalculateSupportDataChunkSize(int chunkSizeInProbes, bool hasVirtualO int supportTouchupChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; int supportLayerMaskChunkSize = hasRenderingLayers ? UnsafeUtility.SizeOf() * chunkSizeInProbes : 0; int supportOffsetsChunkSize = hasVirtualOffsets ? UnsafeUtility.SizeOf() * chunkSizeInProbes : 0; - - return supportPositionChunkSize + supportValidityChunkSize + + + return supportPositionChunkSize + supportValidityChunkSize + supportOffsetsChunkSize + supportLayerMaskChunkSize + supportTouchupChunkSize; } @@ -760,7 +760,7 @@ static bool ValidateBakingCellsSize(BakingCell[] bakingCells, int chunkSizeInPro return true; int supportDataChunkSize = CalculateSupportDataChunkSize(chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers); - + // Calculate total chunks count - need to call AnalyzeBrickForIndirectionEntries to get shChunkCount // Create a copy to avoid modifying the original cells during validation var tempCells = new BakingCell[bakingCells.Length]; @@ -771,7 +771,7 @@ static bool ValidateBakingCellsSize(BakingCell[] bakingCells, int chunkSizeInPro AnalyzeBrickForIndirectionEntries(ref tempCells[i]); totalChunksCount += tempCells[i].shChunkCount; } - + // Perform the critical size check long supportDataTotalSize = (long)totalChunksCount * supportDataChunkSize; if (supportDataTotalSize > int.MaxValue) @@ -802,19 +802,20 @@ static void WriteNativeArray(System.IO.FileStream fs, NativeArray array) w /// CellSharedData: a binary flat file containing bricks data /// CellSupportData: a binary flat file containing debug data (stripped from player builds if building without debug shaders) /// - static unsafe bool WriteBakingCells(BakingCell[] bakingCells) + static unsafe bool WriteBakingCells(ProbeVolumeBakingSet bakingSet, BakingCell[] bakingCells) { - m_BakingSet.GetBlobFileNames(m_BakingSet.lightingScenario, out var cellDataFilename, out var cellBricksDataFilename, out var cellOptionalDataFilename, out var cellProbeOcclusionDataFilename, out var cellSharedDataFilename, out var cellSupportDataFilename); - - m_BakingSet.cellDescs = new SerializedDictionary(); - m_BakingSet.bakedMinDistanceBetweenProbes = m_ProfileInfo.minDistanceBetweenProbes; - m_BakingSet.bakedSimplificationLevels = m_ProfileInfo.simplificationLevels; - m_BakingSet.bakedProbeOffset = m_ProfileInfo.probeOffset; - m_BakingSet.bakedProbeOcclusion = false; - m_BakingSet.bakedSkyOcclusion = m_BakingSet.skyOcclusion; - m_BakingSet.bakedSkyShadingDirection = m_BakingSet.bakedSkyOcclusion && m_BakingSet.skyOcclusionShadingDirection; - m_BakingSet.bakedMaskCount = m_BakingSet.useRenderingLayers ? APVDefinitions.probeMaxRegionCount : 1; - m_BakingSet.bakedLayerMasks = m_BakingSet.ComputeRegionMasks(); + bakingSet.GetBlobFileNames(bakingSet.lightingScenario, out var cellDataFilename, out var cellBricksDataFilename, + out var cellOptionalDataFilename, out var cellProbeOcclusionDataFilename, out var cellSharedDataFilename, out var cellSupportDataFilename); + + bakingSet.cellDescs = new SerializedDictionary(); + bakingSet.bakedMinDistanceBetweenProbes = m_ProfileInfo.minDistanceBetweenProbes; + bakingSet.bakedSimplificationLevels = m_ProfileInfo.simplificationLevels; + bakingSet.bakedProbeOffset = m_ProfileInfo.probeOffset; + bakingSet.bakedProbeOcclusion = false; + bakingSet.bakedSkyOcclusion = bakingSet.skyOcclusion; + bakingSet.bakedSkyShadingDirection = bakingSet.bakedSkyOcclusion && bakingSet.skyOcclusionShadingDirection; + bakingSet.bakedMaskCount = bakingSet.useRenderingLayers ? APVDefinitions.probeMaxRegionCount : 1; + bakingSet.bakedLayerMasks = bakingSet.ComputeRegionMasks(); var cellSharedDataDescs = new SerializedDictionary(); var cellL0L1DataDescs = new SerializedDictionary(); @@ -823,12 +824,12 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) var cellBricksDescs = new SerializedDictionary(); var cellSupportDescs = new SerializedDictionary(); - var voSettings = m_BakingSet.settings.virtualOffsetSettings; + var voSettings = bakingSet.settings.virtualOffsetSettings; bool hasVirtualOffsets = voSettings.useVirtualOffset; - bool handlesSkyOcclusion = m_BakingSet.bakedSkyOcclusion; - bool handlesSkyShading = m_BakingSet.bakedSkyShadingDirection && m_BakingSet.bakedSkyShadingDirection; - bool hasRenderingLayers = m_BakingSet.useRenderingLayers; - int validityRegionCount = m_BakingSet.bakedMaskCount; + bool handlesSkyOcclusion = bakingSet.bakedSkyOcclusion; + bool handlesSkyShading = bakingSet.bakedSkyShadingDirection && bakingSet.bakedSkyShadingDirection; + bool hasRenderingLayers = bakingSet.useRenderingLayers; + int validityRegionCount = bakingSet.bakedMaskCount; for (var i = 0; i < bakingCells.Length; ++i) { @@ -836,9 +837,9 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) var bakingCell = bakingCells[i]; // If any cell had probe occlusion, the baking set has probe occlusion. - m_BakingSet.bakedProbeOcclusion |= bakingCell.probeOcclusion?.Length > 0; + bakingSet.bakedProbeOcclusion |= bakingCell.probeOcclusion?.Length > 0; - m_BakingSet.cellDescs.Add(bakingCell.index, new CellDesc + bakingSet.cellDescs.Add(bakingCell.index, new CellDesc { position = bakingCell.position, index = bakingCell.index, @@ -850,7 +851,7 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) bricksCount = bakingCell.bricks.Length, }); - m_BakingSet.maxSHChunkCount = Mathf.Max(m_BakingSet.maxSHChunkCount, bakingCell.shChunkCount); + bakingSet.maxSHChunkCount = Mathf.Max(bakingSet.maxSHChunkCount, bakingCell.shChunkCount); m_TotalCellCounts.Add(new CellCounts { @@ -872,8 +873,8 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) var L0L1TotalSize = m_TotalCellCounts.chunksCount * L0L1ChunkSize; using var probesL0L1 = new NativeArray(L0L1TotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); - m_BakingSet.L0ChunkSize = L0L1R1xChunkSize; - m_BakingSet.L1ChunkSize = L1ChunkSize; + bakingSet.L0ChunkSize = L0L1R1xChunkSize; + bakingSet.L1ChunkSize = L1ChunkSize; // CellOptionalData // L2 Data: 15 Coeffs stored in 4 byte4 textures. @@ -882,39 +883,39 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) var L2TotalSize = m_TotalCellCounts.chunksCount * L2ChunkSize; // 4 textures using var probesL2 = new NativeArray(L2TotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); - m_BakingSet.L2TextureChunkSize = L2TextureChunkSize; + bakingSet.L2TextureChunkSize = L2TextureChunkSize; // Probe occlusion data - int probeOcclusionChunkSize = m_BakingSet.bakedProbeOcclusion ? sizeof(byte) * 4 * chunkSizeInProbes : 0; // 4 unorm per probe + int probeOcclusionChunkSize = bakingSet.bakedProbeOcclusion ? sizeof(byte) * 4 * chunkSizeInProbes : 0; // 4 unorm per probe int probeOcclusionTotalSize = m_TotalCellCounts.chunksCount * probeOcclusionChunkSize; using var probeOcclusion = new NativeArray(probeOcclusionTotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); - m_BakingSet.ProbeOcclusionChunkSize = probeOcclusionChunkSize; + bakingSet.ProbeOcclusionChunkSize = probeOcclusionChunkSize; // CellSharedData - m_BakingSet.sharedValidityMaskChunkSize = sizeof(byte) * validityRegionCount * chunkSizeInProbes; - m_BakingSet.sharedSkyOcclusionL0L1ChunkSize = handlesSkyOcclusion ? sizeof(ushort) * 4 * chunkSizeInProbes : 0; - m_BakingSet.sharedSkyShadingDirectionIndicesChunkSize = handlesSkyShading ? sizeof(byte) * chunkSizeInProbes : 0; - m_BakingSet.sharedDataChunkSize = m_BakingSet.sharedValidityMaskChunkSize + m_BakingSet.sharedSkyOcclusionL0L1ChunkSize + m_BakingSet.sharedSkyShadingDirectionIndicesChunkSize; + bakingSet.sharedValidityMaskChunkSize = sizeof(byte) * validityRegionCount * chunkSizeInProbes; + bakingSet.sharedSkyOcclusionL0L1ChunkSize = handlesSkyOcclusion ? sizeof(ushort) * 4 * chunkSizeInProbes : 0; + bakingSet.sharedSkyShadingDirectionIndicesChunkSize = handlesSkyShading ? sizeof(byte) * chunkSizeInProbes : 0; + bakingSet.sharedDataChunkSize = bakingSet.sharedValidityMaskChunkSize + bakingSet.sharedSkyOcclusionL0L1ChunkSize + bakingSet.sharedSkyShadingDirectionIndicesChunkSize; - var sharedDataTotalSize = m_TotalCellCounts.chunksCount * m_BakingSet.sharedDataChunkSize; + var sharedDataTotalSize = m_TotalCellCounts.chunksCount * bakingSet.sharedDataChunkSize; using var sharedData = new NativeArray(sharedDataTotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); // Brick data using var bricks = new NativeArray(m_TotalCellCounts.bricksCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); // CellSupportData - use pure helper function for calculation - m_BakingSet.supportPositionChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; - m_BakingSet.supportValidityChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; - m_BakingSet.supportOffsetsChunkSize = hasVirtualOffsets ? UnsafeUtility.SizeOf() * chunkSizeInProbes : 0; - m_BakingSet.supportTouchupChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; - m_BakingSet.supportLayerMaskChunkSize = hasRenderingLayers ? UnsafeUtility.SizeOf() * chunkSizeInProbes : 0; - - m_BakingSet.supportDataChunkSize = CalculateSupportDataChunkSize(chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers); - long supportDataTotalSize = (long)m_TotalCellCounts.chunksCount * m_BakingSet.supportDataChunkSize; + bakingSet.supportPositionChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; + bakingSet.supportValidityChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; + bakingSet.supportOffsetsChunkSize = hasVirtualOffsets ? UnsafeUtility.SizeOf() * chunkSizeInProbes : 0; + bakingSet.supportTouchupChunkSize = UnsafeUtility.SizeOf() * chunkSizeInProbes; + bakingSet.supportLayerMaskChunkSize = hasRenderingLayers ? UnsafeUtility.SizeOf() * chunkSizeInProbes : 0; + + bakingSet.supportDataChunkSize = CalculateSupportDataChunkSize(chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers); + long supportDataTotalSize = (long)m_TotalCellCounts.chunksCount * bakingSet.supportDataChunkSize; using var supportData = new NativeArray((int)supportDataTotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); - var sceneStateHash = m_BakingSet.GetBakingHashCode(); + var sceneStateHash = bakingSet.GetBakingHashCode(); var startCounts = new CellCounts(); int sharedChunkOffset = 0; @@ -932,15 +933,15 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) for (var i = 0; i < bakingCells.Length; ++i) { var bakingCell = bakingCells[i]; - var cellDesc = m_BakingSet.cellDescs[bakingCell.index]; + var cellDesc = bakingSet.cellDescs[bakingCell.index]; var chunksCount = cellDesc.shChunkCount; - cellSharedDataDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * m_BakingSet.sharedDataChunkSize, elementCount = chunksCount }); + cellSharedDataDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * bakingSet.sharedDataChunkSize, elementCount = chunksCount }); cellL0L1DataDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * L0L1ChunkSize, elementCount = chunksCount }); cellL2DataDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * L2ChunkSize, elementCount = chunksCount }); cellProbeOcclusionDataDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * probeOcclusionChunkSize, elementCount = chunksCount }); cellBricksDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.bricksCount * sizeof(Brick), elementCount = cellDesc.bricksCount }); - cellSupportDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * m_BakingSet.supportDataChunkSize, elementCount = chunksCount }); + cellSupportDescs.Add(bakingCell.index, new StreamableCellDesc() { offset = startCounts.chunksCount * bakingSet.supportDataChunkSize, elementCount = chunksCount }); sceneStateHash = sceneStateHash * 23 + bakingCell.GetBakingHashCode(); @@ -954,14 +955,14 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) int cellL1BL1RzOffset = cellL1GL1RyOffset + chunksCount * L1ChunkSize; int validityMaskOffset = sharedChunkOffset; - int skyOcclusionL0L1Offset = validityMaskOffset + chunksCount * m_BakingSet.sharedValidityMaskChunkSize; - int skyShadingIndicesOffset = skyOcclusionL0L1Offset + chunksCount * m_BakingSet.sharedSkyOcclusionL0L1ChunkSize; + int skyOcclusionL0L1Offset = validityMaskOffset + chunksCount * bakingSet.sharedValidityMaskChunkSize; + int skyShadingIndicesOffset = skyOcclusionL0L1Offset + chunksCount * bakingSet.sharedSkyOcclusionL0L1ChunkSize; int positionOffset = supportChunkOffset; - int validityOffset = positionOffset + chunksCount * m_BakingSet.supportPositionChunkSize; - int touchupOffset = validityOffset + chunksCount * m_BakingSet.supportValidityChunkSize; - int layerOffset = touchupOffset + chunksCount * m_BakingSet.supportTouchupChunkSize; // This is optional - int offsetsOffset = layerOffset + chunksCount * m_BakingSet.supportLayerMaskChunkSize; // Keep last as it's optional. + int validityOffset = positionOffset + chunksCount * bakingSet.supportPositionChunkSize; + int touchupOffset = validityOffset + chunksCount * bakingSet.supportValidityChunkSize; + int layerOffset = touchupOffset + chunksCount * bakingSet.supportTouchupChunkSize; // This is optional + int offsetsOffset = layerOffset + chunksCount * bakingSet.supportLayerMaskChunkSize; // Keep last as it's optional. // Here we directly map each chunk to the layout of the 3D textures in order to be able to copy the data directly to the GPU. // The granularity at runtime is one chunk at a time currently so the temporary data loc used is sized accordingly. @@ -971,24 +972,24 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) NativeArray probesTargetL1GL1Ry = probesL0L1.GetSubArray(cellL1GL1RyOffset + chunkIndex * L1ChunkSize, L1ChunkSize); NativeArray probesTargetL1BL1Rz = probesL0L1.GetSubArray(cellL1BL1RzOffset + chunkIndex * L1ChunkSize, L1ChunkSize); - NativeArray validityNeighboorMaskChunkTarget = sharedData.GetSubArray(validityMaskOffset + chunkIndex * m_BakingSet.sharedValidityMaskChunkSize, m_BakingSet.sharedValidityMaskChunkSize); - NativeArray skyOcclusionL0L1ChunkTarget = sharedData.GetSubArray(skyOcclusionL0L1Offset + chunkIndex * m_BakingSet.sharedSkyOcclusionL0L1ChunkSize, m_BakingSet.sharedSkyOcclusionL0L1ChunkSize).Reinterpret(1); - NativeArray skyShadingIndicesChunkTarget = sharedData.GetSubArray(skyShadingIndicesOffset + chunkIndex * m_BakingSet.sharedSkyShadingDirectionIndicesChunkSize, m_BakingSet.sharedSkyShadingDirectionIndicesChunkSize); + NativeArray validityNeighboorMaskChunkTarget = sharedData.GetSubArray(validityMaskOffset + chunkIndex * bakingSet.sharedValidityMaskChunkSize, bakingSet.sharedValidityMaskChunkSize); + NativeArray skyOcclusionL0L1ChunkTarget = sharedData.GetSubArray(skyOcclusionL0L1Offset + chunkIndex * bakingSet.sharedSkyOcclusionL0L1ChunkSize, bakingSet.sharedSkyOcclusionL0L1ChunkSize).Reinterpret(1); + NativeArray skyShadingIndicesChunkTarget = sharedData.GetSubArray(skyShadingIndicesOffset + chunkIndex * bakingSet.sharedSkyShadingDirectionIndicesChunkSize, bakingSet.sharedSkyShadingDirectionIndicesChunkSize); - NativeArray positionsChunkTarget = supportData.GetSubArray(positionOffset + chunkIndex * m_BakingSet.supportPositionChunkSize, m_BakingSet.supportPositionChunkSize).Reinterpret(1); - NativeArray validityChunkTarget = supportData.GetSubArray(validityOffset + chunkIndex * m_BakingSet.supportValidityChunkSize, m_BakingSet.supportValidityChunkSize).Reinterpret(1); - NativeArray touchupVolumeInteractionChunkTarget = supportData.GetSubArray(touchupOffset + chunkIndex * m_BakingSet.supportTouchupChunkSize, m_BakingSet.supportTouchupChunkSize).Reinterpret(1); - NativeArray regionChunkTarget = supportData.GetSubArray(layerOffset + chunkIndex * m_BakingSet.supportLayerMaskChunkSize, m_BakingSet.supportLayerMaskChunkSize).Reinterpret(1); - NativeArray offsetChunkTarget = supportData.GetSubArray(offsetsOffset + chunkIndex * m_BakingSet.supportOffsetsChunkSize, m_BakingSet.supportOffsetsChunkSize).Reinterpret(1); + NativeArray positionsChunkTarget = supportData.GetSubArray(positionOffset + chunkIndex * bakingSet.supportPositionChunkSize, bakingSet.supportPositionChunkSize).Reinterpret(1); + NativeArray validityChunkTarget = supportData.GetSubArray(validityOffset + chunkIndex * bakingSet.supportValidityChunkSize, bakingSet.supportValidityChunkSize).Reinterpret(1); + NativeArray touchupVolumeInteractionChunkTarget = supportData.GetSubArray(touchupOffset + chunkIndex * bakingSet.supportTouchupChunkSize, bakingSet.supportTouchupChunkSize).Reinterpret(1); + NativeArray regionChunkTarget = supportData.GetSubArray(layerOffset + chunkIndex * bakingSet.supportLayerMaskChunkSize, bakingSet.supportLayerMaskChunkSize).Reinterpret(1); + NativeArray offsetChunkTarget = supportData.GetSubArray(offsetsOffset + chunkIndex * bakingSet.supportOffsetsChunkSize, bakingSet.supportOffsetsChunkSize).Reinterpret(1); NativeArray probesTargetL2_0 = probesL2.GetSubArray(shL2ChunkOffset + chunksCount * L2TextureChunkSize * 0 + chunkIndex * L2TextureChunkSize, L2TextureChunkSize); NativeArray probesTargetL2_1 = probesL2.GetSubArray(shL2ChunkOffset + chunksCount * L2TextureChunkSize * 1 + chunkIndex * L2TextureChunkSize, L2TextureChunkSize); NativeArray probesTargetL2_2 = probesL2.GetSubArray(shL2ChunkOffset + chunksCount * L2TextureChunkSize * 2 + chunkIndex * L2TextureChunkSize, L2TextureChunkSize); NativeArray probesTargetL2_3 = probesL2.GetSubArray(shL2ChunkOffset + chunksCount * L2TextureChunkSize * 3 + chunkIndex * L2TextureChunkSize, L2TextureChunkSize); - NativeArray probeOcclusionTarget = probeOcclusion.GetSubArray(probeOcclusionChunkOffset + chunkIndex * m_BakingSet.ProbeOcclusionChunkSize, m_BakingSet.ProbeOcclusionChunkSize); + NativeArray probeOcclusionTarget = probeOcclusion.GetSubArray(probeOcclusionChunkOffset + chunkIndex * bakingSet.ProbeOcclusionChunkSize, bakingSet.ProbeOcclusionChunkSize); - for (int brickIndex = 0; brickIndex < m_BakingSet.chunkSizeInBricks; brickIndex++) + for (int brickIndex = 0; brickIndex < bakingSet.chunkSizeInBricks; brickIndex++) { for (int z = 0; z < ProbeBrickPool.kBrickProbeCountPerDim; z++) { @@ -1008,16 +1009,16 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) for (int l = 0; l < validityRegionCount; l++) validityNeighboorMaskChunkTarget[index * validityRegionCount + l] = 0; - if (m_BakingSet.bakedSkyOcclusion) + if (bakingSet.bakedSkyOcclusion) { WriteToShaderSkyOcclusion(Vector4.zero, skyOcclusionL0L1ChunkTarget, index * 4); - if (m_BakingSet.bakedSkyShadingDirection) + if (bakingSet.bakedSkyShadingDirection) { skyShadingIndicesChunkTarget[index] = 255; } } - if (m_BakingSet.bakedProbeOcclusion) + if (bakingSet.bakedProbeOcclusion) { WriteToShaderProbeOcclusion(Vector4.one, probeOcclusionTarget, index * 4); } @@ -1039,16 +1040,16 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) for (int l = 0; l < validityRegionCount; l++) validityNeighboorMaskChunkTarget[index * validityRegionCount + l] = bakingCell.validityNeighbourMask[l, shidx]; - if (m_BakingSet.bakedSkyOcclusion) + if (bakingSet.bakedSkyOcclusion) { WriteToShaderSkyOcclusion(bakingCell.skyOcclusionDataL0L1[shidx], skyOcclusionL0L1ChunkTarget, index * 4); - if (m_BakingSet.bakedSkyShadingDirection) + if (bakingSet.bakedSkyShadingDirection) { skyShadingIndicesChunkTarget[index] = bakingCell.skyShadingDirectionIndices[shidx]; } } - if (m_BakingSet.bakedProbeOcclusion) + if (bakingSet.bakedProbeOcclusion) { WriteToShaderProbeOcclusion(bakingCell.probeOcclusion[shidx], probeOcclusionTarget, index * 4); } @@ -1071,8 +1072,8 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) shL0L1ChunkOffset += (chunksCount * L0L1ChunkSize); shL2ChunkOffset += (chunksCount * L2ChunkSize); probeOcclusionChunkOffset += (chunksCount * probeOcclusionChunkSize); - supportChunkOffset += (chunksCount * m_BakingSet.supportDataChunkSize); - sharedChunkOffset += (chunksCount * m_BakingSet.sharedDataChunkSize); + supportChunkOffset += (chunksCount * bakingSet.supportDataChunkSize); + sharedChunkOffset += (chunksCount * bakingSet.sharedDataChunkSize); bricks.GetSubArray(startCounts.bricksCount, cellDesc.bricksCount).CopyFrom(bakingCell.bricks); @@ -1084,7 +1085,7 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) } // Need to save here because the forced import below discards the changes. - EditorUtility.SetDirty(m_BakingSet); + EditorUtility.SetDirty(bakingSet); AssetDatabase.SaveAssets(); // Explicitly make sure the binary output files are writable since we write them using the C# file API (i.e. check out Perforce files if applicable) @@ -1136,20 +1137,20 @@ static unsafe bool WriteBakingCells(BakingCell[] bakingCells) AssetDatabase.ImportAsset(cellSharedDataFilename); AssetDatabase.ImportAsset(cellSupportDataFilename); - var bakingSetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_BakingSet)); + var bakingSetGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(bakingSet)); - m_BakingSet.scenarios[ProbeReferenceVolume.instance.lightingScenario] = new ProbeVolumeBakingSet.PerScenarioDataInfo + bakingSet.scenarios[bakingSet.lightingScenario] = new ProbeVolumeBakingSet.PerScenarioDataInfo { sceneHash = sceneStateHash, cellDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellL0L1DataDescs, L0L1ChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellDataFilename)), cellOptionalDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellL2DataDescs, L2ChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellOptionalDataFilename)), cellProbeOcclusionDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellProbeOcclusionDataDescs, probeOcclusionChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellProbeOcclusionDataFilename)), }; - m_BakingSet.cellSharedDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellSharedDataDescs, m_BakingSet.sharedDataChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellSharedDataFilename)); - m_BakingSet.cellBricksDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellBricksDescs, sizeof(Brick), bakingSetGUID, AssetDatabase.AssetPathToGUID(cellBricksDataFilename)); - m_BakingSet.cellSupportDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellSupportDescs, m_BakingSet.supportDataChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellSupportDataFilename)); + bakingSet.cellSharedDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellSharedDataDescs, bakingSet.sharedDataChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellSharedDataFilename)); + bakingSet.cellBricksDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellBricksDescs, sizeof(Brick), bakingSetGUID, AssetDatabase.AssetPathToGUID(cellBricksDataFilename)); + bakingSet.cellSupportDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellSupportDescs, bakingSet.supportDataChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellSupportDataFilename)); - EditorUtility.SetDirty(m_BakingSet); + EditorUtility.SetDirty(bakingSet); return true; } @@ -1198,7 +1199,7 @@ unsafe static void WriteDilatedCells(List cells) probeOcclusion.CopyFrom(System.IO.File.ReadAllBytes(cellProbeOcclusionDataFilename)); } - var lightingScenario = ProbeReferenceVolume.instance.lightingScenario; + var lightingScenario = m_BakingSet.lightingScenario; Debug.Assert(m_BakingSet.scenarios.ContainsKey(lightingScenario)); var scenarioDataInfo = m_BakingSet.scenarios[lightingScenario]; diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs index 7e12d43d7df..08269a06bb3 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs @@ -356,7 +356,7 @@ static internal void RecomputeVOForDebugOnly() if (ValidateBakingCellsSize(bakingCellsArray, chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers)) { // Write back the assets. - WriteBakingCells(bakingCellsArray); + WriteBakingCells(m_BakingSet, bakingCellsArray); } m_BakingBatch?.Dispose(); diff --git a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs index 3467867e883..f2bcb0a0077 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs @@ -479,6 +479,14 @@ struct BakeData // Cancellation public bool failed; + [Flags] + enum BakeJobRequests + { + MAIN_REQUEST = 1, + TOUCHUP_REQUESTS = 2, + ADDITIONAL_REQUEST = 4 + } + internal static void InitVirtualOffsetJob(IntPtr pVirtualOffsetsBuffer, ref bool bakeVirtualOffsets) { bool usingVirtualOffset = m_BakingSet.settings.virtualOffsetSettings.useVirtualOffset; @@ -541,7 +549,11 @@ public void Init(ProbeVolumeBakingSet bakingSet, NativeList probePositi probeCount = probePositions.Length; reflectionProbeCount = requests.Count; - jobs = CreateBakingJobs(bakingSet, requests.Count != 0); + var probeJobRequests = BakeJobRequests.MAIN_REQUEST | BakeJobRequests.TOUCHUP_REQUESTS; + if (requests.Count > 0) + probeJobRequests |= BakeJobRequests.ADDITIONAL_REQUEST; + + jobs = CreateBakingJobs(bakingSet, probeJobRequests); originalPositions = probePositions.ToArray(Allocator.Persistent); SortPositions(probePositions, requests); @@ -587,13 +599,22 @@ public void InitAdditionalRequests(NativeList probePositions, List probePositions, BakeType bakeType) + public void InitLightingJob(ProbeVolumeBakingSet bakingSet, ProbeAdjustmentVolume touchup, NativeList probePositions, BakeType bakeType) { probeCount = probePositions.Length; s_AdjustmentVolumes = new TouchupVolumeWithBoundsList(); + touchup.GetOBBandAABB(out var obb, out var aabb); + s_AdjustmentVolumes.Add((obb, aabb, touchup)); + touchup.skyDirection.Normalize(); - jobs = CreateBakingJobs(bakingSet, false); + var probeJobRequests = BakeJobRequests.TOUCHUP_REQUESTS; + if (touchup.mode != ProbeAdjustmentVolume.Mode.OverrideSampleCount) + { + // Other touchup volumes don't need a job of their own but they do need a main request job + probeJobRequests |= BakeJobRequests.MAIN_REQUEST; + } + jobs = CreateBakingJobs(bakingSet, probeJobRequests); SortPositions(probePositions, new List()); lightingJob = lightingOverride ?? new DefaultLightTransport(); @@ -622,16 +643,19 @@ public void ExecuteLightingAsync() bakingThread.Start(); } - static BakeJob[] CreateBakingJobs(ProbeVolumeBakingSet bakingSet, bool hasAdditionalRequests) + static BakeJob[] CreateBakingJobs(ProbeVolumeBakingSet bakingSet, BakeJobRequests bakeJobRequests) { // Build the list of adjustment volumes affecting sample count var touchupVolumesAndBounds = new TouchupVolumeWithBoundsList(); + if (bakeJobRequests.HasFlag(BakeJobRequests.TOUCHUP_REQUESTS)) { // This is slow, but we should have very little amount of touchup volumes. foreach (var adjustment in s_AdjustmentVolumes) { if (adjustment.volume.mode == ProbeAdjustmentVolume.Mode.OverrideSampleCount) + { touchupVolumesAndBounds.Add(adjustment); + } } // Sort by volume to give priority to smaller volumes @@ -640,18 +664,33 @@ static BakeJob[] CreateBakingJobs(ProbeVolumeBakingSet bakingSet, bool hasAdditi var lightingSettings = ProbeVolumeLightingTab.GetLightingSettings(); bool skyOcclusion = bakingSet.skyOcclusion; + var jobs = new List(); - int additionalJobs = hasAdditionalRequests ? 2 : 1; - var jobs = new BakeJob[touchupVolumesAndBounds.Count + additionalJobs]; + if (bakeJobRequests.HasFlag(BakeJobRequests.TOUCHUP_REQUESTS)) + { + foreach (var touchupVolume in touchupVolumesAndBounds) + { + BakeJob job = new BakeJob(); + job.Create(lightingSettings, skyOcclusion, touchupVolume); + jobs.Add(job); + } + } - for (int i = 0; i < touchupVolumesAndBounds.Count; i++) - jobs[i].Create(lightingSettings, skyOcclusion, touchupVolumesAndBounds[i]); + if (bakeJobRequests.HasFlag(BakeJobRequests.MAIN_REQUEST)) + { + BakeJob job = new BakeJob(); + job.Create(bakingSet, lightingSettings, skyOcclusion); + jobs.Add(job); + } - jobs[touchupVolumesAndBounds.Count + 0].Create(bakingSet, lightingSettings, skyOcclusion); - if (hasAdditionalRequests) - jobs[touchupVolumesAndBounds.Count + 1].Create(bakingSet, lightingSettings, false); + if (bakeJobRequests.HasFlag(BakeJobRequests.ADDITIONAL_REQUEST)) + { + BakeJob job = new BakeJob(); + job.Create(bakingSet, lightingSettings, false); + jobs.Add(job); + } - return jobs; + return jobs.ToArray(); } static BakeJob[] CreateAdditionalBakingJobs() @@ -1802,7 +1841,7 @@ static void ApplyPostBakeOperations() // Attempt to convert baking cells to runtime cells bool succeededWritingBakingCells; using (new BakingCompleteProfiling(BakingCompleteProfiling.Stages.WriteBakedData)) - succeededWritingBakingCells = WriteBakingCells(m_BakedCells.Values.ToArray()); + succeededWritingBakingCells = WriteBakingCells(m_BakingSet, m_BakedCells.Values.ToArray()); if (!succeededWritingBakingCells) return; diff --git a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs index 5a8301d8a9b..cb1340dc443 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputSerialization.cs @@ -5,6 +5,8 @@ using Unity.Mathematics; using UnityEngine; using Unity.Collections.LowLevel.Unsafe; +using UnityEditor.LightBaking; +using MixedLightingMode = UnityEngine.MixedLightingMode; // The types defined in this file should match the types defined in BakeInput.h. namespace UnityEditor.PathTracing.LightBakerBridge @@ -252,6 +254,15 @@ internal struct LightingSettings : IBakeInputVisitable public float aoDistance; public bool useHardwareRayTracing; + public LightSamplingMode directLightSamplingMode; + public uint directRISCandidateCount; + public LightSamplingMode indirectLightSamplingMode; + public UInt32 indirectRISCandidateCount; + public LightAccelerationStructure lightAccelerationStructure; + public uint lightGridMaxCells; + public EmissiveSamplingMode directEmissiveSamplingMode; + public EmissiveSamplingMode indirectEmissiveSamplingMode; + public void Transfer(IBakeInputVisitor visitor) { visitor.Transfer(ref lightmapSampleCounts); @@ -263,6 +274,15 @@ public void Transfer(IBakeInputVisitor visitor) visitor.TransferBoolean(ref aoEnabled); visitor.TransferBlittable(ref aoDistance); visitor.TransferBoolean(ref useHardwareRayTracing); + + visitor.TransferBlittable(ref directLightSamplingMode); + visitor.TransferBlittable(ref directRISCandidateCount); + visitor.TransferBlittable(ref indirectLightSamplingMode); + visitor.TransferBlittable(ref indirectRISCandidateCount); + visitor.TransferBlittable(ref lightAccelerationStructure); + visitor.TransferBlittable(ref lightGridMaxCells); + visitor.TransferBlittable(ref directEmissiveSamplingMode); + visitor.TransferBlittable(ref indirectEmissiveSamplingMode); } } @@ -893,7 +913,9 @@ internal struct BakeInput : IBakeInputVisitable public UInt32[] instanceToTextureDataIndex; // Index into albedoData and emissiveData for each instance public Int32[] materialToTransmissionDataIndex; // Index into transmissionData and transmissionDataProperties for each material public TextureData[] albedoData; + public TextureProperties[] albedoDataProperties; // Same size as albedoData public TextureData[] emissiveData; + public TextureProperties[] emissiveDataProperties; // Same size as emissiveData public TextureData[] transmissionData; // Same size as transmissionDataProperties public TextureProperties[] transmissionDataProperties; // Same size as transmissionData // Cookie data @@ -914,7 +936,9 @@ public void Transfer(IBakeInputVisitor visitor) visitor.TransferBlittableArray(ref instanceToTextureDataIndex); visitor.TransferBlittableArray(ref materialToTransmissionDataIndex); visitor.TransferArray(ref albedoData); + visitor.TransferArray(ref albedoDataProperties); visitor.TransferArray(ref emissiveData); + visitor.TransferArray(ref emissiveDataProperties); visitor.TransferArray(ref transmissionData); visitor.TransferArray(ref transmissionDataProperties); visitor.TransferArray(ref cookieData); @@ -927,7 +951,7 @@ internal static class BakeInputSerialization { // Should match BakeInputSerialization::kCurrentFileVersion in BakeInputSerialization.h. // If these are out of sync, the implementation in this file probably needs to be updated. - const UInt64 CurrentFileVersion = 202601191; + const UInt64 CurrentFileVersion = 202603061; public static bool Deserialize(string path, out BakeInput bakeInput) { diff --git a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs index af5158ef66d..90586c42c6c 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/BakeInputToWorldConversion.cs @@ -2,13 +2,15 @@ using System.Collections.Generic; using UnityEngine.PathTracing.Core; using UnityEngine.Rendering; -using UnityEngine.LightTransport; using Unity.Mathematics; +using UnityEditor.LightBaking; using UnityEngine; using UnityEngine.PathTracing.Lightmapping; using UnityEngine.PathTracing.Integration; using UnityEngine.Rendering.Sampling; using UnityEngine.Rendering.UnifiedRayTracing; +using InputExtraction = UnityEngine.LightTransport.InputExtraction; +using Material = UnityEngine.Material; namespace UnityEditor.PathTracing.LightBakerBridge { @@ -208,7 +210,7 @@ internal static void InjectAnalyticalLights( lights[i] = lightDescriptor; } - world.lightPickingMethod = LightPickingMethod.LightGrid; + world.lightPickingMethod = bakeInput.lightingSettings.lightAccelerationStructure == LightAccelerationStructure.LightGrid ? LightPickingMethod.LightGrid : LightPickingMethod.Uniform; lightHandles = world.AddLights(lights, false, autoEstimateLUTRange, bakeInput.lightingSettings.mixedLightingMode); } @@ -267,15 +269,27 @@ internal static void InjectMaterials( // Create albedo and emission textures from materials var perTexturePairMaterials = new MaterialPool.MaterialDescriptor[bakeInput.albedoData.Length]; Debug.Assert(bakeInput.albedoData.Length == bakeInput.emissiveData.Length); + Debug.Assert(bakeInput.albedoData.Length == bakeInput.albedoDataProperties.Length); + Debug.Assert(bakeInput.emissiveData.Length == bakeInput.emissiveDataProperties.Length); for (int i = 0; i < bakeInput.albedoData.Length; i++) { ref var material = ref perTexturePairMaterials[i]; var baseTexture = CreateTexture2DFromTextureData(in bakeInput.albedoData[i], $"World (albedo) {i}"); + ref readonly TextureProperties albedoProperties = ref bakeInput.albedoDataProperties[i]; + baseTexture.wrapModeU = albedoProperties.wrapModeU; + baseTexture.wrapModeV = albedoProperties.wrapModeV; + baseTexture.filterMode = albedoProperties.filterMode; allocatedObjects.Add(baseTexture); var emissiveTexture = CreateTexture2DFromTextureData(in bakeInput.emissiveData[i], $"World (emissive) {i}"); + ref readonly TextureProperties emissiveProperties = ref bakeInput.emissiveDataProperties[i]; + emissiveTexture.wrapModeU = emissiveProperties.wrapModeU; + emissiveTexture.wrapModeV = emissiveProperties.wrapModeV; + emissiveTexture.filterMode = emissiveProperties.filterMode; allocatedObjects.Add(emissiveTexture); material.Albedo = baseTexture; material.Emission = emissiveTexture; + material.PointSampleAlbedo = albedoProperties.filterMode == FilterMode.Point; + material.PointSampleEmission = emissiveProperties.filterMode == FilterMode.Point; // Only mark emissive if it isn't the default black texture bool isEmissiveSinglePixel = bakeInput.emissiveData[i].data.Length == 1; @@ -537,7 +551,7 @@ internal static void PopulateWorld(InputExtraction.BakeInput input, UnityCompute Dictionary> lodInstances; Dictionary> lodgroupToContributorInstances; WorldHelpers.AddContributingInstancesToWorld(world.PathTracingWorld, in fatInstances, out lodInstances, out lodgroupToContributorInstances); - world.PathTracingWorld.Build(sceneBounds, cmd, ref world.ScratchBuffer, samplingResources, true, 1024); + world.PathTracingWorld.Build(sceneBounds, cmd, ref world.ScratchBuffer, samplingResources, true, 1024, (int)input.bakeInput.GetLightingSettings().lightGridMaxCells); } internal static void DeserializeAndInjectBakeInputData( diff --git a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs index 948a2c17da5..809c8f6f498 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/PathTracing/LightBakerStrangler.cs @@ -345,7 +345,6 @@ internal static bool Bake(string bakeInputPath, string lightmapRequestsPath, str samplingResources.Load((uint)UnityEngine.Rendering.Sampling.SamplingResources.ResourceType.All); // Deserialize BakeInput, inject data into world - const bool useLegacyBakingBehavior = true; const bool autoEstimateLUTRange = true; BakeInputToWorldConversion.InjectBakeInputData(world.PathTracingWorld, autoEstimateLUTRange, in bakeInput, out Bounds sceneBounds, out world.Meshes, out FatInstance[] fatInstances, out world.LightHandles, @@ -356,7 +355,7 @@ internal static bool Bake(string bakeInputPath, string lightmapRequestsPath, str // Build world with extracted data const bool emissiveSampling = true; - world.PathTracingWorld.Build(sceneBounds, deviceContext.GetCommandBuffer(), ref world.ScratchBuffer, samplingResources, emissiveSampling, 1024); + world.PathTracingWorld.Build(sceneBounds, deviceContext.GetCommandBuffer(), ref world.ScratchBuffer, samplingResources, emissiveSampling, 1024, (int)bakeInput.lightingSettings.lightGridMaxCells); LightmapBakeSettings lightmapBakeSettings = GetLightmapBakeSettings(bakeInput); // Build array of lightmap descriptors based on the atlassing data and instances. @@ -367,7 +366,7 @@ internal static bool Bake(string bakeInputPath, string lightmapRequestsPath, str ulong lightmapWorkSteps = CalculateWorkStepsForLightmapRequests(in lightmapRequestData, lightmapDescriptors, lightmapBakeSettings); progressState.SetTotalWorkSteps(probeWorkSteps + lightmapWorkSteps); - if (!ExecuteProbeRequests(in bakeInput, in probeRequestData, deviceContext, useLegacyBakingBehavior, world, progressState, samplingResources)) + if (!ExecuteProbeRequests(in bakeInput, in probeRequestData, deviceContext, world, progressState, samplingResources)) return false; if (lightmapRequestData.requests.Length <= 0) @@ -377,7 +376,7 @@ internal static bool Bake(string bakeInputPath, string lightmapRequestsPath, str LightmapResourceLibrary resources = new(); resources.Load(world.RayTracingContext); - if (ExecuteLightmapRequests(in lightmapRequestData, deviceContext, world, in fatInstances, in lodInstances, in lodgroupToContributorInstances, integrationSettings, useLegacyBakingBehavior, resources, progressState, lightmapDescriptors, lightmapBakeSettings, samplingResources) != Result.Success) + if (ExecuteLightmapRequests(in lightmapRequestData, deviceContext, world, in fatInstances, in lodInstances, in lodgroupToContributorInstances, integrationSettings, resources, progressState, lightmapDescriptors, lightmapBakeSettings, samplingResources) != Result.Success) return false; CoreUtils.Destroy(resources.UVFallbackBufferGenerationMaterial); @@ -479,7 +478,13 @@ internal static LightmapBakeSettings GetLightmapBakeSettings(in BakeInput bakeIn DirectSampleCount = math.max(0, bakeInput.lightingSettings.lightmapSampleCounts.directSampleCount), IndirectSampleCount = math.max(0, bakeInput.lightingSettings.lightmapSampleCounts.indirectSampleCount), BounceCount = math.max(0, bakeInput.lightingSettings.maxBounces), - AOMaxDistance = math.max(0.0f, bakeInput.lightingSettings.aoDistance) + AOMaxDistance = math.max(0.0f, bakeInput.lightingSettings.aoDistance), + DirectLightSamplingMode = bakeInput.lightingSettings.directLightSamplingMode, + DirectRISCandidateCount = bakeInput.lightingSettings.directRISCandidateCount, + IndirectLightSamplingMode = bakeInput.lightingSettings.indirectLightSamplingMode, + IndirectRISCandidateCount = bakeInput.lightingSettings.indirectRISCandidateCount, + DirectEmissiveSamplingMode = bakeInput.lightingSettings.directEmissiveSamplingMode, + IndirectEmissiveSamplingMode = bakeInput.lightingSettings.indirectEmissiveSamplingMode, }; lightmapBakeSettings.ValiditySampleCount = lightmapBakeSettings.IndirectSampleCount; return lightmapBakeSettings; @@ -872,7 +877,6 @@ internal static Result ExecuteLightmapRequests( in Dictionary> lodInstances, in Dictionary> lodgroupToContributorInstances, IntegrationSettings integrationSettings, - bool useLegacyBakingBehavior, LightmapResourceLibrary lightmapResourceLib, BakeProgressState progressState, LightmapDesc[] lightmapDescriptors, @@ -898,7 +902,12 @@ internal static Result ExecuteLightmapRequests( if (!lightmappingContext.Initialize(deviceContext, initialLightmapResolution, initialLightmapResolution, world, maxIndexCount, maxVertexCount, lightmapResourceLib)) return Result.InitializeFailure; - lightmappingContext.IntegratorContext.Initialize(samplingResources, lightmapResourceLib, !useLegacyBakingBehavior); + CommandBuffer cmd = lightmappingContext.GetCommandBuffer(); + lightmappingContext.IntegratorContext.Initialize(samplingResources, lightmapResourceLib); + + // Setup keywords only once before accumulation. + lightmappingContext.IntegratorContext.LightmapDirectIntegrator.SetupLightSamplingKeywords(cmd, lightmapBakeSettings.DirectLightSamplingMode, lightmapBakeSettings.DirectEmissiveSamplingMode); + lightmappingContext.IntegratorContext.LightmapIndirectIntegrator.SetupLightSamplingKeywords(cmd, lightmapBakeSettings.IndirectLightSamplingMode, lightmapBakeSettings.IndirectEmissiveSamplingMode); // Chart identification happens in multithreaded fashion on the CPU. We start it immediately so it can run in tandem with other work. bool usesChartIdentification = AnyLightmapRequestHasOutput(lightmapRequestData.requests, LightmapRequestOutputType.ChartIndex) || @@ -918,7 +927,6 @@ internal static Result ExecuteLightmapRequests( } } - CommandBuffer cmd = lightmappingContext.GetCommandBuffer(); using LightmapIntegrationHelpers.GPUSync gpuSync = new(); // used for sync points in debug mode gpuSync.Create(); @@ -1418,8 +1426,7 @@ private static (uint directSampleCount, uint effectiveIndirectSampleCount) GetPr } internal static bool ExecuteProbeRequests(in BakeInput bakeInput, in ProbeRequestData probeRequestData, UnityComputeDeviceContext deviceContext, - bool useLegacyBakingBehavior, UnityComputeWorld world, BakeProgressState progressState, - UnityEngine.Rendering.Sampling.SamplingResources samplingResources) + UnityComputeWorld world, BakeProgressState progressState, UnityEngine.Rendering.Sampling.SamplingResources samplingResources) { if (probeRequestData.requests.Length == 0) return true; @@ -1428,7 +1435,7 @@ internal static bool ExecuteProbeRequests(in BakeInput bakeInput, in ProbeReques integrationResources.Load(world.RayTracingContext); var probeOcclusionLightIndexMappingShader = UnityEditor.AssetDatabase.LoadAssetAtPath("Packages/com.unity.render-pipelines.core/Runtime/PathTracing/Shaders/ProbeOcclusionLightIndexMapping.compute"); - using UnityComputeProbeIntegrator probeIntegrator = new(!useLegacyBakingBehavior, samplingResources, integrationResources, probeOcclusionLightIndexMappingShader); + using UnityComputeProbeIntegrator probeIntegrator = new(samplingResources, integrationResources, probeOcclusionLightIndexMappingShader); probeIntegrator.SetProgressReporter(progressState); // Create input position buffer @@ -1458,6 +1465,12 @@ internal static bool ExecuteProbeRequests(in BakeInput bakeInput, in ProbeReques (uint directSampleCount, uint effectiveIndirectSampleCount) = GetProbeSampleCounts(request.sampleCount); probeIntegrator.Prepare(deviceContext, world, positionsBuffer.Slice(), pushoff, (int)bounceCount); + probeIntegrator.SetLightSamplingSettings( + bakeInput.lightingSettings.directLightSamplingMode, + bakeInput.lightingSettings.directRISCandidateCount, + bakeInput.lightingSettings.indirectLightSamplingMode, + bakeInput.lightingSettings.indirectRISCandidateCount, + bakeInput.lightingSettings.indirectEmissiveSamplingMode); List eventsToWaitFor = new(); List buffersToDestroy = new(); diff --git a/Packages/com.unity.render-pipelines.core/Editor/Settings/PropertyDrawers/DefaultVolumeProfileSettingsPropertyDrawer.cs b/Packages/com.unity.render-pipelines.core/Editor/Settings/PropertyDrawers/DefaultVolumeProfileSettingsPropertyDrawer.cs index bd307155ce0..3e1a845611b 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Settings/PropertyDrawers/DefaultVolumeProfileSettingsPropertyDrawer.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Settings/PropertyDrawers/DefaultVolumeProfileSettingsPropertyDrawer.cs @@ -132,7 +132,7 @@ void IRenderPipelineGraphicsSettingsContextMenu2.PopulateContextMenu(T bool canCreateNewAsset = RenderPipelineManager.currentPipeline is TRenderPipeline; VolumeProfileUtils.AddVolumeProfileContextMenuItems(ref menu, setting.volumeProfile, - s_DefaultVolumeProfileEditor.allEditors, + s_DefaultVolumeProfileEditor == null ? null : s_DefaultVolumeProfileEditor.allEditors, overrideStateOnReset: true, defaultVolumeProfilePath: defaultVolumeProfilePath, onNewVolumeProfileCreated: createdProfile => @@ -151,7 +151,7 @@ void IRenderPipelineGraphicsSettingsContextMenu2.PopulateContextMenu(T } VolumeProfileUtils.UpdateGlobalDefaultVolumeProfile(createdProfile, initialAsset); }, - onComponentEditorsExpandedCollapsed: s_DefaultVolumeProfileEditor.RebuildListViews, + onComponentEditorsExpandedCollapsed: s_DefaultVolumeProfileEditor == null ? null : s_DefaultVolumeProfileEditor.RebuildListViews, canCreateNewAsset); } } diff --git a/Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchSelectors.uss b/Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchColumnProviders.uss similarity index 100% rename from Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchSelectors.uss rename to Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchColumnProviders.uss diff --git a/Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchSelectors.uss.meta b/Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchColumnProviders.uss.meta similarity index 100% rename from Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchSelectors.uss.meta rename to Packages/com.unity.render-pipelines.core/Editor/StyleSheets/LightingSearchColumnProviders.uss.meta diff --git a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentEditor.cs b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentEditor.cs index 13367b7e2ac..faf442d8768 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentEditor.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentEditor.cs @@ -196,7 +196,6 @@ internal void SetVolumeProfile(VolumeProfile p) static Dictionary s_ParameterDrawers; SupportedOnRenderPipelineAttribute m_SupportedOnRenderPipelineAttribute; - Type[] m_LegacyPipelineTypes; static VolumeComponentEditor() { @@ -274,11 +273,6 @@ internal void Init() var volumeComponentType = volumeComponent.GetType(); m_SupportedOnRenderPipelineAttribute = volumeComponentType.GetCustomAttribute(); - -#pragma warning disable CS0618 - var supportedOn = volumeComponentType.GetCustomAttribute(); - m_LegacyPipelineTypes = supportedOn != null ? supportedOn.pipelineTypes : Array.Empty(); -#pragma warning restore CS0618 } internal void DetermineVisibility(Type renderPipelineAssetType, Type renderPipelineType) @@ -295,12 +289,6 @@ internal void DetermineVisibility(Type renderPipelineAssetType, Type renderPipel return; } - if (renderPipelineType != null && m_LegacyPipelineTypes.Length > 0) - { - visible = m_LegacyPipelineTypes.Contains(renderPipelineType); - return; - } - visible = true; } @@ -440,6 +428,7 @@ public override void OnInspectorGUI() } } + GUIContent m_DisplayTitle; /// /// Sets the label for the component header. Override this method to provide /// a custom label. If you don't, Unity automatically obtains one from the class name. @@ -447,17 +436,19 @@ public override void OnInspectorGUI() /// A label to display in the component header. public virtual GUIContent GetDisplayTitle() { + if (m_DisplayTitle != null) return m_DisplayTitle; + var volumeComponentType = volumeComponent.GetType(); var displayInfo = volumeComponentType.GetCustomAttribute(); if (displayInfo != null && !string.IsNullOrWhiteSpace(displayInfo.name)) - return EditorGUIUtility.TrTextContent(displayInfo.name, string.Empty); - + return m_DisplayTitle = EditorGUIUtility.TrTextContent(displayInfo.name, string.Empty); + #pragma warning disable CS0618 if (!string.IsNullOrWhiteSpace(volumeComponent.displayName)) - return EditorGUIUtility.TrTextContent(volumeComponent.displayName, string.Empty); + return m_DisplayTitle = EditorGUIUtility.TrTextContent(volumeComponent.displayName, string.Empty); #pragma warning restore CS0618 - - return EditorGUIUtility.TrTextContent(ObjectNames.NicifyVariableName(volumeComponentType.Name) , string.Empty); + + return m_DisplayTitle = EditorGUIUtility.TrTextContent(ObjectNames.NicifyVariableName(volumeComponentType.Name), string.Empty); } void AddToggleState(GUIContent content, bool state) diff --git a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs index 8dafa09cd61..06e40d35659 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeComponentListEditor.cs @@ -155,6 +155,8 @@ void CreateEditor(VolumeComponent component, SerializedProperty property, int in else m_Editors[index] = editor; + FilterEditorsBySearch(); + DocumentationUtils.TryGetHelpURL(component.GetType(), out string helpUrl); helpUrl ??= string.Empty; m_VolumeComponentHelpUrls[editor] = helpUrl; @@ -222,9 +224,22 @@ public void Clear() asset = null; } + readonly HashSet m_CurrentSearchFilteredEditors = new(); + void FilterEditorsBySearch() + { + m_CurrentSearchFilteredEditors.Clear(); + if (string.IsNullOrEmpty(m_SearchString)) return; + + foreach (var editor in m_Editors) + { + if (MatchesSearchString(editor.GetDisplayTitle().text)) + m_CurrentSearchFilteredEditors.Add(editor); + } + } + bool EditorIsIncludedInCurrentSearch(VolumeComponentEditor editor) => string.IsNullOrEmpty(m_SearchString) || m_CurrentSearchFilteredEditors.Contains(editor); bool MatchesSearchString(string title) { - return m_SearchString.Length == 0 || title.Contains(m_SearchString, StringComparison.OrdinalIgnoreCase); + return string.IsNullOrEmpty(m_SearchString) || title.Contains(m_SearchString, StringComparison.OrdinalIgnoreCase); } /// @@ -263,7 +278,7 @@ bool ShouldDrawEditor(VolumeComponentEditor editor) { if (!editor.visible) return false; - return MatchesSearchString(editor.GetDisplayTitle().text); + return EditorIsIncludedInCurrentSearch(editor); } void DrawEditor(VolumeComponentEditor editor, int index = -1) @@ -310,7 +325,11 @@ void DrawEditor(VolumeComponentEditor editor, int index = -1) { Rect searchRect = GUILayoutUtility.GetRect(50, EditorGUIUtility.singleLineHeight); searchRect.width -= 2; - m_SearchString = m_SearchField.OnGUI(searchRect, m_SearchString); + using (var check = new EditorGUI.ChangeCheckScope()) + { + m_SearchString = m_SearchField.OnGUI(searchRect, m_SearchString); + if (check.changed) FilterEditorsBySearch(); + } GUILayout.Space(2); EditorGUILayout.HelpBox( @@ -346,7 +365,6 @@ void DrawEditor(VolumeComponentEditor editor, int index = -1) for (int i = 0; i < editors.Count; i++) DrawEditor(editors[i]); - GUILayout.Space(8); } } diff --git a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeProfileUtils.cs b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeProfileUtils.cs index 59b79a90346..b1368c76eb0 100644 --- a/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeProfileUtils.cs +++ b/Packages/com.unity.render-pipelines.core/Editor/Volume/VolumeProfileUtils.cs @@ -140,19 +140,19 @@ static VolumeComponent GetVolumeComponentOfTypeOrDefault(this VolumeProfile prof static List GetTypesMissingFromDefaultProfile(VolumeProfile profile) { List missingTypes = new List(); - var volumeComponentTypes = VolumeManager.instance.baseComponentTypeArray; + + var volumeComponentTypes = VolumeManager.instance.isInitialized ? + VolumeManager.instance.baseComponentTypeArray : VolumeManager.instance.LoadBaseTypesByReflection(GraphicsSettings.currentRenderPipelineAssetType); foreach (var type in volumeComponentTypes) { if (profile.components.Find(c => c.GetType() == type) == null) { - if (type.IsDefined(typeof(ObsoleteAttribute), false) || - type.IsDefined(typeof(HideInInspector), false)) + if (type.IsDefined(typeof(ObsoleteAttribute), false)) continue; missingTypes.Add(type); } } - return missingTypes; } @@ -163,13 +163,14 @@ static List GetTypesMissingFromDefaultProfile(VolumeProfile profile) /// VolumeProfile to use. /// An optional VolumeProfile asset containing default values to use for /// any components that are added to . - public static void EnsureAllOverridesForDefaultProfile(VolumeProfile profile, VolumeProfile defaultValueSource = null) + public static void EnsureAllOverridesForDefaultProfile(VolumeProfile profile, VolumeProfile defaultValueSource = null) => TryEnsureAllOverridesForDefaultProfile(profile, defaultValueSource); + internal static bool TryEnsureAllOverridesForDefaultProfile(VolumeProfile profile, VolumeProfile defaultValueSource = null) { // It's possible that the volume profile is assigned to the default asset inside the HDRP package. In // this case it cannot be modified. User is expected to use HDRP Wizard "Fix" to create a local profile. var path = AssetDatabase.GetAssetPath(profile); if (CoreEditorUtils.IsAssetInReadOnlyPackage(path)) - return; + return false; bool changed = false; int numComponentsBefore = profile.components.Count; @@ -241,6 +242,8 @@ public static void EnsureAllOverridesForDefaultProfile(VolumeProfile profile, Vo VolumeManager.instance.OnVolumeProfileChanged(profile); EditorUtility.SetDirty(profile); } + + return changed; } /// @@ -297,12 +300,14 @@ public static void AddVolumeProfileContextMenuItems( menu.AddItem(Styles.collapseAll, false, () => { - SetComponentEditorsExpanded(componentEditors, false); + if (componentEditors != null) + SetComponentEditorsExpanded(componentEditors, false); onComponentEditorsExpandedCollapsed?.Invoke(); }); menu.AddItem(Styles.expandAll, false, () => { - SetComponentEditorsExpanded(componentEditors, true); + if (componentEditors != null) + SetComponentEditorsExpanded(componentEditors, true); onComponentEditorsExpandedCollapsed?.Invoke(); }); } diff --git a/Packages/com.unity.render-pipelines.core/Runtime-PrivateShared/OnTileValidationLayer.cs b/Packages/com.unity.render-pipelines.core/Runtime-PrivateShared/OnTileValidationLayer.cs index 98e6512b086..d828b805b5f 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime-PrivateShared/OnTileValidationLayer.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime-PrivateShared/OnTileValidationLayer.cs @@ -75,9 +75,8 @@ public void Clear() // >0 = tracked, and used in a raster pass, with the the state being the number of the pass DynamicArray m_HandleStates; - const string m_ErrorMessageValidationIssue = "The On Tile Validation layer has detected an issue: "; - const string m_ErrorMessageHowToResolve = "The On Tile Validation layer is activated with the setting 'On Tile Validation' on the URP Renderer. When activated, it is not allowed to sample (RenderGraph.UseTexture) the cameraColor or cameraDepth (intermediate) textures or the GBuffers or any copies of those." + - "You need to disable any of the following that could cause the issue: a URP setting that would break the native render pass, a ScriptableRenderPass that is enqueued from script, or a ScriptableRenderFeature that is installed on your URP Renderer.\n"; + const string k_ErrorMessageValidationIssue = "The On-Tile Validation layer has detected an issue: "; + const string k_ErrorMessageHowToResolveDefault = "Disable the On-Tile Validation Layer or ensure that all render passes meet the constraints of this layer.\n"; public OnTileValidationLayer() { @@ -87,8 +86,12 @@ public OnTileValidationLayer() m_CurrentPass.Init(); Clear(); + + errorMessageHowToResolve = k_ErrorMessageHowToResolveDefault; } + public string errorMessageHowToResolve { get; set; } + //Assumes input is valid and tracked as on tile. [MethodImpl(MethodImplOptions.AggressiveInlining)] void ValidateNoNonRasterPassInbetween(in TextureHandle input) @@ -107,23 +110,23 @@ void ValidateNoNonRasterPassInbetween(in TextureHandle input) void ThrowNoNonRasterPassInBetween(in TextureHandle input) { var resourceName = renderGraph.GetTextureName(in input); - throw new InvalidOperationException($"{m_ErrorMessageValidationIssue} render pass '{m_CurrentPass.info.name}'" + + throw new InvalidOperationException($"{k_ErrorMessageValidationIssue} render pass '{m_CurrentPass.info.name}'" + $" results in a load action for resource '{resourceName}' due to a previous Unsafe or Compute render pass '{m_LastNonRasterPassInfo.name}'. " + - $"These can't be merged.\n{m_ErrorMessageHowToResolve}"); + $"These can't be merged.\n{errorMessageHowToResolve}"); } void ThrowTextureSamplingException(in TextureHandle input, string methodName) { var resourceName = renderGraph.GetTextureName(in input); - throw new InvalidOperationException($"{m_ErrorMessageValidationIssue} render pass '{m_CurrentPass.info.name}' calls '{methodName}' with resource '{resourceName}'.\n{m_ErrorMessageHowToResolve}"); + throw new InvalidOperationException($"{k_ErrorMessageValidationIssue} render pass '{m_CurrentPass.info.name}' calls '{methodName}' with resource '{resourceName}'.\n{errorMessageHowToResolve}"); } void ThrowNotRasterPassException(in TextureHandle input, string methodName) { var resourceName = renderGraph.GetTextureName(in input); - throw new InvalidOperationException($"{m_ErrorMessageValidationIssue} render pass '{m_CurrentPass.info.name}' calls '{methodName}' with resource '{resourceName}'. " + + throw new InvalidOperationException($"{k_ErrorMessageValidationIssue} render pass '{m_CurrentPass.info.name}' calls '{methodName}' with resource '{resourceName}'. " + $"Unsafe and Compute render passes can't be merged. Use a Raster render pass and ensure that no load/store action will be performed." + - $"\n{m_ErrorMessageHowToResolve}"); + $"\n{errorMessageHowToResolve}"); } const string k_UseTexture = "UseTexture"; diff --git a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Panel.cs b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Panel.cs index f3d85d97b6c..e1cce1f0ab8 100644 --- a/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Panel.cs +++ b/Packages/com.unity.render-pipelines.core/Runtime/Debugging/DebugUI.Panel.cs @@ -4,6 +4,10 @@ using System; +#if UNITY_EDITOR +using UnityEditor; +#endif + #if ENABLE_RENDERING_DEBUGGER_UI using UnityEngine.UIElements; #endif @@ -20,6 +24,8 @@ public partial class DebugUI public class Panel : IContainer, IComparable { #if ENABLE_RENDERING_DEBUGGER_UI + private VisualElement m_HelpButton; + /// public VisualElement Create(DebugUI.Context context) { @@ -29,13 +35,28 @@ public VisualElement Create(DebugUI.Context context) name = displayName + "_Content" }; - var label = container.Q public MaterialProperty reflections; +#if URP_SCREEN_SPACE_REFLECTION + /// + /// The MaterialProperty for screen space reflections. + /// + public MaterialProperty screenSpaceReflections; +#endif + /// /// The MaterialProperty for enabling/disabling clear coat. /// @@ -266,6 +282,9 @@ public LitProperties(MaterialProperty[] properties) // Advanced Props highlights = BaseShaderGUI.FindProperty("_SpecularHighlights", properties, false); reflections = BaseShaderGUI.FindProperty("_EnvironmentReflections", properties, false); +#if URP_SCREEN_SPACE_REFLECTION + screenSpaceReflections = BaseShaderGUI.FindProperty("_ScreenSpaceReflections", properties, false); +#endif clearCoat = BaseShaderGUI.FindProperty("_ClearCoat", properties, false); clearCoatMap = BaseShaderGUI.FindProperty("_ClearCoatMap", properties, false); @@ -470,6 +489,11 @@ public static void SetMaterialKeywords(Material material) if (material.HasProperty("_EnvironmentReflections")) CoreUtils.SetKeyword(material, "_ENVIRONMENTREFLECTIONS_OFF", material.GetFloat("_EnvironmentReflections") == 0.0f); +#if URP_SCREEN_SPACE_REFLECTION + if (material.HasProperty("_ScreenSpaceReflections")) + CoreUtils.SetKeyword(material, "_SCREENSPACEREFLECTIONS_OFF", + material.GetFloat("_ScreenSpaceReflections") == 0.0f); +#endif if (material.HasProperty("_OcclusionMap")) CoreUtils.SetKeyword(material, "_OCCLUSIONMAP", material.GetTexture("_OcclusionMap")); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl index d3f261d1c6b..82128033643 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/CanvasPass.hlsl @@ -80,6 +80,8 @@ Varyings BuildVaryings(Attributes input) float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); float2 maskUV = (input.positionOS.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); output.texCoord1 = float4(input.positionOS.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy))); + #else + output.texCoord1 = input.uv1; #endif #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl index 034743f2b48..a54f26e4a9f 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthNormalsOnlyPass.hlsl @@ -57,6 +57,10 @@ void frag( outNormalWS = half4(NormalizeNormalPerPixel(normalWS), 0.0); #endif + #if defined(_WRITE_SMOOTHNESS) + outNormalWS.a = surfaceDescription.Smoothness; + #endif + #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl index 980437a6ba8..3af6f1f101d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/MotionVectorPass.hlsl @@ -184,6 +184,9 @@ float4 frag( #if defined(APPLICATION_SPACE_WARP_MOTION) + #if APPLICATION_SPACE_WARP_MOTION_TRANSPARENT && defined(_SURFACE_TYPE_TRANSPARENT) + clip(surfaceDescription.Alpha - 0.001); + #endif return float4(CalcAswNdcMotionVectorFromCsPositions(mvInput.positionCSNoJitter, mvInput.previousPositionCSNoJitter), 1); #else return float4(CalcNdcMotionVectorFromCsPositions(mvInput.positionCSNoJitter, mvInput.previousPositionCSNoJitter), 0, 0); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl index 0acd9e96da6..f205c9f2d84 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRForwardPass.hlsl @@ -58,7 +58,7 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, void InitializeBakedGIData(Varyings input, inout InputData inputData) { #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, input.sh, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl index 22247357d87..83e8ca7df59 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/PBRGBufferPass.hlsl @@ -54,7 +54,7 @@ void InitializeInputData(Varyings input, SurfaceDescription surfaceDescription, void InitializeBakedGIData(Varyings input, inout InputData inputData) { #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, input.sh, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); @@ -136,7 +136,9 @@ GBufferFragOutput frag(PackedVaryings packedInput) Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); - half3 color = GlobalIllumination(brdfData, inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS); + half3 color = GlobalIllumination(brdfData, (BRDFData)0, 0, + inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); return PackGBuffersBRDFData(brdfData, inputData, surfaceDescription.Smoothness, surfaceDescription.Emission + color, surfaceDescription.Occlusion); } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl index c1f3e090c13..73b59f438db 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShaderPassDecal.hlsl @@ -88,7 +88,7 @@ void InitializeInputData(Varyings input, float3 positionWS, half3 normalWS, half #endif #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, normalWS); #elif defined(VARYINGS_NEED_DYNAMIC_LIGHTMAP_UV) && defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV.xy, half3(input.sh), normalWS); #if defined(VARYINGS_NEED_STATIC_LIGHTMAP_UV) diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/DepthNormalsOnlyPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/DepthNormalsOnlyPass.hlsl index 222e3d2fb19..92db032351d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/DepthNormalsOnlyPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/DepthNormalsOnlyPass.hlsl @@ -27,11 +27,24 @@ void frag(PackedVaryings packedInput, half alpha = AlphaDiscard(surfaceDescription.Alpha, surfaceDescription.AlphaClipThreshold); #endif - half3 normalWS = GetTerrainNormalWS(unpacked, surfaceDescription); #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); #endif + + half3 normalWS = GetTerrainNormalWS(unpacked, surfaceDescription); +#if defined(_GBUFFER_NORMALS_OCT) + normalWS = normalize(normalWS); + float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms + float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1] + half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS); // values between [ 0, 1] + color = half4(packedNormalWS, 0.0); +#else color = half4(NormalizeNormalPerPixel(normalWS), 0.0); +#endif + +#if defined(_WRITE_SMOOTHNESS) + color.a = surfaceDescription.Smoothness; +#endif } #endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl index 8d6f188373b..8cc1fd2b91b 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Terrain/PBRGBufferPass.hlsl @@ -107,7 +107,9 @@ GBufferFragOutput frag(PackedVaryings packedInput) half4 color; Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, inputData.shadowMask); MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, inputData.shadowMask); - color.rgb = GlobalIllumination(brdfData, inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, inputData.normalWS, inputData.viewDirectionWS); + color.rgb = GlobalIllumination(brdfData, (BRDFData)0, 0, + inputData.bakedGI, surfaceDescription.Occlusion, inputData.positionWS, + inputData.normalWS, inputData.viewDirectionWS, inputData.normalizedScreenSpaceUV); color.a = alpha; SplatmapFinalColor(color, inputData.fogCoord); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs index e2eaebe08cd..e2e0897433f 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalLitSubTarget.cs @@ -119,7 +119,9 @@ public override void ProcessPreviewMaterial(Material material) material.SetFloat(Property.QueueControl, (float)BaseShaderGUI.QueueControl.Auto); if (IsSpacewarpSupported()) + { material.SetFloat(Property.XrMotionVectorsPass, 1.0f); + } // call the full unlit material setup function ShaderGraphLitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial); @@ -201,7 +203,9 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera collector.AddFloatProperty(Property.QueueControl, -1.0f); if (IsSpacewarpSupported()) + { collector.AddFloatProperty(Property.XrMotionVectorsPass, 1.0f); + } } public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) @@ -380,8 +384,8 @@ public static SubShaderDescriptor LitSubShader(UniversalTarget target, WorkflowM // Currently neither of these passes (selection/picking) can be last for the game view for // UI shaders to render correctly. Verify [1352225] before changing this order. - result.passes.Add(PassVariant(CorePasses.SceneSelection(target), CorePragmas.Default)); - result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.Default)); + result.passes.Add(PassVariant(CorePasses.SceneSelection(target), CorePragmas.Instanced)); + result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.Instanced)); result.passes.Add(PassVariant(LitPasses._2D(target), CorePragmas.Default)); return result; @@ -655,7 +659,7 @@ public static PassDescriptor DepthNormal(UniversalTarget target) renderStates = CoreRenderStates.DepthNormalsOnly(target), pragmas = CorePragmas.Instanced, defines = new DefineCollection(), - keywords = new KeywordCollection(), + keywords = new KeywordCollection { CoreKeywordDescriptors.WriteSmoothness, CoreKeywordDescriptors.GBufferNormalsOct }, includes = new IncludeCollection { CoreIncludes.DepthNormalsOnly }, // Custom Interpolator Support @@ -695,7 +699,7 @@ public static PassDescriptor DepthNormalOnly(UniversalTarget target) renderStates = CoreRenderStates.DepthNormalsOnly(target), pragmas = CorePragmas.Instanced, defines = new DefineCollection(), - keywords = new KeywordCollection(), + keywords = new KeywordCollection { CoreKeywordDescriptors.WriteSmoothness }, includes = new IncludeCollection { CoreIncludes.DepthNormalsOnly }, // Custom Interpolator Support @@ -844,6 +848,7 @@ static class LitKeywords public static readonly KeywordCollection Forward = new KeywordCollection { { CoreKeywordDescriptors.ScreenSpaceAmbientOcclusion }, + { CoreKeywordDescriptors.ScreenSpaceReflection }, { CoreKeywordDescriptors.ScreenSpaceIrradiance }, { CoreKeywordDescriptors.StaticLightmap }, { CoreKeywordDescriptors.DynamicLightmap }, @@ -870,6 +875,7 @@ static class LitKeywords public static readonly KeywordCollection GBuffer = new KeywordCollection { + { CoreKeywordDescriptors.ScreenSpaceReflection }, { CoreKeywordDescriptors.ScreenSpaceIrradiance }, { CoreKeywordDescriptors.StaticLightmap }, { CoreKeywordDescriptors.DynamicLightmap }, diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs index 2566168cdd1..86b25f5d134 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs @@ -1421,6 +1421,7 @@ class CoreBlockMasks public static readonly BlockFieldDescriptor[] FragmentDepthNormals = new BlockFieldDescriptor[] { + BlockFields.SurfaceDescription.Smoothness, BlockFields.SurfaceDescription.NormalOS, BlockFields.SurfaceDescription.NormalTS, BlockFields.SurfaceDescription.NormalWS, @@ -1684,6 +1685,8 @@ public static RenderStateCollection ScenePicking(UniversalTarget target) #region Pragmas static class CorePragmas { + public static PragmaDescriptor MultiCompileAppSpacewarpTransparent => new PragmaDescriptor { value = "multi_compile _ APPLICATION_SPACE_WARP_MOTION_TRANSPARENT" }; + public static readonly PragmaCollection Default = new PragmaCollection { { Pragma.Target(ShaderModel.Target20) }, @@ -1711,6 +1714,7 @@ static class CorePragmas { { Pragma.Target(ShaderModel.Target35) }, { Pragma.MultiCompileInstancing }, + { MultiCompileAppSpacewarpTransparent }, { Pragma.Vertex("vert") }, { Pragma.Fragment("frag") }, }; @@ -2395,6 +2399,25 @@ static class CoreKeywordDescriptors stages = KeywordShaderStage.Fragment, }; + public static readonly KeywordDescriptor ScreenSpaceReflection = new KeywordDescriptor() + { + displayName = "Screen Space Reflection", + referenceName = "_SCREEN_SPACE_REFLECTION", + type = KeywordType.Boolean, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global, + stages = KeywordShaderStage.Fragment, + }; + + public static readonly KeywordDescriptor WriteSmoothness = new KeywordDescriptor() + { + displayName = "Write Smoothness", + referenceName = "_WRITE_SMOOTHNESS", + type = KeywordType.Boolean, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global, + }; + public static readonly KeywordDescriptor UseLegacyLightmaps = new KeywordDescriptor() { displayName = "Use Legacy Lightmaps", diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs index b385663ea79..2d3d217f03d 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTerrainLitSubTarget.cs @@ -1056,7 +1056,7 @@ public static PassDescriptor DepthNormal(UniversalTarget target) renderStates = CoreRenderStates.DepthNormalsOnly(target), pragmas = TerrainCorePragmas.Instanced, defines = new DefineCollection(), - keywords = new KeywordCollection() { TerrainSubShaders.AlphaTestOn, }, + keywords = new KeywordCollection() { TerrainSubShaders.AlphaTestOn, CoreKeywordDescriptors.WriteSmoothness, CoreKeywordDescriptors.GBufferNormalsOct }, includes = TerrainCoreIncludes.DepthNormalsOnly, // Custom Interpolator Support @@ -1502,6 +1502,7 @@ static class TerrainLitKeywords public static readonly KeywordCollection Forward = new KeywordCollection { { ScreenSpaceAmbientOcclusion }, + { CoreKeywordDescriptors.ScreenSpaceReflection }, { CoreKeywordDescriptors.StaticLightmap }, { CoreKeywordDescriptors.DynamicLightmap }, { CoreKeywordDescriptors.DirectionalLightmapCombined }, @@ -1533,6 +1534,7 @@ static class TerrainLitKeywords { CoreKeywordDescriptors.GBufferNormalsOct }, { CoreKeywordDescriptors.LightLayers }, { CoreKeywordDescriptors.RenderPassEnabled }, + { CoreKeywordDescriptors.ScreenSpaceReflection }, { CoreKeywordDescriptors.DebugDisplay }, }; } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs index d7a8d509b3d..c2da6cb31c9 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalUnlitSubTarget.cs @@ -95,7 +95,9 @@ public override void ProcessPreviewMaterial(Material material) material.SetFloat(Property.QueueControl, (float)BaseShaderGUI.QueueControl.Auto); if (IsSpacewarpSupported()) + { material.SetFloat(Property.XrMotionVectorsPass, 1.0f); + } // call the full unlit material setup function ShaderGraphUnlitGUI.UpdateMaterial(material, MaterialUpdateType.CreatedNewMaterial); @@ -142,7 +144,9 @@ public override void CollectShaderProperties(PropertyCollector collector, Genera collector.AddFloatProperty(Property.QueueControl, -1.0f); if (IsSpacewarpSupported()) + { collector.AddFloatProperty(Property.XrMotionVectorsPass, 1.0f); + } } public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Action onChange, Action registerUndo) @@ -262,8 +266,8 @@ public static SubShaderDescriptor Unlit(UniversalTarget target, string renderTyp // Currently neither of these passes (selection/picking) can be last for the game view for // UI shaders to render correctly. Verify [1352225] before changing this order. - result.passes.Add(PassVariant(CorePasses.SceneSelection(target), CorePragmas.Default)); - result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.Default)); + result.passes.Add(PassVariant(CorePasses.SceneSelection(target), CorePragmas.Instanced)); + result.passes.Add(PassVariant(CorePasses.ScenePicking(target), CorePragmas.Instanced)); return result; } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs b/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs index 0e5cd32bcda..387aefc1931 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/ShaderScriptableStripper.cs @@ -159,6 +159,8 @@ public bool PassHasKeyword(LocalKeyword keyword) LocalKeyword m_GbufferNormalsOct; LocalKeyword m_ScreenSpaceOcclusion; LocalKeyword m_ScreenSpaceIrradiance; + LocalKeyword m_ScreenSpaceReflection; + LocalKeyword m_WriteSmoothness; LocalKeyword m_UseFastSRGBLinearConversion; LocalKeyword m_LightLayers; LocalKeyword m_DecalLayers; @@ -230,6 +232,8 @@ private void InitializeLocalShaderKeywords([DisallowNull] Shader shader) m_GbufferNormalsOct = TryGetLocalKeyword(shader, ShaderKeywordStrings._GBUFFER_NORMALS_OCT); m_ScreenSpaceOcclusion = TryGetLocalKeyword(shader, ShaderKeywordStrings.ScreenSpaceOcclusion); m_ScreenSpaceIrradiance = TryGetLocalKeyword(shader, ShaderKeywordStrings.ScreenSpaceIrradiance); + m_ScreenSpaceReflection = TryGetLocalKeyword(shader, ShaderKeywordStrings.ScreenSpaceReflection); + m_WriteSmoothness = TryGetLocalKeyword(shader, ShaderKeywordStrings.WriteSmoothness); m_UseFastSRGBLinearConversion = TryGetLocalKeyword(shader, ShaderKeywordStrings.UseFastSRGBLinearConversion); m_LightLayers = TryGetLocalKeyword(shader, ShaderKeywordStrings.LightLayers); m_DecalLayers = TryGetLocalKeyword(shader, ShaderKeywordStrings.DecalLayers); @@ -666,6 +670,22 @@ internal bool StripUnusedFeatures_ScreenSpaceOcclusion(ref IShaderScriptableStri return false; } + internal bool StripUnusedFeatures_ScreenSpaceReflection(ref IShaderScriptableStrippingData strippingData, ref ShaderStripTool stripTool) + { +#if URP_SCREEN_SPACE_REFLECTION + // Screen Space Reflection + if (stripTool.StripMultiCompile(m_ScreenSpaceReflection, ShaderFeatures.ScreenSpaceReflection)) + return true; + + if (stripTool.StripMultiCompile(m_WriteSmoothness, ShaderFeatures.ScreenSpaceReflection)) + return true; + + return false; +#else + return strippingData.IsKeywordEnabled(m_ScreenSpaceReflection) || strippingData.IsKeywordEnabled(m_WriteSmoothness); +#endif + } + internal bool StripUnusedFeatures_DecalsDbuffer(ref IShaderScriptableStrippingData strippingData, ref ShaderStripTool stripTool) { // DBuffer @@ -727,6 +747,15 @@ internal bool StripUnusedFeatures_WriteRenderingLayers(ref IShaderScriptableStri { if (strippingData.passName == kPassNameDepthNormals) { +#if URP_SCREEN_SPACE_REFLECTION + // If SSR is enabled, always keep the variant with WriteRenderingLayers disabled. We need this for the SSR transparent depthnormal pass. + if (strippingData.IsShaderFeatureEnabled(ShaderFeatures.ScreenSpaceReflection)) + { + if (stripTool.StripMultiCompileKeepOffVariant(m_WriteRenderingLayers, ShaderFeatures.DepthNormalPassRenderingLayers)) + return true; + } + else +#endif if (stripTool.StripMultiCompile(m_WriteRenderingLayers, ShaderFeatures.DepthNormalPassRenderingLayers)) return true; } @@ -896,6 +925,9 @@ internal bool StripUnusedFeatures(ref IShaderScriptableStrippingData strippingDa if (StripUnusedFeatures_ScreenSpaceOcclusion(ref strippingData, ref stripTool)) return true; + if (StripUnusedFeatures_ScreenSpaceReflection(ref strippingData, ref stripTool)) + return true; + if (StripUnusedFeatures_DecalsDbuffer(ref strippingData, ref stripTool)) return true; @@ -1056,13 +1088,13 @@ internal bool StripUnusedPass_2D(ref IShaderScriptableStrippingData strippingDat internal bool StripUnusedPass_Meta(ref IShaderScriptableStrippingData strippingData) { - // Meta pass is needed in the player for Enlighten Precomputed Realtime GI albedo and emission. + // Meta pass is needed for Enlighten and Surface Cache realtime GI systems. if (strippingData.passType == PassType.Meta) { if (SupportedRenderingFeatures.active.enlighten == false - || ((int)SupportedRenderingFeatures.active.lightmapBakeTypes | (int)LightmapBakeType.Realtime) == 0 + && ((int)SupportedRenderingFeatures.active.lightmapBakeTypes | (int)LightmapBakeType.Realtime) == 0 #if SURFACE_CACHE - || !strippingData.IsShaderFeatureEnabled(ShaderFeatures.SurfaceCache) + && !strippingData.IsShaderFeatureEnabled(ShaderFeatures.SurfaceCache) #endif ) return true; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/AnimationClipConverter/AnimationClipConverter.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/AnimationClipConverter/AnimationClipConverter.cs index d2474e9b732..314ebf0656a 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/AnimationClipConverter/AnimationClipConverter.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/AnimationClipConverter/AnimationClipConverter.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Text; -using NUnit.Framework; using UnityEditor.Rendering.Converter; using UnityEngine; using UnityEngine.Categorization; +using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using static UnityEditor.Rendering.AnimationClipUpgrader; using ClipPath = UnityEditor.Rendering.AnimationClipUpgrader.ClipPath; @@ -46,6 +46,18 @@ public AnimationClipConverterItem(GlobalObjectId gid, string assetPath) Description = "Updates animation clips that reference material properties to work with URP shaders.\nEnsures material animations continue working after converting Materials from Built-in RP to URP.")] internal sealed class AnimationClipConverter : IRenderPipelineConverter { + public bool isEnabled + { + get + { + if (GraphicsSettings.currentRenderPipeline is not UniversalRenderPipelineAsset urpAsset) + return false; + + return urpAsset.scriptableRenderer is UniversalRenderer; + } + } + public string isDisabledMessage => "Converter requires URP with an Universal Renderer. Convert your project to URP to use this converter."; + [SerializeField] internal List assets = new(); @@ -106,14 +118,21 @@ void OnAnimationClipDependenciesSearchFinish() ( SearchServiceUtils.IndexingOptions.DeepSearch, query, - (searchItem, path) => + (item, path) => { - if (searchItem.ToObject() is not GameObject go || go.scene == null) + var unityObject = item.ToObject(); + + if (unityObject == null) return; - var gid = GlobalObjectId.GetGlobalObjectIdSlow(go); + var gid = GlobalObjectId.GetGlobalObjectIdSlow(unityObject); + int type = gid.identifierType; // 1=Asset, 2=SceneObject - var assetItem = new RenderPipelineConverterAssetItem(gid, go.scene.path); + var assetItem = new RenderPipelineConverterAssetItem(gid.ToString()) + { + name = unityObject.name, + info = path, + }; if (animatorUsingClip.TryGetValue(path, out var list)) { diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DMaterialUpgrader.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DMaterialUpgrader.cs index 0e97e287d06..b503bc5c6f5 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DMaterialUpgrader.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/BuiltInToURP3DMaterialUpgrader.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using UnityEditor.Rendering.Converter; using UnityEngine.Categorization; +using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; namespace UnityEditor.Rendering.Universal @@ -14,6 +15,20 @@ namespace UnityEditor.Rendering.Universal Description = "This converter scans all materials that reference Built-in shaders and upgrades them to use Universal Render Pipeline (URP) shaders.")] internal sealed class BuiltInToURP3DMaterialUpgrader : RenderPipelineConverterMaterialUpgrader { + + public override bool isEnabled + { + get + { + if (GraphicsSettings.currentRenderPipeline is not UniversalRenderPipelineAsset urpAsset) + return false; + + return urpAsset.scriptableRenderer is UniversalRenderer; + } + } + + public override string isDisabledMessage => "Converter requires URP with a Universal Renderer. Convert your project to URP to use this converter."; + internal static List FetchMaterialUpgraders() { var allURPUpgraders = MaterialUpgrader.FetchAllUpgradersForPipeline(typeof(UniversalRenderPipelineAsset)); diff --git a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/PPv2/PPv2Converter.cs b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/PPv2/PPv2Converter.cs index 094c8f94d97..943eade6a22 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/PPv2/PPv2Converter.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/Tools/Converters/PPv2/PPv2Converter.cs @@ -1,20 +1,22 @@ -#if PPV2_EXISTS using System; using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; using System.Text; -using UnityEditor.SceneManagement; -using UnityEngine.Categorization; using UnityEditor.Rendering.Converter; +using UnityEngine.Categorization; +using UnityEngine.Rendering.Universal; + +#if PPV2_EXISTS using UnityEngine; using UnityEngine.Rendering; -using UnityEngine.Rendering.Universal; -using UnityEngine.SceneManagement; +using System.IO; +using System.Linq; +using System.Reflection; +using UnityEditor.SceneManagement; using BIRPRendering = UnityEngine.Rendering.PostProcessing; +using UnityEngine.SceneManagement; using Object = UnityEngine.Object; using URPRendering = UnityEngine.Rendering.Universal; +#endif namespace UnityEditor.Rendering.Universal { @@ -28,6 +30,7 @@ namespace UnityEditor.Rendering.Universal internal class PPv2Converter : AssetsConverter { +#if PPV2_EXISTS public override bool isEnabled => s_PostProcessTypesToSearch?.Count() > 0; public override string isDisabledMessage => "Missing types to search"; @@ -484,6 +487,12 @@ public IEnumerable GetAllBIRPConverters() return derivedTypes; } +#else + public override bool isEnabled => false; + public override string isDisabledMessage => "Post Processing package is not installed. Please install the Post Processing package package to enable this converter."; + protected override List<(string query, string description)> contextSearchQueriesAndIds + => null; + protected override Status ConvertObject(UnityEngine.Object obj, StringBuilder message) { return Status.Error; } +#endif } } -#endif diff --git a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs index cac806e7568..206a82fb1b5 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Drawers.cs @@ -132,7 +132,7 @@ internal static void Expand(Expandable expandable, bool state) } public static readonly CED.IDrawer Inspector = CED.Group( - CED.Group(PrepareOnTileValidationWarning), + CED.Group(PrepareTileOnlyModeWarning), CED.AdditionalPropertiesFoldoutGroup(Styles.renderingSettingsText, Expandable.Rendering, k_ExpandedState, ExpandableAdditional.Rendering, k_AdditionalPropertiesState, DrawRendering, DrawRenderingAdditional), CED.FoldoutGroup(Styles.qualitySettingsText, Expandable.Quality, k_ExpandedState, DrawQuality), CED.AdditionalPropertiesFoldoutGroup(Styles.lightingSettingsText, Expandable.Lighting, k_ExpandedState, ExpandableAdditional.Lighting, k_AdditionalPropertiesState, DrawLighting, DrawLightingAdditional), @@ -160,10 +160,10 @@ static void DrawRendering(SerializedUniversalRenderPipelineAsset serialized, Edi EditorGUILayout.HelpBox(Styles.rendererUnsupportedAPIMessage.text + unsupportedGraphicsApisMessage, MessageType.Warning, true); EditorGUILayout.PropertyField(serialized.requireDepthTextureProp, Styles.requireDepthTextureText); - DisplayOnTileValidationWarning(serialized.requireDepthTextureProp, p => p.boolValue, Styles.requireDepthTextureText); + DisplayTileOnlyHelpBox(serialized.requireDepthTextureProp, p => p.boolValue, Styles.requireDepthTextureText); EditorGUILayout.PropertyField(serialized.requireOpaqueTextureProp, Styles.requireOpaqueTextureText); - DisplayOnTileValidationWarning(serialized.requireOpaqueTextureProp, p => p.boolValue, Styles.requireOpaqueTextureText); + DisplayTileOnlyHelpBox(serialized.requireOpaqueTextureProp, p => p.boolValue, Styles.requireOpaqueTextureText); EditorGUI.BeginDisabledGroup(!serialized.requireOpaqueTextureProp.boolValue); EditorGUILayout.PropertyField(serialized.opaqueDownsamplingProp, Styles.opaqueDownsamplingText); @@ -181,7 +181,7 @@ static void DrawRendering(SerializedUniversalRenderPipelineAsset serialized, Edi ++EditorGUI.indentLevel; serialized.smallMeshScreenPercentage.floatValue = Mathf.Clamp(EditorGUILayout.FloatField(Styles.smallMeshScreenPercentage, serialized.smallMeshScreenPercentage.floatValue), 0.0f, 20.0f); EditorGUILayout.PropertyField(serialized.gpuResidentDrawerEnableOcclusionCullingInCameras, Styles.gpuResidentDrawerEnableOcclusionCullingInCameras); - DisplayOnTileValidationWarning(serialized.gpuResidentDrawerEnableOcclusionCullingInCameras, p => p.boolValue, Styles.gpuResidentDrawerEnableOcclusionCullingInCameras); + DisplayTileOnlyHelpBox(serialized.gpuResidentDrawerEnableOcclusionCullingInCameras, p => p.boolValue, Styles.gpuResidentDrawerEnableOcclusionCullingInCameras); --EditorGUI.indentLevel; if (brgStrippingError) @@ -193,7 +193,10 @@ static void DrawRendering(SerializedUniversalRenderPipelineAsset serialized, Edi } } if (lightingModeError) - EditorGUILayout.HelpBox(Styles.lightModeErrorMessage.text, MessageType.Warning, true); + { + var renderersToChange = GetRendererNamesWithoutCorrectLightingMode(serialized.asset); + EditorGUILayout.HelpBox(string.Format(Styles.lightModeErrorFormatter, renderersToChange), MessageType.Error, true); + } if (staticBatchingWarning) EditorGUILayout.HelpBox(Styles.staticBatchingInfoMessage.text, MessageType.Info, true); } @@ -215,6 +218,41 @@ private static bool HasCorrectLightingModes(UniversalRenderPipelineAsset asset) return true; } + /// Formats renderer names as "'Name1', 'Name2'" using pooled StringBuilder. Shared by Tile-Only Mode and lighting mode messages. + static string FormatRendererNames(IEnumerable collection, string suffix = "") + { + if (collection == null) + return string.Empty; + using var _ = StringBuilderPool.Get(out var sb); + var first = true; + foreach (var r in collection) + { + if (r == null) + continue; + if (!first) + sb.Append(", "); + sb.Append("'").Append(r.name).Append("'").Append(suffix); + first = false; + } + return sb.ToString(); + } + + private static IEnumerable GetRenderersWithoutCorrectLightingMode(UniversalRenderPipelineAsset asset) + { + if (asset?.m_RendererDataList == null) + yield break; + foreach (var rendererData in asset.m_RendererDataList) + { + if (rendererData == null) + continue; + if (rendererData is not UniversalRendererData universalRendererData || !universalRendererData.usesClusterLightLoop) + yield return rendererData; + } + } + + private static string GetRendererNamesWithoutCorrectLightingMode(UniversalRenderPipelineAsset asset) + => FormatRendererNames(GetRenderersWithoutCorrectLightingMode(asset)); + static void DrawRenderingAdditional(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) { EditorGUILayout.PropertyField(serialized.srpBatcher, Styles.srpBatcher); @@ -243,15 +281,15 @@ static void DrawQuality(SerializedUniversalRenderPipelineAsset serialized, Edito DrawHDR(serialized, ownerEditor); EditorGUILayout.PropertyField(serialized.msaa, Styles.msaaText); - DisplayOnTileValidationWarning( + DisplayTileOnlyHelpBox( serialized.msaa, p => p.intValue != (int)MsaaQuality.Disabled // This operation is actually ok on Quest && !IsAndroidXRTargetted(), - Styles.msaaText); + Styles.msaaText, MessageType.Info, Styles.msaaTileOnlyInfo); serialized.renderScale.floatValue = EditorGUILayout.Slider(Styles.renderScaleText, serialized.renderScale.floatValue, UniversalRenderPipeline.minRenderScale, UniversalRenderPipeline.maxRenderScale); - DisplayOnTileValidationWarning( + DisplayTileOnlyHelpBox( serialized.renderScale, p => { @@ -328,7 +366,7 @@ static void DrawUpscalingFilterDropdownAndOptions(SerializedUniversalRenderPipel serialized.selectedUpscalerName.stringValue = namesArray[selectedIndex]; } - DisplayOnTileValidationWarning(serialized.upscalingFilter, p => serialized.selectedUpscalerName.stringValue != UniversalRenderPipeline.k_UpscalerName_Auto, Styles.upscalingFilterText); + DisplayTileOnlyHelpBox(serialized.upscalingFilter, p => serialized.selectedUpscalerName.stringValue != UniversalRenderPipeline.k_UpscalerName_Auto, Styles.upscalingFilterText); // --- 5. Draw Options per upscaler --- string selectedName = namesArray[selectedIndex]; @@ -417,7 +455,7 @@ static void DrawUpscalingFilterDropdownAndOptions(SerializedUniversalRenderPipel serialized.upscalingFilter.enumValueIndex = Math.Min(selectedIndex, (int)UpscalingFilterSelection.STP); } - DisplayOnTileValidationWarning(serialized.upscalingFilter, p => p.intValue != (int)UpscalingFilterSelection.Auto, Styles.upscalingFilterText); + DisplayTileOnlyHelpBox(serialized.upscalingFilter, p => p.intValue != (int)UpscalingFilterSelection.Auto, Styles.upscalingFilterText); // draw upscaler options, if any switch (serialized.asset.upscalingFilter) @@ -451,10 +489,14 @@ static void DrawUpscalingFilterDropdownAndOptions(SerializedUniversalRenderPipel #endif } + public static readonly string disabledPostprocessing = L10n.Tr("HDR is not supported by one of the Universal Render Pipeline renderers."); + static void DrawHDR(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) { EditorGUILayout.PropertyField(serialized.hdr, Styles.hdrText); - DisplayOnTileValidationWarning(serialized.hdr, p => p.boolValue, Styles.hdrText); + + // A ScriptableRenderFeature can add HDR, for example the OnTilePostProcessing extension. + DisplayTileOnlyHelpBox(serialized.hdr, p => p.boolValue, Styles.hdrText, customMessage: Styles.tileOnlyModeMaybeMessage); // Nested and in-between additional property bool additionalProperties = k_ExpandedState[Expandable.Quality] && k_AdditionalPropertiesState[ExpandableAdditional.Quality]; @@ -859,8 +901,6 @@ static void DrawCascades(SerializedUniversalRenderPipelineAsset serialized, int static void DrawPostProcessing(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) { - DisplayOnTileValidationWarningForPostProcessingSection(Styles.postProcessingSettingsText); - EditorGUILayout.PropertyField(serialized.colorGradingMode, Styles.colorGradingMode); bool isHdrOn = serialized.hdr.boolValue; if (!isHdrOn && serialized.colorGradingMode.intValue == (int)ColorGradingMode.HighDynamicRange) @@ -942,36 +982,33 @@ static void DrawAdaptivePerformance(SerializedUniversalRenderPipelineAsset seria EditorGUILayout.PropertyField(serialized.useAdaptivePerformance, Styles.useAdaptivePerformance); } #endif - - struct OnTileValidationInfos + struct TileOnlyModeInfos { - public bool enabled => !string.IsNullOrEmpty(formatter); - public readonly string formatter; + public bool enabled => !string.IsNullOrEmpty(rendererNames); + public readonly bool isSingleRendererCase; public readonly string rendererNames; - public readonly string rendererNamesWithPostProcess; - public OnTileValidationInfos(string formatter, string rendererNames, string rendererNamesWithPostProcess) + public TileOnlyModeInfos(bool isSingleRendererCase, string rendererNames) { - this.formatter = formatter; + this.isSingleRendererCase = isSingleRendererCase; this.rendererNames = rendererNames; - this.rendererNamesWithPostProcess = rendererNamesWithPostProcess; } } - static OnTileValidationInfos lastOnTileValidationInfos; //prevent computing this multiple time for this ImGUI frame + static TileOnlyModeInfos lastTileOnlyModeInfos; //prevent computing this multiple time for this ImGUI frame - static void PrepareOnTileValidationWarning(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) + static void PrepareTileOnlyModeWarning(SerializedUniversalRenderPipelineAsset serialized, Editor ownerEditor) { // Rules: // - mono selection: - // - only 1 Renderer in the list: Display warning if RendererData's OnTileValidation is enabled - // - many Renderers in the list: Display warning with list of RendererData's where OnTileValidation is enabled + // - only 1 Renderer in the list: Display warning if RendererData's Tile-Only Mode is enabled + // - many Renderers in the list: Display warning with list of RendererData's where Tile-Only Mode is enabled // - multi selection: - // - compute the list interection of RendererDatas where OnTileValidation is enabled amongst all URPAsset in selection + // - compute the list interection of RendererDatas where Tile-Only Mode is enabled amongst all URPAsset in selection // - If list is not empty, display warning with this list. Additionaly specify for item iden due to being at different position // - Additionally for both, for Post Processing section: only show names where Post Processing is enabled - lastOnTileValidationInfos = default; + lastTileOnlyModeInfos = default; // If impacted section are not opened, early exit if (!(k_ExpandedState[Expandable.Rendering] || k_ExpandedState[Expandable.Quality] || k_ExpandedState[Expandable.PostProcessing])) @@ -997,7 +1034,7 @@ IEnumerable ArrayElementPropertyEnumerator(SerializedPropert } } - // Helper to filter the list and get only unique result of UniversalRendererData that have the OnTileValidation. + // Helper to filter the list and get only unique result of UniversalRendererData that have Tile-Only Mode. // The returned IDisposable is for being able to return the HashSet to the pool when Dispose is call like at end of Using. IDisposable SelectUniqueAndCast(IEnumerable properties, out HashSet uniques) { @@ -1006,51 +1043,16 @@ IDisposable SelectUniqueAndCast(IEnumerable properties, out while (e.MoveNext()) if (!e.Current.hasMultipleDifferentValues && e.Current.boxedValue is UniversalRendererData universalData - && universalData.onTileValidation) + && universalData.tileOnlyMode) uniques.Add(universalData); return disposer; } - - // Additional select to filter the one that have PostProcessing enabled. - IEnumerable WherePostProcessingEnabled(IEnumerable renderer) - { - var e = renderer.GetEnumerator(); - while (e.MoveNext()) - if (e.Current.postProcessData != null) - yield return e.Current; - } - - // Helper to draw the name in the collection as a string, between '' and with a coma separator - string ListElementNames(IEnumerable collection, string suffix = "") - { - var e = collection.GetEnumerator(); - if (!e.MoveNext()) - return string.Empty; - - string GetName(IEnumerator e) - => $"'{e.Current.name}'{suffix}"; - - string last = GetName(e); - if (!e.MoveNext()) - return last; - using var o = StringBuilderPool.Get(out var sb); - do - { - sb.Append(last); - last = $", {GetName(e)}"; - } - while (e.MoveNext()); - sb.Append(last); - - return sb.ToString(); - } - // Helper for multiple selection to distinguish element that remain at stable position (in the selection) from others string ConcatCollectionInName(IEnumerable rightlyPositioned, IEnumerable wronglyPositioned) { - var firstPart = ListElementNames(rightlyPositioned); - var secondPart = ListElementNames(wronglyPositioned, Styles.suffixWhenDifferentPositionOnTileValidation); + var firstPart = FormatRendererNames(rightlyPositioned); + var secondPart = FormatRendererNames(wronglyPositioned, Styles.suffixWhenDifferentPositionTileOnlyMode); if (string.IsNullOrEmpty(firstPart)) return secondPart; if (string.IsNullOrEmpty(secondPart)) @@ -1059,7 +1061,6 @@ string ConcatCollectionInName(IEnumerable rightlyPosition } string names = null; - string namesWithPostProcess = null; if (!serialized.rendererDatas.hasMultipleDifferentValues) { // Simple case: all element selected share the same list. @@ -1070,46 +1071,41 @@ string ConcatCollectionInName(IEnumerable rightlyPosition return; if (k_ExpandedState[Expandable.Rendering] || k_ExpandedState[Expandable.Quality]) - names = ListElementNames(renderers); - - if (k_ExpandedState[Expandable.PostProcessing]) - namesWithPostProcess = ListElementNames(WherePostProcessingEnabled(renderers)); - - lastOnTileValidationInfos = new OnTileValidationInfos( - serialized.rendererDatas.arraySize == 1 ? Styles.formatterOnTileValidationOneRenderer : Styles.formatterOnTileValidationMultipleRenderer, - names, - namesWithPostProcess); + names = FormatRendererNames(renderers); + + bool isSingleRendererCase = serialized.rendererDatas.arraySize == 1; + lastTileOnlyModeInfos = new TileOnlyModeInfos(isSingleRendererCase, names); return; } } // Complex case: the renderer list is different in some elements of the selection - // Let's compute the intersection of each RendererList where it is a UniversalRenderer with On-Tile Validation enabled. + // Let's compute the intersection of each RendererList where it is a UniversalRenderer with Tile-Only Mode enabled. // If the intersection is empty, it would means no RendererData validate the criteria so we early exit. // We can retrieve element at stable position by directly checking the serialization of the selection. // Elements in the intersection that are not in the stable positio list are elements shared in all list but with moving index. - // Helper to build the HashSet of UniversalRenderer that have OnTileValidation on one targeted asset. + // Helper to build the HashSet of UniversalRenderer that have Tile-Only Mode on one targeted asset. // The returned IDisposable is for being able to return the HashSet to the pool when Dispose is call like at end of Using. - IDisposable GetUniversalRendererWithOnTileValidationEnabled(UniversalRenderPipelineAsset asset, out HashSet set) + IDisposable GetUniversalRendererWithTileOnlyModeEnabled(UniversalRenderPipelineAsset asset, out HashSet set) { IDisposable disposer = HashSetPool.Get(out set); for (int rendererIndex = 0; rendererIndex < asset.rendererDataList.Length; ++rendererIndex) - if (asset.rendererDataList[rendererIndex] is UniversalRendererData universalData && universalData.onTileValidation) + if (asset.rendererDataList[rendererIndex] is UniversalRendererData universalData && universalData.tileOnlyMode) set.Add(universalData); return disposer; } - using (GetUniversalRendererWithOnTileValidationEnabled((UniversalRenderPipelineAsset)serialized.serializedObject.targetObjects[0], out var movingPositions)) + using (GetUniversalRendererWithTileOnlyModeEnabled((UniversalRenderPipelineAsset)serialized.serializedObject.targetObjects[0], out var movingPositions)) { if (movingPositions.Count == 0) return; for (int i = 1; i < serialized.serializedObject.targetObjects.Length; ++i) - using (GetUniversalRendererWithOnTileValidationEnabled((UniversalRenderPipelineAsset)serialized.serializedObject.targetObjects[i], out var otherIntersection)) + using (GetUniversalRendererWithTileOnlyModeEnabled((UniversalRenderPipelineAsset)serialized.serializedObject.targetObjects[i], out var otherIntersection)) { if (otherIntersection.Count == 0) return; @@ -1124,38 +1120,29 @@ IDisposable GetUniversalRendererWithOnTileValidationEnabled(UniversalRenderPipel movingPositions.Remove(stablePositionElement); if (k_ExpandedState[Expandable.Rendering] || k_ExpandedState[Expandable.Quality]) - names = ConcatCollectionInName(stablePositions, movingPositions); - - if (k_ExpandedState[Expandable.PostProcessing]) - namesWithPostProcess = ConcatCollectionInName(WherePostProcessingEnabled(stablePositions), WherePostProcessingEnabled(movingPositions)); + names = ConcatCollectionInName(stablePositions, movingPositions); } - lastOnTileValidationInfos = new OnTileValidationInfos(Styles.formatterOnTileValidationMultipleRenderer, names, namesWithPostProcess); + lastTileOnlyModeInfos = new TileOnlyModeInfos( + isSingleRendererCase: false, + rendererNames: names + ); } } - static void DisplayOnTileValidationWarning(SerializedProperty prop, Func shouldDisplayWarning, GUIContent label = null) + static void DisplayTileOnlyHelpBox(SerializedProperty prop, Func shouldDisplay, GUIContent label, MessageType messageType = MessageType.Warning, string customMessage = null) { - if (prop == null - || shouldDisplayWarning == null - || !lastOnTileValidationInfos.enabled - || !shouldDisplayWarning(prop)) + if (prop == null + || shouldDisplay == null + || !lastTileOnlyModeInfos.enabled + || !shouldDisplay(prop)) return; - EditorGUILayout.HelpBox( - string.Format(lastOnTileValidationInfos.formatter, label == null ? prop.displayName : label.text, lastOnTileValidationInfos.rendererNames), - MessageType.Warning); - } - - //variant for a whole section such as post processing - static void DisplayOnTileValidationWarningForPostProcessingSection(GUIContent label) - { - if (label == null || !lastOnTileValidationInfos.enabled || string.IsNullOrEmpty(lastOnTileValidationInfos.rendererNamesWithPostProcess)) - return; - - EditorGUILayout.HelpBox( - string.Format(lastOnTileValidationInfos.formatter, label.text, lastOnTileValidationInfos.rendererNamesWithPostProcess), - MessageType.Warning); + var fmt = !string.IsNullOrEmpty(customMessage) ? customMessage : Styles.formatterTileOnlyMode; + var labelText = label == null ? prop.displayName : label.text; + string message = string.Format(fmt, labelText, lastTileOnlyModeInfos.rendererNames); + + EditorGUILayout.HelpBox(message, messageType); } } } diff --git a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs index fbb1672aac1..72d028e36e1 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRenderPipelineAsset/UniversalRenderPipelineAssetUI.Skin.cs @@ -145,16 +145,16 @@ internal static class Styles EditorGUIUtility.TrTextContent("\"BatchRendererGroup Variants\" setting must be \"Keep All\". To fix, modify Graphics settings and set \"BatchRendererGroup Variants\" to \"Keep All\"."); public static GUIContent staticBatchingInfoMessage = EditorGUIUtility.TrTextContent("Static Batching is not recommended when using GPU draw submission modes, performance may improve if Static Batching is disabled in Player Settings."); - public static GUIContent lightModeErrorMessage = - EditorGUIUtility.TrTextContent("Rendering Path must be set to Forward+ or Deferred+ for correct lighting and reflections. One or more entries in the RendererList are not set to this mode."); + public static readonly string lightModeErrorFormatter = L10n.Tr("Rendering Path must be set to Forward+ or Deferred+ for correct lighting and reflections. Renderers to change: {0}."); public static GUIContent renderGraphNotEnabledErrorMessage = EditorGUIUtility.TrTextContent("Render Graph must be enabled to use occlusion culling."); public static GUIContent stencilLodCrossFadeWarningMessage = EditorGUIUtility.TrTextContent("LOD Cross Fade with stencil dithering is not compatible with stencil override in Renderer."); - public static readonly string formatterOnTileValidationOneRenderer = L10n.Tr("'{0}' will be skipped because it is incompatible with the enabled 'On-Tile Validation' on the Renderer: {1}."); - public static readonly string formatterOnTileValidationMultipleRenderer = L10n.Tr("'{0}' will be skipped whenever an active renderer uses 'On-Tile Validation' setting, such as: {1}."); - public static readonly string suffixWhenDifferentPositionOnTileValidation = L10n.Tr(" (different position)"); + public static readonly string formatterTileOnlyMode = L10n.Tr("'{0}' will be skipped because it is incompatible with the enabled 'Tile-Only Mode'. Affected renderers: {1}."); + public static readonly string tileOnlyModeMaybeMessage = L10n.Tr("'{0}' might be skipped when 'Tile-Only Mode' is enabled. Renderer Features can provide this functionality, so behavior can vary. Affected renderers: {1}."); + public static readonly string msaaTileOnlyInfo = L10n.Tr("'{0}' is supported in 'Tile-Only Mode'. However, in the Editor and on platforms where the back buffer does not support MSAA, URP forces MSAA to None to keep data in Tile Memory. Affected renderers: {1}."); + public static readonly string suffixWhenDifferentPositionTileOnlyMode = L10n.Tr(" (different position)"); // Dropdown menu options public static string[] mainLightOptions = { "Disabled", "Per Pixel" }; diff --git a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRendererDataEditor.cs b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRendererDataEditor.cs index 9ddadfb8cc7..a332b8e4567 100644 --- a/Packages/com.unity.render-pipelines.universal/Editor/UniversalRendererDataEditor.cs +++ b/Packages/com.unity.render-pipelines.universal/Editor/UniversalRendererDataEditor.cs @@ -14,7 +14,6 @@ public class UniversalRendererDataEditor : ScriptableRendererDataEditor { private static class Styles { - public static readonly GUIContent RendererTitle = EditorGUIUtility.TrTextContent("Universal Renderer", "Custom Universal Renderer for Universal RP."); public static readonly GUIContent PostProcessIncluded = EditorGUIUtility.TrTextContent("Enabled", "Enables the use of post processing effects within the scene. If disabled, Unity excludes post processing renderer Passes, shaders and textures from the build."); public static readonly GUIContent PostProcessLabel = EditorGUIUtility.TrTextContent("Data", "The asset containing references to shaders and Textures that the Renderer uses for post-processing."); public static readonly GUIContent FilteringSectionLabel = EditorGUIUtility.TrTextContent("Filtering", "Settings that controls and define which layers the renderer draws."); @@ -30,9 +29,6 @@ private static class Styles public static readonly GUIContent CopyDepthModeLabel = EditorGUIUtility.TrTextContent("Depth Texture Mode", "Controls after which pass URP copies the scene depth. It has a significant impact on mobile devices bandwidth usage. It also allows to force a depth prepass to generate it."); public static readonly GUIContent DepthAttachmentFormat = EditorGUIUtility.TrTextContent("Depth Attachment Format", "Which format to use (if it is supported) when creating _CameraDepthAttachment."); public static readonly GUIContent DepthTextureFormat = EditorGUIUtility.TrTextContent("Depth Texture Format", "Which format to use (if it is supported) when creating _CameraDepthTexture."); - public static readonly GUIContent RenderPassLabel = EditorGUIUtility.TrTextContent("Native RenderPass", "Enables URP to use RenderPass API."); - - public static readonly GUIContent RenderPassSectionLabel = EditorGUIUtility.TrTextContent("RenderPass", "This section contains properties related to render passes."); public static readonly GUIContent ShadowsSectionLabel = EditorGUIUtility.TrTextContent("Shadows", "This section contains properties related to rendering shadows."); public static readonly GUIContent PostProcessingSectionLabel = EditorGUIUtility.TrTextContent("Post-processing", "This section contains properties related to rendering post-processing."); @@ -44,12 +40,11 @@ private static class Styles public static readonly GUIContent invalidStencilOverride = EditorGUIUtility.TrTextContent("Error: When using the deferred rendering path, the Renderer requires the control over the 4 highest bits of the stencil buffer to store Material types. The current combination of the stencil override options prevents the Renderer from controlling the required bits. Try changing one of the options to Replace."); public static readonly GUIContent intermediateTextureMode = EditorGUIUtility.TrTextContent("Intermediate Texture (Obsolete)", "Should be set to Auto. Controls when URP renders via an intermediate texture."); public static readonly GUIContent warningIntermediateTextureMode = EditorGUIUtility.TrTextContent("'Always' is Obsolete. Change it to Auto. This can improve performance. The setting will disappear once it is corrected to 'Auto'."); - public static readonly GUIContent deferredPlusIncompatibleWarning = EditorGUIUtility.TrTextContent("Deferred+ is only available with Render Graph. In compatibility mode, Deferred+ falls back to Forward+."); - public static readonly GUIContent onTileValidation = EditorGUIUtility.TrTextContent("On-Tile Validation", "Enables the feature validation to prevent going off tile. This is mainly useful for tile based architectures."); - public static readonly string onTileValidationWarning = L10n.Tr("On-Tile validation is enabled. All ScriptableRendererFeatures and other features requiring a full-screen pass will be skipped to preserve the On-Tile optimization."); - public static readonly string deferredOnTileValidationWarning = L10n.Tr("Deferred rendering path is incompatible with the enabled 'On-Tile Validation' and will fallback to Forward."); - public static readonly string deferredPlusOnTileValidationWarning = L10n.Tr("Deferred+ rendering path is incompatible with the enabled 'On-Tile Validation' and will fallback to Forward+."); - public static readonly string postProcessingOnTileValidationWarning = L10n.Tr("'Post-processing' will be skipped because it is incompatible with the enabled 'On-Tile Validation'."); + public static readonly GUIContent tileOnlyMode = EditorGUIUtility.TrTextContent("Tile-Only Mode", "Restricts render passes to avoid memory load/store of main camera targets, keeping them in on‑chip tile memory. This is a potential GPU performance optimization on Tile-Based GPU architectures. It activates additional RenderGaph validation. Some features may be disabled or fall back. See docs for details."); + public static readonly string tileOnlyModeWarning = L10n.Tr("Tile-Only mode will disable or block features, including Renderer Features and Render Passes, that would trigger GPU memory store/load actions."); + public static readonly string deferredTileOnlyModeWarning = L10n.Tr("Deferred rendering path is incompatible with the enabled 'Tile-Only Mode'. Change this to Forward."); + public static readonly string deferredPlusTileOnlyModeWarning = L10n.Tr("Deferred+ rendering path is incompatible with the enabled 'Tile-Only Mode'. Change this to Forward+."); + public static readonly string postProcessingTileOnlyModeWarning = L10n.Tr("'Post-processing' is incompatible with the enabled 'Tile-Only Mode'. Disable this setting. Renderer Features can add On-Tile Post Processing."); } SerializedProperty m_PrepassLayerMask; @@ -66,7 +61,7 @@ private static class Styles SerializedProperty m_Shaders; SerializedProperty m_ShadowTransparentReceiveProp; SerializedProperty m_IntermediateTextureMode; - SerializedProperty m_OnTileValidation; + SerializedProperty m_TileOnlyMode; List m_DepthFormatStrings = new List(); @@ -86,7 +81,7 @@ private void OnEnable() m_Shaders = serializedObject.FindProperty("shaders"); m_ShadowTransparentReceiveProp = serializedObject.FindProperty("m_ShadowTransparentReceive"); m_IntermediateTextureMode = serializedObject.FindProperty("m_IntermediateTextureMode"); - m_OnTileValidation = serializedObject.FindProperty("m_OnTileValidation"); + m_TileOnlyMode = serializedObject.FindProperty("m_TileOnlyMode"); } private void PopulateCompatibleDepthFormats(int renderingMode) @@ -189,15 +184,15 @@ public override void OnInspectorGUI() depthFormatIndex = GetDepthFormatIndex((DepthFormat)m_DepthAttachmentFormat.intValue, m_RenderingMode.intValue); } - if (m_OnTileValidation.boolValue) + if (m_TileOnlyMode.boolValue) { switch ((RenderingMode)m_RenderingMode.intValue) { case RenderingMode.Deferred: - EditorGUILayout.HelpBox(Styles.deferredOnTileValidationWarning, MessageType.Warning); + EditorGUILayout.HelpBox(Styles.deferredTileOnlyModeWarning, MessageType.Error); break; case RenderingMode.DeferredPlus: - EditorGUILayout.HelpBox(Styles.deferredPlusOnTileValidationWarning, MessageType.Warning); + EditorGUILayout.HelpBox(Styles.deferredPlusTileOnlyModeWarning, MessageType.Error); break; } } @@ -236,9 +231,9 @@ public override void OnInspectorGUI() EditorGUILayout.PropertyField(m_DepthTextureFormat, Styles.DepthTextureFormat); - EditorGUILayout.PropertyField(m_OnTileValidation, Styles.onTileValidation); - if (m_OnTileValidation.boolValue) - EditorGUILayout.HelpBox(Styles.onTileValidationWarning, MessageType.Warning); + EditorGUILayout.PropertyField(m_TileOnlyMode, Styles.tileOnlyMode); + if (m_TileOnlyMode.boolValue) + EditorGUILayout.HelpBox(Styles.tileOnlyModeWarning, MessageType.Info); EditorGUI.indentLevel--; EditorGUILayout.Space(); @@ -256,8 +251,8 @@ public override void OnInspectorGUI() { m_PostProcessData.objectReferenceValue = postProcessIncluded ? PostProcessData.GetDefaultPostProcessData() : null; } - if (postProcessIncluded && m_OnTileValidation.boolValue) - EditorGUILayout.HelpBox(Styles.postProcessingOnTileValidationWarning, MessageType.Warning); + if (postProcessIncluded && m_TileOnlyMode.boolValue) + EditorGUILayout.HelpBox(Styles.postProcessingTileOnlyModeWarning, MessageType.Error); EditorGUI.indentLevel++; EditorGUILayout.PropertyField(m_PostProcessData, Styles.PostProcessLabel); EditorGUI.indentLevel--; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs index 7046e32494b..f5261a6876d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Rendergraph/Renderer2DRendergraph.cs @@ -251,8 +251,7 @@ ImportResourceSummary GetImportResourceSummary(RenderGraph renderGraph, Universa bool isBuiltInTexture = cameraData.targetTexture == null; - bool useActualBackbufferOrienation = !cameraData.isSceneViewCamera && !cameraData.isPreviewCamera && cameraData.targetTexture == null; - TextureUVOrigin backbufferTextureUVOrigin = useActualBackbufferOrienation ? (SystemInfo.graphicsUVStartsAtTop ? TextureUVOrigin.TopLeft : TextureUVOrigin.BottomLeft) : TextureUVOrigin.BottomLeft; + TextureUVOrigin backbufferTextureUVOrigin = RenderingUtils.GetBackBufferUVOrientation(cameraData); output.backBufferColorParams.textureUVOrigin = backbufferTextureUVOrigin; output.backBufferDepthParams.textureUVOrigin = backbufferTextureUVOrigin; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider.cs index 0b7cc71583c..118956746d7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; -using UnityEngine.Scripting.APIUpdating; #if UNITY_EDITOR using UnityEditor; @@ -10,16 +9,11 @@ namespace UnityEngine.Rendering.Universal { - - [System.Obsolete("Use ShadowCaster2DProvider instead.")] - public abstract class ShadowShape2DProvider : ShadowCaster2DProvider { } - - /// - /// Class ShadowShape2DProvider has methods called by a ShadowCaster2D to determine if it should be listed as a Casting Option, and to provide geometry if it is the active ShadowShape2DProvider - /// + /// + /// Class ShadowShape2DProvider has methods called by a ShadowCaster2D to determine if it should be listed as a Casting Option, and to provide geometry if it is the active ShadowShape2DProvider + /// [Serializable] - [MovedFrom(true, "UnityEngine.Rendering.Universal", "Unity.RenderPipelines.Universal.2D.Runtime", "ShadowShape2DProvider")] - public abstract class ShadowCaster2DProvider : Provider2D + public abstract class ShadowShape2DProvider : Provider2D { /// /// Gets the name to be listed in the ShadowCaster2D Casting Option drop down. diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_Collider.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_Collider.cs index 31616b94ac5..bf9cc8ed69d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_Collider.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_Collider.cs @@ -3,13 +3,11 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using Unity.Collections; -using UnityEngine.Scripting.APIUpdating; namespace UnityEngine.Rendering.Universal { [Serializable] - [MovedFrom(true, "UnityEngine.Rendering.Universal", "Unity.RenderPipelines.Universal.2D.Runtime", "ShadowShape2DProvider_Collider2D")] - class ShadowCaster2DProvider_Collider2D : ShadowCaster2DProvider + class ShadowShape2DProvider_Collider2D : ShadowShape2DProvider { const float k_InitialTrim = 0.05f; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteRenderer.cs index 5ad118ea0e3..6b8f56bf7d7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteRenderer.cs @@ -4,15 +4,13 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using UnityEngine; -using UnityEngine.Scripting.APIUpdating; using UnityEngine.U2D; namespace UnityEngine.Rendering.Universal { [Serializable] - [MovedFrom(true, "UnityEngine.Rendering.Universal", "Unity.RenderPipelines.Universal.2D.Runtime", "ShadowShape2DProvider_SpriteRenderer")] - class ShadowCaster2DProvider_SpriteRenderer : ShadowCaster2DProvider + class ShadowShape2DProvider_SpriteRenderer : ShadowShape2DProvider { const float k_InitialTrim = 0.05f; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteShape.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteShape.cs index 4ef2b34105c..f1823a44a0d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteShape.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteShape.cs @@ -7,8 +7,6 @@ using Unity.Collections.LowLevel.Unsafe; using UnityEngine.U2D; using Unity.Mathematics; -using UnityEngine.Scripting.APIUpdating; - #if UNITY_EDITOR using UnityEditor; @@ -17,8 +15,7 @@ namespace UnityEngine.Rendering.Universal { [Serializable] - [MovedFrom(true, "UnityEngine.Rendering.Universal", "Unity.RenderPipelines.Universal", "ShadowShape2DProvider_SpriteShape")] - internal class ShadowCaster2DProvider_SpriteShape : ShadowCaster2DProvider + internal class ShadowShape2DProvider_SpriteShape : ShadowShape2DProvider { const float k_InitialTrim = 0.02f; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteSkin.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteSkin.cs index 445c1f821ad..835028d15c9 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteSkin.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Providers/ShadowShape2DProvider_SpriteSkin.cs @@ -5,15 +5,13 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using UnityEngine; -using UnityEngine.Scripting.APIUpdating; using UnityEngine.U2D; using UnityEngine.U2D.Animation; namespace UnityEngine.Rendering.Universal { [Serializable] - [MovedFrom(true, "UnityEngine.Rendering.Universal", "Unity.RenderPipelines.Universal.2D.Runtime", "ShadowShape2DProvider_SpriteSkin")] - class ShadowCaster2DProvider_SpriteSkin : ShadowCaster2DProvider + class ShadowShape2DProvider_SpriteSkin : ShadowShape2DProvider { const float k_InitialTrim = 0.05f; diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShapeProviderUtility.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShapeProviderUtility.cs index 98eb1d5b87f..d580c2c4c65 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShapeProviderUtility.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/Shadow Provider Utility/ShapeProviderUtility.cs @@ -11,7 +11,7 @@ namespace UnityEngine.Rendering.Universal { internal class ShapeProviderUtility { - static public void CallOnBeforeRender(ShadowCaster2DProvider shapeProvider, Component component, ShadowMesh2D shadowMesh, Bounds bounds) + static public void CallOnBeforeRender(ShadowShape2DProvider shapeProvider, Component component, ShadowMesh2D shadowMesh, Bounds bounds) { if (component != null) { @@ -24,7 +24,7 @@ static public void CallOnBeforeRender(ShadowCaster2DProvider shapeProvider, Comp } } - static public void PersistantDataCreated(ShadowCaster2DProvider shapeProvider, Component component, ShadowMesh2D shadowMesh) + static public void PersistantDataCreated(ShadowShape2DProvider shapeProvider, Component component, ShadowMesh2D shadowMesh) { if (component != null) { @@ -34,20 +34,20 @@ static public void PersistantDataCreated(ShadowCaster2DProvider shapeProvider, C } #if UNITY_EDITOR - static public void TryGetDefaultShadowShapeProviderSource(GameObject go, out Component outSource, out ShadowCaster2DProvider outProvider) + static public void TryGetDefaultShadowShapeProviderSource(GameObject go, out Component outSource, out ShadowShape2DProvider outProvider) { outSource = null; outProvider = null; // Create some providers to check against. - var providerTypes = TypeCache.GetTypesDerivedFrom(); - var providers = new List(providerTypes.Count); + var providerTypes = TypeCache.GetTypesDerivedFrom(); + var providers = new List(providerTypes.Count); foreach (Type providerType in providerTypes) { if (providerType.IsAbstract) continue; - providers.Add(Activator.CreateInstance(providerType) as ShadowCaster2DProvider); + providers.Add(Activator.CreateInstance(providerType) as ShadowShape2DProvider); } // Fetch the components to check. diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs index 4e74a9d288b..528691b6a14 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Shadows/ShadowCaster2D.cs @@ -92,7 +92,7 @@ internal enum EdgeProcessing [SerializeField] int m_InstanceId; [SerializeField] Component m_ShadowShape2DComponent; - [SerializeReference] ShadowCaster2DProvider m_ShadowShape2DProvider; + [SerializeReference] ShadowShape2DProvider m_ShadowShape2DProvider; [SerializeField] ShadowCastingSources m_ShadowCastingSource = (ShadowCastingSources)(-1); [SerializeReference] internal ShadowMesh2D m_ShadowMesh; @@ -158,7 +158,7 @@ public float alphaCutoff // Make this public if possible... internal Component shadowShape2DComponent { get { return m_ShadowShape2DComponent; } set { m_ShadowShape2DComponent = value; } } - internal ShadowCaster2DProvider shadowShape2DProvider { get { return m_ShadowShape2DProvider; } set { m_ShadowShape2DProvider = value; } } + internal ShadowShape2DProvider shadowShape2DProvider { get { return m_ShadowShape2DProvider; } set { m_ShadowShape2DProvider = value; } } int m_PreviousShadowGroup = 0; bool m_PreviousCastsShadows = true; @@ -279,9 +279,9 @@ internal bool IsLit(Light2D light) { // Oddly adding and subtracting vectors is expensive here because of the new structures created... Vector3 deltaPos; - deltaPos.x = light.m_CachedPosition.x - boundingSphere.position.x; - deltaPos.y = light.m_CachedPosition.y - boundingSphere.position.y; - deltaPos.z = light.m_CachedPosition.z - boundingSphere.position.z; + deltaPos.x = light.boundingSphere.position.x - boundingSphere.position.x; + deltaPos.y = light.boundingSphere.position.y - boundingSphere.position.y; + deltaPos.z = light.boundingSphere.position.z - boundingSphere.position.z; float distanceSq = Vector3.SqrMagnitude(deltaPos); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Sources/Shadow2DProviderSources.cs b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Sources/Shadow2DProviderSources.cs index 61d40e787e8..fd06e55362c 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/2D/Sources/Shadow2DProviderSources.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/2D/Sources/Shadow2DProviderSources.cs @@ -4,7 +4,7 @@ namespace UnityEngine.Rendering.Universal { [Serializable] - internal class Shadow2DProviderSources : Provider2DSources + internal class Shadow2DProviderSources : Provider2DSources { void SetSelectedHashCode(Provider2D provider, Component component) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/AssemblyInfo.cs b/Packages/com.unity.render-pipelines.universal/Runtime/AssemblyInfo.cs index 45b528a0ea8..696ca4679f7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/AssemblyInfo.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/AssemblyInfo.cs @@ -10,3 +10,4 @@ [assembly: InternalsVisibleTo("Unity.GraphicTests.Performance.Universal.Runtime")] [assembly: InternalsVisibleTo("Unity.RenderPipelines.Multiple_SRP.RuntimeTests")] [assembly: InternalsVisibleTo("Unity.RenderPipelines.Multiple_SRP.EditorTests")] +[assembly: InternalsVisibleTo("UniversalEditorTests")] diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs index 814e25d750b..3554670c15e 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Data/UniversalRenderPipelineAssetPrefiltering.cs @@ -104,6 +104,16 @@ internal enum PrefilteringModeAdditionalLights [ShaderKeywordFilter.SelectIf(PrefilteringMode.SelectOnly, keywordNames: ShaderKeywordStrings.ScreenSpaceOcclusion)] [SerializeField] private PrefilteringMode m_PrefilteringModeScreenSpaceOcclusion = PrefilteringMode.Select; + // Screen Space Reflection + [ShaderKeywordFilter.RemoveIf(PrefilteringMode.Remove, keywordNames: ShaderKeywordStrings.ScreenSpaceReflection)] + [ShaderKeywordFilter.SelectIf(PrefilteringMode.Select, keywordNames: new [] {"", ShaderKeywordStrings.ScreenSpaceReflection})] + [ShaderKeywordFilter.SelectIf(PrefilteringMode.SelectOnly, keywordNames: ShaderKeywordStrings.ScreenSpaceReflection)] + [SerializeField] private PrefilteringMode m_PrefilteringModeScreenSpaceReflection = PrefilteringMode.Select; + + // Keyword used by the DepthNormalOnly pass to write smoothness into alpha channel for screen space reflections. + [ShaderKeywordFilter.RemoveIf(true, keywordNames: ShaderKeywordStrings.WriteSmoothness)] + [SerializeField] private bool m_PrefilterWriteSmoothness = true; + // Rendering Debugger [ShaderKeywordFilter.RemoveIf(true, keywordNames:ShaderKeywordStrings.DEBUG_DISPLAY)] [SerializeField] private bool m_PrefilterDebugKeywords = false; @@ -221,6 +231,7 @@ internal struct ShaderPrefilteringData public PrefilteringModeAdditionalLights additionalLightsPrefilteringMode; public PrefilteringMode additionalLightsShadowsPrefilteringMode; public PrefilteringMode screenSpaceOcclusionPrefilteringMode; + public PrefilteringMode screenSpaceReflectionPrefilteringMode; public bool useLegacyLightmaps; public bool stripXRKeywords; @@ -255,6 +266,9 @@ internal struct ShaderPrefilteringData public bool stripScreenSpaceIrradiance; + // Keyword used by the DepthNormalOnly pass to write smoothness into alpha channel for screen space reflections. + public bool stripWriteSmoothness; + public static ShaderPrefilteringData GetDefault() { return new ShaderPrefilteringData() @@ -265,6 +279,7 @@ public static ShaderPrefilteringData GetDefault() additionalLightsPrefilteringMode = PrefilteringModeAdditionalLights.SelectAll, additionalLightsShadowsPrefilteringMode = PrefilteringMode.Select, screenSpaceOcclusionPrefilteringMode = PrefilteringMode.Select, + screenSpaceReflectionPrefilteringMode = PrefilteringMode.Select, }; } } @@ -281,6 +296,7 @@ internal void UpdateShaderKeywordPrefiltering(ref ShaderPrefilteringData prefilt m_PrefilteringModeAdditionalLight = prefilteringData.additionalLightsPrefilteringMode; m_PrefilteringModeAdditionalLightShadows = prefilteringData.additionalLightsShadowsPrefilteringMode; m_PrefilteringModeScreenSpaceOcclusion = prefilteringData.screenSpaceOcclusionPrefilteringMode; + m_PrefilteringModeScreenSpaceReflection = prefilteringData.screenSpaceReflectionPrefilteringMode; m_PrefilterUseLegacyLightmaps = prefilteringData.useLegacyLightmaps; m_PrefilterXRKeywords = prefilteringData.stripXRKeywords; @@ -316,6 +332,8 @@ internal void UpdateShaderKeywordPrefiltering(ref ShaderPrefilteringData prefilt m_PrefilterReflectionProbeAtlas = prefilteringData.stripReflectionProbeAtlas; m_PrefilterScreenSpaceIrradiance = prefilteringData.stripScreenSpaceIrradiance; + + m_PrefilterWriteSmoothness = prefilteringData.stripWriteSmoothness; } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugDisplaySettingsLighting.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugDisplaySettingsLighting.cs index 91bb3e6d221..be8978e047b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugDisplaySettingsLighting.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugDisplaySettingsLighting.cs @@ -9,7 +9,6 @@ namespace UnityEngine.Rendering.Universal /// /// Lighting-related Rendering Debugger settings. /// - [URPHelpURL("features/rendering-debugger-reference", "lighting")] [Serializable] public class DebugDisplaySettingsLighting : IDebugDisplaySettingsData, ISerializedDebugDisplaySettings { @@ -67,6 +66,7 @@ internal static class WidgetFactory } [DisplayInfo(name = "Lighting", order = 3)] + [URPHelpURL("features/rendering-debugger-reference", "lighting")] internal class SettingsPanel : DebugDisplaySettingsPanel { public SettingsPanel(DebugDisplaySettingsLighting data) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugHandler.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugHandler.cs index f1da7614340..5403e6287c3 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugHandler.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Debug/DebugHandler.cs @@ -136,7 +136,7 @@ public bool TryGetScreenClearColor(ref Color color) internal bool HDRDebugViewIsActive(bool resolveFinalTarget) { // HDR debug views should only apply to the last camera in the stack - return DebugDisplaySettings.lightingSettings.hdrDebugMode != HDRDebugMode.None && resolveFinalTarget; + return m_HDRDebugViewMaterial != null && DebugDisplaySettings.lightingSettings.hdrDebugMode != HDRDebugMode.None && resolveFinalTarget; } internal bool WriteToDebugScreenTexture(bool resolveFinalTarget) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalRenderingData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalRenderingData.cs index 62316da81c1..345c7a1844d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalRenderingData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/FrameData/UniversalRenderingData.cs @@ -52,6 +52,14 @@ public class UniversalRenderingData : ContextItem /// public bool stencilLodCrossFadeEnabled { get; internal set; } +#if URP_SCREEN_SPACE_REFLECTION + /// + /// True if per-pixel smoothness should be written to the alpha channel of the CameraDepthNormals texture, if it exists. + /// Used for screen space reflections. + /// + public bool writesSmoothnessToDepthNormalsAlpha { get; internal set; } +#endif + /// public override void Reset() { @@ -63,6 +71,9 @@ public override void Reset() prepassLayerMask = -1; opaqueLayerMask = -1; transparentLayerMask = -1; +#if URP_SCREEN_SPACE_REFLECTION + writesSmoothnessToDepthNormalsAlpha = false; +#endif } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/BeforeTransparentsColorHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/History/BeforeTransparentsColorHistory.cs new file mode 100644 index 00000000000..99937af59b4 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/BeforeTransparentsColorHistory.cs @@ -0,0 +1,20 @@ +namespace UnityEngine.Rendering.Universal +{ + /// + /// Color history before rendering transparent objects. Raw rendered geometry. No UI overlay. + /// Color space is linear RGB. + /// No mips. + /// MSAA is not supported and is resolved for the history. + /// XR is supported. + /// + internal sealed class BeforeTransparentsColorHistory : ColorHistory + { + /// + public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) + { + m_Names[0] = "BeforeTransparentsColorHistory0"; + m_Names[1] = "BeforeTransparentsColorHistory1"; + base.OnCreate(owner, typeId); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/BeforeTransparentsColorHistory.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/History/BeforeTransparentsColorHistory.cs.meta new file mode 100644 index 00000000000..dcd2a92a5b8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/BeforeTransparentsColorHistory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b1a6c4c4329a09f49a96f22a8922f69a \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/ColorHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/History/ColorHistory.cs new file mode 100644 index 00000000000..0bc07262e41 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/ColorHistory.cs @@ -0,0 +1,128 @@ +using System; +using UnityEngine.Experimental.Rendering; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// Base class for color history. + /// Color space is linear RGB. + /// No mips. + /// MSAA is not supported and is resolved for the history. + /// XR is supported. + /// + public abstract class ColorHistory : CameraHistoryItem + { + private int[] m_Ids = new int[2]; + /// + /// The names to use for history items. + /// + protected string[] m_Names = new[] + { + "ColorHistory0", + "ColorHistory1" + }; + private RenderTextureDescriptor m_Descriptor; + private Hash128 m_DescKey; + + /// + public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) + { + base.OnCreate(owner, typeId); + m_Ids[0] = MakeId(0); + m_Ids[1] = MakeId(1); + } + + /// + /// Get the current history texture. + /// Current history might not be valid yet. It is valid only after executing the producing render pass. + /// + /// Eye index, typically XRPass.multipassId. + /// The texture. + public RTHandle GetCurrentTexture(int eyeIndex = 0) + { + if ((uint)eyeIndex >= m_Ids.Length) + return null; + + return GetCurrentFrameRT(m_Ids[eyeIndex]); + } + + /// + /// Get the previous history texture. + /// Previous history might not be valid yet. It is valid only after executing the producing render pass. + /// + /// Eye index, typically XRPass.multipassId. + /// The texture. + public RTHandle GetPreviousTexture(int eyeIndex = 0) + { + if ((uint)eyeIndex >= m_Ids.Length) + return null; + + return GetPreviousFrameRT(m_Ids[eyeIndex]); + } + + private bool IsAllocated() + { + return GetCurrentTexture() != null; + } + + // True if the desc changed, graphicsFormat etc. + private bool IsDirty(ref RenderTextureDescriptor desc) + { + return m_DescKey != Hash128.Compute(ref desc); + } + + private void Alloc(ref RenderTextureDescriptor desc, bool xrMultipassEnabled) + { + // In generic case, the current texture might not have been written yet. We need double buffering. + AllocHistoryFrameRT(m_Ids[0], 2, ref desc, m_Names[0]); + + if(xrMultipassEnabled) + AllocHistoryFrameRT(m_Ids[1], 2, ref desc, m_Names[1]); + + m_Descriptor = desc; + m_DescKey = Hash128.Compute(ref desc); + } + + /// + /// Release the history texture(s). + /// + public override void Reset() + { + for(int i = 0; i < m_Ids.Length; i++) + ReleaseHistoryFrameRT(m_Ids[i]); + } + + internal RenderTextureDescriptor GetHistoryDescriptor(ref RenderTextureDescriptor cameraDesc) + { + var colorDesc = cameraDesc; + colorDesc.depthStencilFormat = GraphicsFormat.None; + colorDesc.mipCount = 0; + colorDesc.msaaSamples = 1; + + return colorDesc; + } + + // Return true if the RTHandles were reallocated. + internal bool Update(UniversalCameraData cameraData, ref RenderTextureDescriptor cameraDesc, bool xrMultipassEnabled = false) + { + if (cameraDesc.width > 0 && cameraDesc.height > 0 && cameraDesc.graphicsFormat != GraphicsFormat.None) + { + var historyDesc = GetHistoryDescriptor(ref cameraDesc); + + Camera camera = cameraData.camera; + bool isPreview = camera.cameraType == CameraType.Preview; + bool isRenderRequest = camera.isProcessingRenderRequest; + if (!isPreview && !isRenderRequest && IsDirty(ref historyDesc)) + Reset(); + + if (!IsAllocated()) + { + Alloc(ref historyDesc, xrMultipassEnabled); + return true; + } + } + + return false; + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/ColorHistory.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/History/ColorHistory.cs.meta new file mode 100644 index 00000000000..dd0960cb009 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/ColorHistory.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b0ecc0d40b758794593fe6ee53c2b117 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/History/RawColorHistory.cs b/Packages/com.unity.render-pipelines.universal/Runtime/History/RawColorHistory.cs index d74ae87a1e7..acc0692fbf8 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/History/RawColorHistory.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/History/RawColorHistory.cs @@ -11,113 +11,14 @@ namespace UnityEngine.Rendering.Universal /// MSAA is not supported and is resolved for the history. /// XR is supported. /// - public sealed class RawColorHistory : CameraHistoryItem + public sealed class RawColorHistory : ColorHistory { - private int[] m_Ids = new int[2]; - private static readonly string[] m_Names = new[] - { - "RawColorHistory0", - "RawColorHistory1" - }; - private RenderTextureDescriptor m_Descriptor; - private Hash128 m_DescKey; - /// public override void OnCreate(BufferedRTHandleSystem owner, uint typeId) { + m_Names[0] = "RawColorHistory0"; + m_Names[1] = "RawColorHistory1"; base.OnCreate(owner, typeId); - m_Ids[0] = MakeId(0); - m_Ids[1] = MakeId(1); - } - - /// - /// Get the current history texture. - /// Current history might not be valid yet. It is valid only after executing the producing render pass. - /// - /// Eye index, typically XRPass.multipassId. - /// The texture. - public RTHandle GetCurrentTexture(int eyeIndex = 0) - { - if ((uint)eyeIndex >= m_Ids.Length) - return null; - - return GetCurrentFrameRT(m_Ids[eyeIndex]); - } - - /// - /// Get the previous history texture. - /// Previous history might not be valid yet. It is valid only after executing the producing render pass. - /// - /// Eye index, typically XRPass.multipassId. - /// The texture. - public RTHandle GetPreviousTexture(int eyeIndex = 0) - { - if ((uint)eyeIndex >= m_Ids.Length) - return null; - - return GetPreviousFrameRT(m_Ids[eyeIndex]); - } - - private bool IsAllocated() - { - return GetCurrentTexture() != null; - } - - // True if the desc changed, graphicsFormat etc. - private bool IsDirty(ref RenderTextureDescriptor desc) - { - return m_DescKey != Hash128.Compute(ref desc); - } - - private void Alloc(ref RenderTextureDescriptor desc, bool xrMultipassEnabled) - { - // In generic case, the current texture might not have been written yet. We need double buffering. - AllocHistoryFrameRT(m_Ids[0], 2, ref desc, m_Names[0]); - - if(xrMultipassEnabled) - AllocHistoryFrameRT(m_Ids[1], 2, ref desc, m_Names[1]); - - m_Descriptor = desc; - m_DescKey = Hash128.Compute(ref desc); - } - - /// - /// Release the history texture(s). - /// - public override void Reset() - { - for(int i = 0; i < m_Ids.Length; i++) - ReleaseHistoryFrameRT(m_Ids[i]); - } - - internal RenderTextureDescriptor GetHistoryDescriptor(ref RenderTextureDescriptor cameraDesc) - { - var colorDesc = cameraDesc; - colorDesc.depthStencilFormat = GraphicsFormat.None; - colorDesc.mipCount = 0; - colorDesc.msaaSamples = 1; - - return colorDesc; - } - - // Return true if the RTHandles were reallocated. - internal bool Update(ref RenderTextureDescriptor cameraDesc, bool xrMultipassEnabled = false) - { - if (cameraDesc.width > 0 && cameraDesc.height > 0 && cameraDesc.graphicsFormat != GraphicsFormat.None) - { - var historyDesc = GetHistoryDescriptor(ref cameraDesc); - - if (IsDirty(ref historyDesc)) - Reset(); - - if (!IsAllocated()) - { - Alloc(ref historyDesc, xrMultipassEnabled); - return true; - } - } - - return false; } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen.meta new file mode 100644 index 00000000000..702238e83f8 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cd6ee03b8cfece34586c63ce0d561baf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenRenderPipelineRuntimeResources.cs b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenRenderPipelineRuntimeResources.cs new file mode 100644 index 00000000000..565805de8a9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenRenderPipelineRuntimeResources.cs @@ -0,0 +1,46 @@ +using System; + +namespace UnityEngine.Rendering +{ + /// + /// Common global resources for mip pyramid generator (color, depth). + /// + [Serializable] + [SupportedOnRenderPipeline] + [Categorization.CategoryInfo(Name = "R: Mip Generator Resources", Order = 1000), HideInInspector] + internal sealed class MipGenRenderPipelineRuntimeResources : IRenderPipelineResources + { + /// + /// Version of the SSR Resources + /// + public int version => 0; + + bool IRenderPipelineGraphicsSettings.isAvailableInPlayerBuild => true; + + [SerializeField, ResourcePath("Runtime/MipGen/Shaders/ColorPyramidPS.shader")] + private Shader m_ColorPyramidPS; + + public Shader colorPyramidPS + { + get => m_ColorPyramidPS; + set => this.SetValueAndNotify(ref m_ColorPyramidPS, value); + } + + [SerializeField, ResourcePath("Runtime/MipGen/Shaders/ColorPyramid.compute")] + public ComputeShader m_ColorPyramidCS; + public ComputeShader colorPyramidCS + { + get => m_ColorPyramidCS; + set => this.SetValueAndNotify(ref m_ColorPyramidCS, value); + } + + [SerializeField, ResourcePath("Runtime/MipGen/Shaders/DepthPyramid.compute")] + private ComputeShader m_DepthPyramidCS; + + public ComputeShader depthPyramidCS + { + get => m_DepthPyramidCS; + set => this.SetValueAndNotify(ref m_DepthPyramidCS, value); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenRenderPipelineRuntimeResources.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenRenderPipelineRuntimeResources.cs.meta new file mode 100644 index 00000000000..e1f2cd6e65f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenRenderPipelineRuntimeResources.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 26bfb1c84b583444c85ebb814cb4eaf9 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs new file mode 100644 index 00000000000..8f7fcd4f482 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs @@ -0,0 +1,509 @@ +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.RenderGraphModule.Util; +using UnityEngine.Rendering.Universal; + +namespace UnityEngine.Rendering +{ + internal struct PackedMipChainInfo + { + public Vector2Int textureSize; + public int mipLevelCount; // mips contain min (closest) depth + public int mipLevelCountCheckerboard; + public Vector2Int[] mipLevelSizes; + public Vector2Int[] mipLevelOffsets; // mips contain min (closest) depth + public Vector2Int[] mipLevelOffsetsCheckerboard; + + private Vector2 cachedTextureScale; + private Vector2Int cachedHardwareTextureSize; + private int cachedCheckerboardMipCount; + + public void Allocate() + { + mipLevelOffsets = new Vector2Int[15]; + mipLevelOffsetsCheckerboard = new Vector2Int[15]; + mipLevelSizes = new Vector2Int[15]; + } + + enum PackDirection + { + Right, + Down, + } + + static Vector2Int NextMipBegin(Vector2Int prevMipBegin, Vector2Int prevMipSize, PackDirection dir) + { + Vector2Int mipBegin = prevMipBegin; + if (dir == PackDirection.Right) + mipBegin.x += prevMipSize.x; + else + mipBegin.y += prevMipSize.y; + return mipBegin; + } + + // We pack all MIP levels into the top MIP level to avoid the Pow2 MIP chain restriction. + // We compute the required size iteratively. + // This function is NOT fast, but it is illustrative, and can be optimized later. + public void ComputePackedMipChainInfo(Vector2Int viewportSize, int checkerboardMipCount) + { + // only support up to 2 mips of checkerboard data being created + checkerboardMipCount = Mathf.Clamp(checkerboardMipCount, 0, 2); + + bool isHardwareDrsOn = DynamicResolutionHandler.instance.HardwareDynamicResIsEnabled(); + Vector2Int hardwareTextureSize = isHardwareDrsOn ? DynamicResolutionHandler.instance.ApplyScalesOnSize(viewportSize) : viewportSize; + Vector2 textureScale = isHardwareDrsOn ? new Vector2((float)viewportSize.x / (float)hardwareTextureSize.x, (float)viewportSize.y / (float)hardwareTextureSize.y) : new Vector2(1.0f, 1.0f); + + // No work needed. + if (cachedHardwareTextureSize == hardwareTextureSize && cachedTextureScale == textureScale && cachedCheckerboardMipCount == checkerboardMipCount) + return; + + cachedHardwareTextureSize = hardwareTextureSize; + cachedTextureScale = textureScale; + cachedCheckerboardMipCount = checkerboardMipCount; + + mipLevelSizes[0] = hardwareTextureSize; + mipLevelOffsets[0] = Vector2Int.zero; + mipLevelOffsetsCheckerboard[0] = mipLevelOffsets[0]; + + int mipLevel = 0; + Vector2Int mipSize = hardwareTextureSize; + bool hasCheckerboard = (checkerboardMipCount != 0); + do + { + mipLevel++; + + // Round up. + mipSize.x = Mathf.Max(1, (mipSize.x + 1) >> 1); + mipSize.y = Mathf.Max(1, (mipSize.y + 1) >> 1); + + mipLevelSizes[mipLevel] = mipSize; + + Vector2Int prevMipSize = mipLevelSizes[mipLevel - 1]; + Vector2Int prevMipBegin = mipLevelOffsets[mipLevel - 1]; + Vector2Int prevMipBeginCheckerboard = mipLevelOffsetsCheckerboard[mipLevel - 1]; + + Vector2Int mipBegin = prevMipBegin; + Vector2Int mipBeginCheckerboard = prevMipBeginCheckerboard; + if (mipLevel == 1) + { + // first mip always below full resolution + mipBegin = NextMipBegin(prevMipBegin, prevMipSize, PackDirection.Down); + + // pack checkerboard next to it if present + if (hasCheckerboard) + mipBeginCheckerboard = NextMipBegin(mipBegin, mipSize, PackDirection.Right); + else + mipBeginCheckerboard = mipBegin; + } + else + { + // alternate directions, mip 2 starts with down if checkerboard, right if not + bool isOdd = ((mipLevel & 1) != 0); + PackDirection dir = (isOdd ^ hasCheckerboard) ? PackDirection.Down : PackDirection.Right; + + mipBegin = NextMipBegin(prevMipBegin, prevMipSize, dir); + mipBeginCheckerboard = NextMipBegin(prevMipBeginCheckerboard, prevMipSize, dir); + } + + mipLevelOffsets[mipLevel] = mipBegin; + mipLevelOffsetsCheckerboard[mipLevel] = mipBeginCheckerboard; + + hardwareTextureSize.x = Mathf.Max(hardwareTextureSize.x, mipBegin.x + mipSize.x); + hardwareTextureSize.y = Mathf.Max(hardwareTextureSize.y, mipBegin.y + mipSize.y); + hardwareTextureSize.x = Mathf.Max(hardwareTextureSize.x, mipBeginCheckerboard.x + mipSize.x); + hardwareTextureSize.y = Mathf.Max(hardwareTextureSize.y, mipBeginCheckerboard.y + mipSize.y); + } + while ((mipSize.x > 1) || (mipSize.y > 1)); + + textureSize = new Vector2Int( + (int)Mathf.Ceil((float)hardwareTextureSize.x * textureScale.x), (int)Mathf.Ceil((float)hardwareTextureSize.y * textureScale.y)); + + mipLevelCount = mipLevel + 1; + mipLevelCountCheckerboard = hasCheckerboard ? (1 + checkerboardMipCount) : 0; + } + } + + internal class MipGenerator + { + ComputeShader m_ColorPyramidCS = null; + ComputeShader m_DepthPyramidCS = null; + Shader m_ColorPyramidPS; + Material m_ColorPyramidPSMat; + MaterialPropertyBlock m_PropertyBlockBlur; + + int m_DepthDownsampleKernel = -1; + int m_ColorDownsampleKernel = -1; + int m_ColorGaussianKernel = -1; + + bool m_PreferCompute; + bool m_SupportCompute; + + LocalKeyword m_DisableTexture2DArrayColorKeyword; + LocalKeyword m_DisableTexture2DArrayColorPSKeyword; + LocalKeyword m_DisableTexture2DArrayDepthKeyword; + LocalKeyword m_EnableCheckerboardKeyword; + + public static readonly int _DepthMipChain = Shader.PropertyToID("_DepthMipChain"); + public static readonly int _DepthPyramidConstants = Shader.PropertyToID("DepthPyramidConstants"); + + public static readonly int _Size = Shader.PropertyToID("_Size"); + public static readonly int _Source = Shader.PropertyToID("_Source"); + public static readonly int _Destination = Shader.PropertyToID("_Destination"); + + public static readonly int _SourceMip = Shader.PropertyToID("_SourceMip"); + public static readonly int _SrcScaleBias = Shader.PropertyToID("_SrcScaleBias"); + public static readonly int _SrcUvLimits = Shader.PropertyToID("_SrcUvLimits"); + + public static readonly string k_EnableCheckerboard = "ENABLE_CHECKERBOARD"; + + public MipGenerator(bool preferCompute = true) + { + if (!GraphicsSettings.TryGetRenderPipelineSettings(out var runtimeShaders)) + { + Debug.LogErrorFormat( + $"Couldn't find the required resources for the {nameof(MipGenerator)} ."); + } + + m_SupportCompute = SystemInfo.supportsComputeShaders + && runtimeShaders.colorPyramidCS.HasKernel("ColorDownsample") + && runtimeShaders.colorPyramidCS.HasKernel("ColorGaussian") + && runtimeShaders.depthPyramidCS.HasKernel("DepthDownsample"); + if (m_SupportCompute) + { + m_ColorPyramidCS = runtimeShaders.colorPyramidCS; + m_DepthPyramidCS = runtimeShaders.depthPyramidCS; + + m_ColorDownsampleKernel = m_ColorPyramidCS.FindKernel("ColorDownsample"); + m_ColorGaussianKernel = m_ColorPyramidCS.FindKernel("ColorGaussian"); + m_DisableTexture2DArrayColorKeyword = new LocalKeyword(m_ColorPyramidCS, ShaderKeywordStrings.DisableTexture2DXArray); + + m_DepthDownsampleKernel = m_DepthPyramidCS.FindKernel("DepthDownsample"); + m_DisableTexture2DArrayDepthKeyword = new LocalKeyword(m_DepthPyramidCS, ShaderKeywordStrings.DisableTexture2DXArray); + m_EnableCheckerboardKeyword = new LocalKeyword(m_DepthPyramidCS, k_EnableCheckerboard); + } + + m_ColorPyramidPS = runtimeShaders.colorPyramidPS; + m_DisableTexture2DArrayColorPSKeyword = new LocalKeyword(m_ColorPyramidPS, ShaderKeywordStrings.DisableTexture2DXArray); + m_ColorPyramidPSMat = CoreUtils.CreateEngineMaterial(m_ColorPyramidPS); + m_PropertyBlockBlur = new MaterialPropertyBlock(); + + m_PreferCompute = preferCompute; + } + + public void Release() + { + CoreUtils.Destroy(m_ColorPyramidPSMat); + } + + class DepthPyramidPassData + { + public PackedMipChainInfo info; + public ComputeShader cs; + public int kernel; + public TextureHandle depthTexture; + public LocalKeyword disableTexture2DArrayKeyword; + public LocalKeyword enableCheckerboardKeyword; + } + + // Generates an in-place depth pyramid Compute only + // TODO: Mip-mapping depth is problematic for precision at lower mips, generate a packed atlas instead + public void RenderMinDepthPyramid(RenderGraph renderGraph, TextureHandle depthTexture, ref PackedMipChainInfo depthBufferMipChainInfo) + { + if (!m_SupportCompute) + { + Debug.LogError("MipGenerator: Can't render depth pyramid, platform doesn't support compute shaders."); + return; + } + + using (var builder = renderGraph.AddComputePass("Generate Depth Buffer MIP Chain", out var passData)) + { + passData.info = depthBufferMipChainInfo; + passData.cs = m_DepthPyramidCS; + passData.kernel = m_DepthDownsampleKernel; + passData.depthTexture = depthTexture; + passData.disableTexture2DArrayKeyword = m_DisableTexture2DArrayDepthKeyword; + passData.enableCheckerboardKeyword = m_EnableCheckerboardKeyword; + + // Enable global state modification so we can set keywords. + builder.AllowGlobalStateModification(true); + builder.UseTexture(passData.depthTexture, AccessFlags.ReadWrite); + builder.SetRenderFunc(static (data, context) => + { + var cmd = context.cmd; + var sourceIsArray = (((RenderTexture)data.depthTexture).dimension == TextureDimension.Tex2DArray); + + cmd.SetKeyword(data.cs, data.disableTexture2DArrayKeyword, !sourceIsArray); + + // Note: Gather() doesn't take a LOD parameter and we cannot bind an SRV of a MIP level, + // and we don't support Min samplers either. So we are forced to perform 4x loads. + for (int dstIndex0 = 1; dstIndex0 < data.info.mipLevelCount;) + { + int minCount = Mathf.Min(data.info.mipLevelCount - dstIndex0, 4); + int cbCount = 0; + if (dstIndex0 < data.info.mipLevelCountCheckerboard) + { + cbCount = data.info.mipLevelCountCheckerboard - dstIndex0; + Debug.Assert(dstIndex0 == 1, "expected to make checkerboard mips on the first pass"); + Debug.Assert(cbCount <= minCount, "expected fewer checkerboard mips than min mips"); + Debug.Assert(cbCount <= 2, "expected 2 or fewer checkerboard mips for now"); + } + + Vector2Int srcOffset = data.info.mipLevelOffsets[dstIndex0 - 1]; + Vector2Int srcSize = data.info.mipLevelSizes[dstIndex0 - 1]; + int dstIndex1 = Mathf.Min(dstIndex0 + 1, data.info.mipLevelCount - 1); + int dstIndex2 = Mathf.Min(dstIndex0 + 2, data.info.mipLevelCount - 1); + int dstIndex3 = Mathf.Min(dstIndex0 + 3, data.info.mipLevelCount - 1); + + DepthPyramidConstants cb = new DepthPyramidConstants + { + _MinDstCount = (uint)minCount, + _CbDstCount = (uint)cbCount, + _SrcOffset = srcOffset, + _SrcLimit = srcSize - Vector2Int.one, + _DstSize0 = data.info.mipLevelSizes[dstIndex0], + _DstSize1 = data.info.mipLevelSizes[dstIndex1], + _DstSize2 = data.info.mipLevelSizes[dstIndex2], + _DstSize3 = data.info.mipLevelSizes[dstIndex3], + _MinDstOffset0 = data.info.mipLevelOffsets[dstIndex0], + _MinDstOffset1 = data.info.mipLevelOffsets[dstIndex1], + _MinDstOffset2 = data.info.mipLevelOffsets[dstIndex2], + _MinDstOffset3 = data.info.mipLevelOffsets[dstIndex3], + _CbDstOffset0 = data.info.mipLevelOffsetsCheckerboard[dstIndex0], + _CbDstOffset1 = data.info.mipLevelOffsetsCheckerboard[dstIndex1], + }; + + ConstantBuffer.Push(cmd, in cb, data.cs, _DepthPyramidConstants); + + cmd.SetComputeTextureParam(data.cs, data.kernel, _DepthMipChain, data.depthTexture); + cmd.SetKeyword(data.cs, data.enableCheckerboardKeyword, cbCount != 0); + + Vector2Int dstSize = data.info.mipLevelSizes[dstIndex0]; + cmd.DispatchCompute(data.cs, data.kernel, CoreUtils.DivRoundUp(dstSize.x, 8), CoreUtils.DivRoundUp(dstSize.y, 8), ((RenderTexture)data.depthTexture).volumeDepth); + + dstIndex0 += minCount; + } + + }); + } + } + + private class PassDataMipChainRaster + { + public MaterialPropertyBlock propertyBlock; + public Material material; + public TextureHandle source; + public int dstMipWidth, dstMipHeight; + public int srcMipLevel; + public float scaleX, scaleY; + public float blurSourceTextureWidth, blurSourceTextureHeight; + public LocalKeyword disableTexture2DArrayKeyword; + public bool sourceIsArray; + } + + private class PassDataMipChainCompute + { + public int numTheadGroupX, numTheadGroupY, numTheadGroupZ; + public int srcMipWidth, srcMipHeight; + public int dstMipWidth, dstMipHeight; + public int srcMipLevel; + public TextureHandle tempDownsamplePyramid, destination; + public ComputeShader cs; + public LocalKeyword disableTexture2DArrayKeyword; + public int downsampleKernel, gaussianKernel; + public bool sourceIsArray; + } + + // Generates the gaussian pyramid of source into destination + // We can't do it in place as the color pyramid has to be read while writing to the color + // buffer in some cases (e.g. refraction, distortion) + // Returns the number of mips + public int RenderColorGaussianPyramid(RenderGraph renderGraph, Vector2Int size, TextureHandle source, TextureHandle destination) + { + TextureDesc descSrc = renderGraph.GetTextureDesc(source); + TextureDesc descDst = renderGraph.GetTextureDesc(destination); + + // Select between Tex2D and Tex2DArray versions of the kernels + bool sourceIsArray = (descSrc.dimension == TextureDimension.Tex2DArray); + // Sanity check + if (sourceIsArray) + { + Debug.Assert(descSrc.dimension == descDst.dimension, "MipGenerator source texture does not match dimension of destination!"); + } + + int srcMipLevel = 0; + int srcMipWidth = size.x; + int srcMipHeight = size.y; + + bool isHardwareDrsOn = DynamicResolutionHandler.instance.HardwareDynamicResIsEnabled(); + var hardwareTextureSize = new Vector2Int(descSrc.width, descSrc.height); + if (isHardwareDrsOn) + hardwareTextureSize = DynamicResolutionHandler.instance.ApplyScalesOnSize(hardwareTextureSize); + + renderGraph.AddCopyPass(source, destination, "Copy mip 0"); + var finalTargetSize = new Vector2Int(descDst.width, descDst.height); + if (descDst.useDynamicScale && isHardwareDrsOn) + finalTargetSize = DynamicResolutionHandler.instance.ApplyScalesOnSize(finalTargetSize); + + bool usePixelShader = !m_SupportCompute || !m_PreferCompute; + + // Note: smaller mips are excluded as we don't need them and the gaussian compute works + // on 8x8 blocks + while (srcMipWidth >= 8 || srcMipHeight >= 8) + { + int dstMipWidth = Mathf.Max(1, srcMipWidth >> 1); + int dstMipHeight = Mathf.Max(1, srcMipHeight >> 1); + + var desc = new TextureDesc(dstMipWidth, dstMipHeight); + desc.name = "Temporary Downsampled Pyramid"; + desc.scale = Vector2.one * 0.5f; + desc.dimension = descSrc.dimension; + desc.colorFormat = descDst.colorFormat; + desc.enableRandomWrite = !usePixelShader; + desc.useMipMap = false; + desc.slices = sourceIsArray ? TextureXR.slices : 1; + var tempDownsamplePyramid = renderGraph.CreateTexture(desc); + + // Scale for downsample + float downsampleScaleX = ((float)srcMipWidth / finalTargetSize.x); + float downsampleScaleY = ((float)srcMipHeight / finalTargetSize.y); + + if (usePixelShader) + { + // Downsample. + renderGraph.AddBlitPass(destination, tempDownsamplePyramid, new(downsampleScaleX, downsampleScaleY), Vector2.zero, sourceMip: srcMipLevel, passName: "Color Pyramid - Downsample"); + + // In this mip generation process, source viewport can be smaller than the source render target itself because of the RTHandle system + // We are not using the scale provided by the RTHandle system for two reasons: + // - Source might be a planar probe which will not be scaled by the system (since it's actually the final target of probe rendering at the exact size) + // - When computing mip size, depending on even/odd sizes, the scale computed for mip 0 might miss a texel at the border. + // This can result in a shift in the mip map downscale that depends on the render target size rather than the actual viewport + // (Two rendering at the same viewport size but with different RTHandle reference size would yield different results which can break automated testing) + // So in the end we compute a specific scale for downscale and blur passes at each mip level. + + // Scales for Blur + // Same size as m_TempColorTargets which is the source for vertical blur + desc.name = "Temp Gaussian Pyramid Target"; + desc.slices = sourceIsArray ? TextureXR.slices : 1; + desc.dimension = descSrc.dimension; + desc.filterMode = FilterMode.Bilinear; + desc.colorFormat = descDst.colorFormat; + desc.enableRandomWrite = false; + desc.useMipMap = false; + var tempColorTarget = renderGraph.CreateTexture(desc); + + var hardwareBlurSourceTextureSize = new Vector2Int(dstMipWidth, dstMipHeight); + if (isHardwareDrsOn) + hardwareBlurSourceTextureSize = DynamicResolutionHandler.instance.ApplyScalesOnSize(hardwareBlurSourceTextureSize); + + float blurSourceTextureWidth = (float)hardwareBlurSourceTextureSize.x; + float blurSourceTextureHeight = (float)hardwareBlurSourceTextureSize.y; + + float scaleX = ((float)dstMipWidth / blurSourceTextureWidth); + float scaleY = ((float)dstMipHeight / blurSourceTextureHeight); + + // Blur horizontal. + using (var builder = renderGraph.AddRasterRenderPass("Color Pyramid - Horizontal Blur", out var passData)) + { + passData.propertyBlock = m_PropertyBlockBlur; + passData.source = tempDownsamplePyramid; + passData.material = m_ColorPyramidPSMat; + passData.dstMipWidth = dstMipWidth; + passData.dstMipHeight = dstMipHeight; + passData.scaleX = scaleX; + passData.scaleY = scaleY; + passData.blurSourceTextureWidth = blurSourceTextureWidth; + passData.blurSourceTextureHeight = blurSourceTextureHeight; + passData.disableTexture2DArrayKeyword = m_DisableTexture2DArrayColorPSKeyword; + passData.sourceIsArray = sourceIsArray; + + builder.UseTexture(passData.source, AccessFlags.Read); + builder.SetRenderAttachment(tempColorTarget, 0); + builder.SetRenderFunc(static (data, context) => MipChainRasterBlurExecutePass(data, context, false)); + } + + // Blur vertical. + using (var builder = renderGraph.AddRasterRenderPass("Color Pyramid - Vertical Blur", out var passData)) + { + passData.propertyBlock = m_PropertyBlockBlur; + passData.source = tempColorTarget; + passData.material = m_ColorPyramidPSMat; + passData.dstMipWidth = dstMipWidth; + passData.dstMipHeight = dstMipHeight; + passData.scaleX = scaleX; + passData.scaleY = scaleY; + passData.blurSourceTextureWidth = blurSourceTextureWidth; + passData.blurSourceTextureHeight = blurSourceTextureHeight; + passData.disableTexture2DArrayKeyword = m_DisableTexture2DArrayColorPSKeyword; + passData.sourceIsArray = sourceIsArray; + + builder.UseTexture(passData.source, AccessFlags.Read); + builder.SetRenderAttachment(destination, 0, AccessFlags.Write, srcMipLevel + 1, -1); + builder.SetRenderFunc(static (data, context) => MipChainRasterBlurExecutePass(data, context, true)); + } + } + else + { + using (var builder = renderGraph.AddComputePass("Color Pyramid - MIP Chain (Compute)", out var passData)) + { + passData.numTheadGroupX = (dstMipWidth + 7) / 8; + passData.numTheadGroupY = (dstMipHeight + 7) / 8; + passData.numTheadGroupZ = TextureXR.slices; + passData.srcMipWidth = srcMipWidth; + passData.srcMipHeight = srcMipHeight; + passData.dstMipWidth = dstMipWidth; + passData.dstMipHeight = dstMipHeight; + passData.srcMipLevel = srcMipLevel; + passData.tempDownsamplePyramid = tempDownsamplePyramid; + passData.destination = destination; + passData.cs = m_ColorPyramidCS; + passData.disableTexture2DArrayKeyword = m_DisableTexture2DArrayColorKeyword; + passData.downsampleKernel = m_ColorDownsampleKernel; + passData.gaussianKernel = m_ColorGaussianKernel; + passData.sourceIsArray = sourceIsArray; + + // Enable global state modification so we can set keywords. + builder.AllowGlobalStateModification(true); + builder.UseTexture(passData.tempDownsamplePyramid, AccessFlags.ReadWrite); + builder.UseTexture(destination, AccessFlags.ReadWrite); + + builder.SetRenderFunc(static (PassDataMipChainCompute data, ComputeGraphContext context) => + { + context.cmd.SetKeyword(data.cs, data.disableTexture2DArrayKeyword, !data.sourceIsArray); + + // Downsample. + context.cmd.SetComputeVectorParam(data.cs, _Size, new Vector4(data.srcMipWidth, data.srcMipHeight, 0f, 0f)); + context.cmd.SetComputeTextureParam(data.cs, data.downsampleKernel, _Source, data.destination, data.srcMipLevel); + context.cmd.SetComputeTextureParam(data.cs, data.downsampleKernel, _Destination, data.tempDownsamplePyramid); + context.cmd.DispatchCompute(data.cs, data.downsampleKernel, data.numTheadGroupX, data.numTheadGroupY, data.numTheadGroupZ); + + // Single pass blur + context.cmd.SetComputeVectorParam(data.cs, _Size, new Vector4(data.dstMipWidth, data.dstMipHeight, 0f, 0f)); + context.cmd.SetComputeTextureParam(data.cs, data.gaussianKernel, _Source, data.tempDownsamplePyramid); + context.cmd.SetComputeTextureParam(data.cs, data.gaussianKernel, _Destination, data.destination, data.srcMipLevel + 1); + context.cmd.DispatchCompute(data.cs, data.gaussianKernel, data.numTheadGroupX, data.numTheadGroupY, data.numTheadGroupZ); + }); + } + } + + srcMipLevel++; + srcMipWidth = dstMipWidth; + srcMipHeight = dstMipHeight; + + finalTargetSize.x >>= 1; + finalTargetSize.y >>= 1; + } + + return srcMipLevel + 1; + } + + static void MipChainRasterBlurExecutePass(PassDataMipChainRaster data, RasterGraphContext context, bool isVertical) + { + data.propertyBlock.SetTexture(_Source, data.source); + data.propertyBlock.SetVector(_SrcScaleBias, new Vector4(data.scaleX, data.scaleY, 0f, 0f)); + data.propertyBlock.SetVector(_SrcUvLimits, new Vector4((data.dstMipWidth - 0.5f) / data.blurSourceTextureWidth, (data.dstMipHeight - 0.5f) / data.blurSourceTextureHeight, !isVertical ? 1.0f / data.blurSourceTextureWidth : 0f, isVertical ? 1.0f / data.blurSourceTextureHeight : 0)); + data.propertyBlock.SetFloat(_SourceMip, 0); + data.material.SetKeyword(data.disableTexture2DArrayKeyword, !data.sourceIsArray); + context.cmd.SetViewport(new Rect(0, 0, data.dstMipWidth, data.dstMipHeight)); + context.cmd.DrawProcedural(Matrix4x4.identity, data.material, 0, MeshTopology.Triangles, 3, 1, data.propertyBlock); + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs.meta new file mode 100644 index 00000000000..e53674be8cd --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/MipGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 68deae0b402bcaa43a6f4fb81a956eaa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders.meta new file mode 100644 index 00000000000..2a6b2a1e40b --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6c88990944d5cd446b5b7b917b2c85a9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramid.compute b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramid.compute new file mode 100644 index 00000000000..a68f35ba18a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramid.compute @@ -0,0 +1,188 @@ +// +// This is a modified version of the BlurCS compute shader from Microsoft's MiniEngine +// library. The copyright notice from the original version is included below. +// +// The original source code of MiniEngine is available on GitHub. +// https://github.com/Microsoft/DirectX-Graphics-Samples +// + +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +// Developed by Minigraph +// +// Author: Bob Brown +// + +#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2 glcore gles3 webgpu + +#pragma kernel ColorGaussian KERNEL_SIZE=8 MAIN_GAUSSIAN=ColorGaussian +#pragma kernel ColorDownsample KERNEL_SIZE=8 MAIN_DOWNSAMPLE=ColorDownsample + +#pragma multi_compile_local _ DISABLE_TEXTURE2D_X_ARRAY + +//#define NO_ALPHA + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" + +RW_TEXTURE2D_X(unorm float4, _Source); +RW_TEXTURE2D_X(unorm float4, _Destination); + +CBUFFER_START(cb) + float4 _Size; // x: src width, y: src height, zw: unused +CBUFFER_END + +// 16x16 pixels with an 8x8 center that we will be blurring writing out. Each uint is two color +// channels packed together. +// The reason for separating channels is to reduce bank conflicts in the local data memory +// controller. A large stride will cause more threads to collide on the same memory bank. +groupshared uint gs_cacheR[128]; +groupshared uint gs_cacheG[128]; +groupshared uint gs_cacheB[128]; +#if !defined(NO_ALPHA) +groupshared uint gs_cacheA[128]; +#endif + +float4 BlurPixels(float4 a, float4 b, float4 c, float4 d, float4 e, float4 f, float4 g, float4 h, float4 i) +{ + return 0.27343750 * (e ) + + 0.21875000 * (d + f) + + 0.10937500 * (c + g) + + 0.03125000 * (b + h) + + 0.00390625 * (a + i); +} + +void Store2Pixels(uint index, float4 pixel1, float4 pixel2) +{ + gs_cacheR[index] = f32tof16(pixel1.r) | f32tof16(pixel2.r) << 16; + gs_cacheG[index] = f32tof16(pixel1.g) | f32tof16(pixel2.g) << 16; + gs_cacheB[index] = f32tof16(pixel1.b) | f32tof16(pixel2.b) << 16; +#if !defined(NO_ALPHA) + gs_cacheA[index] = f32tof16(pixel1.a) | f32tof16(pixel2.a) << 16; +#endif +} + +void Load2Pixels(uint index, out float4 pixel1, out float4 pixel2) +{ + uint rr = gs_cacheR[index]; + uint gg = gs_cacheG[index]; + uint bb = gs_cacheB[index]; +#if !defined(NO_ALPHA) + uint aa = gs_cacheA[index]; +#else + uint aa = 0; +#endif + pixel1 = float4(f16tof32(rr ), f16tof32(gg ), f16tof32(bb ), f16tof32(aa )); + pixel2 = float4(f16tof32(rr >> 16), f16tof32(gg >> 16), f16tof32(bb >> 16), f16tof32(aa >> 16)); +} + +void Store1Pixel(uint index, float4 pixel) +{ + gs_cacheR[index] = asuint(pixel.r); + gs_cacheG[index] = asuint(pixel.g); + gs_cacheB[index] = asuint(pixel.b); +#if !defined(NO_ALPHA) + gs_cacheA[index] = asuint(pixel.a); +#endif +} + +void Load1Pixel(uint index, out float4 pixel) +{ +#if defined(NO_ALPHA) + uint a = 0; +#else + uint a = gs_cacheA[index]; +#endif + pixel = asfloat(uint4(gs_cacheR[index], gs_cacheG[index], gs_cacheB[index], a)); +} + +// Blur two pixels horizontally. This reduces LDS reads and pixel unpacking. +void BlurHorizontally(uint outIndex, uint leftMostIndex) +{ + float4 s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + Load2Pixels(leftMostIndex + 0, s0, s1); + Load2Pixels(leftMostIndex + 1, s2, s3); + Load2Pixels(leftMostIndex + 2, s4, s5); + Load2Pixels(leftMostIndex + 3, s6, s7); + Load2Pixels(leftMostIndex + 4, s8, s9); + + Store1Pixel(outIndex , BlurPixels(s0, s1, s2, s3, s4, s5, s6, s7, s8)); + Store1Pixel(outIndex + 1, BlurPixels(s1, s2, s3, s4, s5, s6, s7, s8, s9)); +} + +void BlurVertically(uint2 pixelCoord, uint topMostIndex) +{ + float4 s0, s1, s2, s3, s4, s5, s6, s7, s8; + Load1Pixel(topMostIndex , s0); + Load1Pixel(topMostIndex + 8, s1); + Load1Pixel(topMostIndex + 16, s2); + Load1Pixel(topMostIndex + 24, s3); + Load1Pixel(topMostIndex + 32, s4); + Load1Pixel(topMostIndex + 40, s5); + Load1Pixel(topMostIndex + 48, s6); + Load1Pixel(topMostIndex + 56, s7); + Load1Pixel(topMostIndex + 64, s8); + + float4 blurred = BlurPixels(s0, s1, s2, s3, s4, s5, s6, s7, s8); + + // Write to the final target + _Destination[COORD_TEXTURE2D_X(pixelCoord)] = blurred; +} + +[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)] +void MAIN_GAUSSIAN(uint2 groupId : SV_GroupID, uint2 groupThreadId : SV_GroupThreadID, uint3 dispatchThreadId : SV_DispatchThreadID) +{ + UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); + + // Upper-left pixel coordinate of quad that this thread will read + int2 threadUL = (groupThreadId << 1) + (groupId << 3) - 4; + uint2 uthreadUL = uint2(max(0, threadUL)); + + uint2 size = uint2(_Size.xy) - 1u; + float4 p00 = _Source[COORD_TEXTURE2D_X(min(uthreadUL + uint2(0u, 0u), size))]; + float4 p10 = _Source[COORD_TEXTURE2D_X(min(uthreadUL + uint2(1u, 0u), size))]; + float4 p11 = _Source[COORD_TEXTURE2D_X(min(uthreadUL + uint2(1u, 1u), size))]; + float4 p01 = _Source[COORD_TEXTURE2D_X(min(uthreadUL + uint2(0u, 1u), size))]; + + // Store the 4 downsampled pixels in LDS + uint destIdx = groupThreadId.x + (groupThreadId.y << 4u); + Store2Pixels(destIdx , p00, p10); + Store2Pixels(destIdx + 8u, p01, p11); + + GroupMemoryBarrierWithGroupSync(); + + // Horizontally blur the pixels in LDS + uint row = groupThreadId.y << 4u; + BlurHorizontally(row + (groupThreadId.x << 1u), row + groupThreadId.x + (groupThreadId.x & 4u)); + + GroupMemoryBarrierWithGroupSync(); + + // Vertically blur the pixels in LDS and write the result to memory + BlurVertically(dispatchThreadId.xy, (groupThreadId.y << 3u) + groupThreadId.x); +} + +[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)] +void MAIN_DOWNSAMPLE(uint3 dispatchThreadId : SV_DispatchThreadID) +{ + UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z); + + uint2 offset = dispatchThreadId.xy * 2u; + uint2 size = uint2(_Size.xy) - 1u; + + uint2 c00 = min(offset + uint2(0u, 0u), size); + uint2 c10 = min(offset + uint2(1u, 0u), size); + uint2 c11 = min(offset + uint2(1u, 1u), size); + uint2 c01 = min(offset + uint2(0u, 1u), size); + float4 p00 = _Source[COORD_TEXTURE2D_X(c00)]; + float4 p10 = _Source[COORD_TEXTURE2D_X(c10)]; + float4 p11 = _Source[COORD_TEXTURE2D_X(c11)]; + float4 p01 = _Source[COORD_TEXTURE2D_X(c01)]; + + _Destination[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = (p00 + p01 + p11 + p10) * 0.25; +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramid.compute.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramid.compute.meta new file mode 100644 index 00000000000..20f2715d8e6 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramid.compute.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 28969cfddd9ef3f4e94b971690146a4f +timeCreated: 1503754250 +licenseType: Pro +ComputeShaderImporter: + currentAPIMask: 131076 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.hlsl new file mode 100644 index 00000000000..a7a8cada8de --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.hlsl @@ -0,0 +1,57 @@ +#pragma multi_compile_local _ DISABLE_TEXTURE2D_X_ARRAY + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + +TEXTURE2D_X_HALF(_Source); +uniform float4 _SrcScaleBias; +uniform float4 _SrcUvLimits; // {xy: max uv, zw: offset of blur for 1 texel } +uniform half _SourceMip; + +struct Attributes +{ + uint vertexID : SV_VertexID; + UNITY_VERTEX_INPUT_INSTANCE_ID +}; + +struct Varyings +{ + float4 positionCS : SV_POSITION; + float2 texcoord : TEXCOORD0; + UNITY_VERTEX_OUTPUT_STEREO +}; + +Varyings Vert(Attributes input) +{ + Varyings output; + UNITY_SETUP_INSTANCE_ID(input); + UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); + output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID); + output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID) * _SrcScaleBias.xy + _SrcScaleBias.zw; + return output; +} + +half4 Frag(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + // Gaussian weights for 9 texel kernel from center textel to furthest texel. Keep in sync with ColorPyramid.compute + const half gaussWeights[] = { 0.27343750, 0.21875000, 0.10937500, 0.03125000, 0.00390625 }; + + float2 offset = _SrcUvLimits.zw; + float2 offset1 = offset * (1.0 + (gaussWeights[2] / (gaussWeights[1] + gaussWeights[2]))); + float2 offset2 = offset * (3.0 + (gaussWeights[4] / (gaussWeights[3] + gaussWeights[4]))); + + float2 uv_m2 = input.texcoord.xy - offset2; + float2 uv_m1 = input.texcoord.xy - offset1; + float2 uv_p0 = input.texcoord.xy; + float2 uv_p1 = min(_SrcUvLimits.xy, input.texcoord.xy + offset1); + float2 uv_p2 = min(_SrcUvLimits.xy, input.texcoord.xy + offset2); + + return + + SAMPLE_TEXTURE2D_X_LOD(_Source, sampler_LinearClamp, uv_m2, _SourceMip) * (gaussWeights[3] + gaussWeights[4]) + + SAMPLE_TEXTURE2D_X_LOD(_Source, sampler_LinearClamp, uv_m1, _SourceMip) * (gaussWeights[1] + gaussWeights[2]) + + SAMPLE_TEXTURE2D_X_LOD(_Source, sampler_LinearClamp, uv_p0, _SourceMip) * gaussWeights[0] + + SAMPLE_TEXTURE2D_X_LOD(_Source, sampler_LinearClamp, uv_p1, _SourceMip) * (gaussWeights[1] + gaussWeights[2]) + + SAMPLE_TEXTURE2D_X_LOD(_Source, sampler_LinearClamp, uv_p2, _SourceMip) * (gaussWeights[3] + gaussWeights[4]); +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.hlsl.meta new file mode 100644 index 00000000000..835cc8b0f27 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.hlsl.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 95152aa728f8eec4d9d5c1988ddd90e6 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.shader b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.shader new file mode 100644 index 00000000000..5ac3e092f29 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.shader @@ -0,0 +1,23 @@ +Shader "Hidden/ColorPyramidPS" +{ + SubShader + { + Tags{ "RenderPipeline" = "UniversalPipeline" } + + Pass + { + ZWrite Off ZTest Always Blend Off Cull Off + ColorMask RGBA + + HLSLPROGRAM + #pragma editor_sync_compilation + #pragma target 2.0 + #pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2 glcore gles3 webgpu + #pragma vertex Vert + #pragma fragment Frag + #include_with_pragmas "ColorPyramidPS.hlsl" + ENDHLSL + } + } + Fallback Off +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.shader.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.shader.meta new file mode 100644 index 00000000000..f40c57fedd9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/ColorPyramidPS.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 63b92baba208e314c8fdebe52ca0cc34 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramid.compute b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramid.compute new file mode 100644 index 00000000000..97933346c24 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramid.compute @@ -0,0 +1,130 @@ +#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2 glcore gles3 webgpu + +#pragma multi_compile_local _ ENABLE_CHECKERBOARD +#pragma multi_compile_local _ DISABLE_TEXTURE2D_X_ARRAY + +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureXR.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl" + +#pragma kernel DepthDownsample + +RW_TEXTURE2D_X(float, _DepthMipChain); + +#if UNITY_REVERSED_Z +#define MIN_DEPTH(A, B) max((A), (B)) +#define MIN3_DEPTH(A, B, C) Max3((A), (B), (C)) +#define MAX_DEPTH(A, B) min((A), (B)) +#define MAX3_DEPTH(A, B, C) Min3((A), (B), (C)) +#else +#define MIN_DEPTH(A, B) min((A), (B)) +#define MIN3_DEPTH(A, B, C) Min3((A), (B), (C)) +#define MAX_DEPTH(A, B) max((A), (B)) +#define MAX3_DEPTH(A, B, C) Max3((A), (B), (C)) +#endif + +uint2 CoordInTileByIndex(uint i) +{ + // decode i = [yxxyyx] (we want each pair of bits to have an x and a y) + return uint2( + (i & 1) | ((i >> 2) & 6), + ((i >> 1) & 3) | ((i >> 3) & 4)); +} + +groupshared float s_minDepth[32]; +#ifdef ENABLE_CHECKERBOARD +groupshared float s_maxDepth[32]; +#endif + +void SubgroupMergeDepths(uint threadID, uint bitIndex, inout float minDepth, inout float maxDepth) +{ + uint highIndex = threadID >> (bitIndex + 1); + uint lowIndex = threadID & ((1 << (bitIndex + 1)) - 1); + + if (lowIndex == (1 << bitIndex)) + { + s_minDepth[highIndex] = minDepth; +#ifdef ENABLE_CHECKERBOARD + s_maxDepth[highIndex] = maxDepth; +#endif + } + GroupMemoryBarrierWithGroupSync(); + + if (lowIndex == 0) + { + minDepth = MIN_DEPTH(minDepth, s_minDepth[highIndex]); +#ifdef ENABLE_CHECKERBOARD + maxDepth = MAX_DEPTH(maxDepth, s_maxDepth[highIndex]); +#endif + } + GroupMemoryBarrierWithGroupSync(); +} + +float CheckerboardDepth(uint2 coord, float minDepth, float maxDepth) +{ + return ((coord.x ^ coord.y) & 1) ? minDepth : maxDepth; +} + +// Downsample a depth texture by taking the min value of sampled pixels +[numthreads(64, 1, 1)] +void DepthDownsample(uint threadID : SV_GroupThreadID, uint3 groupID : SV_GroupID) +{ + UNITY_XR_ASSIGN_VIEW_INDEX(groupID.z); + + // assign threads to pixels in a swizzle-like pattern + int2 dstCoord0 = (groupID.xy << 3) | CoordInTileByIndex(threadID); + + int2 readOffsetUL = dstCoord0 << 1; + float p00 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(0, 0), _SrcLimit))]; + float p10 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(1, 0), _SrcLimit))]; + float p01 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(0, 1), _SrcLimit))]; + float p11 = _DepthMipChain[COORD_TEXTURE2D_X(_SrcOffset + min(readOffsetUL + int2(1, 1), _SrcLimit))]; + float minDepth = MIN3_DEPTH(p00, p10, MIN_DEPTH(p01, p11)); + float maxDepth = MAX3_DEPTH(p00, p10, MAX_DEPTH(p01, p11)); + + // write dst0 + if (all(dstCoord0 < _DstSize0)) + { + _DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset0 + dstCoord0)] = minDepth; +#ifdef ENABLE_CHECKERBOARD + if (_CbDstCount >= 1) + _DepthMipChain[COORD_TEXTURE2D_X(_CbDstOffset0 + dstCoord0)] = CheckerboardDepth(dstCoord0, minDepth, maxDepth); +#endif + } + + // merge to thread 0 in subgroup size 4 + SubgroupMergeDepths(threadID, 0, minDepth, maxDepth); + SubgroupMergeDepths(threadID, 1, minDepth, maxDepth); + if (_MinDstCount >= 2 && (threadID & 0x3) == 0) + { + int2 dstCoord1 = dstCoord0 >> 1; + if (all(dstCoord1 < _DstSize1)) + { + _DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset1 + dstCoord1)] = minDepth; +#ifdef ENABLE_CHECKERBOARD + if (_CbDstCount >= 2) + _DepthMipChain[COORD_TEXTURE2D_X(_CbDstOffset1 + dstCoord1)] = CheckerboardDepth(dstCoord1, minDepth, maxDepth); +#endif + } + } + + // merge to thread 0 in subgroup size 16 + SubgroupMergeDepths(threadID, 2, minDepth, maxDepth); + SubgroupMergeDepths(threadID, 3, minDepth, maxDepth); + if (_MinDstCount >= 3 && (threadID & 0xf) == 0) + { + int2 dstCoord2 = dstCoord0 >> 2; + if (all(dstCoord2 < _DstSize2)) + _DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset2 + dstCoord2)] = minDepth; + } + + // merge to thread 0 + SubgroupMergeDepths(threadID, 4, minDepth, maxDepth); + SubgroupMergeDepths(threadID, 5, minDepth, maxDepth); + if (_MinDstCount >= 4 && (threadID & 0x3f) == 0) + { + int2 dstCoord3 = dstCoord0 >> 3; + if (all(dstCoord3 < _DstSize3)) + _DepthMipChain[COORD_TEXTURE2D_X(_MinDstOffset3 + dstCoord3)] = minDepth; + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramid.compute.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramid.compute.meta new file mode 100644 index 00000000000..b2d59121e15 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramid.compute.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 90a204702cd44e54cac7ed4fc6e5d86b +timeCreated: 1506516404 +licenseType: Pro +ComputeShaderImporter: + externalObjects: {} + currentAPIMask: 4 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs new file mode 100644 index 00000000000..5d56fa43cbe --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs @@ -0,0 +1,27 @@ +namespace UnityEngine.Rendering +{ + [GenerateHLSL(needAccessors = false, generateCBuffer = true)] + internal unsafe struct DepthPyramidConstants + { + public uint _MinDstCount; + public uint _CbDstCount; + public uint _DepthPyramidPad0; + public uint _DepthPyramidPad1; + + public Vector2Int _SrcOffset; + public Vector2Int _SrcLimit; + + public Vector2Int _DstSize0; + public Vector2Int _DstSize1; + public Vector2Int _DstSize2; + public Vector2Int _DstSize3; + + public Vector2Int _MinDstOffset0; + public Vector2Int _MinDstOffset1; + public Vector2Int _MinDstOffset2; + public Vector2Int _MinDstOffset3; + + public Vector2Int _CbDstOffset0; + public Vector2Int _CbDstOffset1; + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl new file mode 100644 index 00000000000..5e8e9edaad3 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl @@ -0,0 +1,29 @@ +// +// This file was automatically generated. Please don't edit by hand. Execute Editor command [ Edit > Rendering > Generate Shader Includes ] instead +// + +#ifndef DEPTHPYRAMIDCONSTANTS_CS_HLSL +#define DEPTHPYRAMIDCONSTANTS_CS_HLSL +// Generated from UnityEngine.Rendering.DepthPyramidConstants +// PackingRules = Exact +CBUFFER_START(DepthPyramidConstants) + uint _MinDstCount; + uint _CbDstCount; + uint _DepthPyramidPad0; + uint _DepthPyramidPad1; + int2 _SrcOffset; + int2 _SrcLimit; + int2 _DstSize0; + int2 _DstSize1; + int2 _DstSize2; + int2 _DstSize3; + int2 _MinDstOffset0; + int2 _MinDstOffset1; + int2 _MinDstOffset2; + int2 _MinDstOffset3; + int2 _CbDstOffset0; + int2 _CbDstOffset1; +CBUFFER_END + + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl.meta new file mode 100644 index 00000000000..1673d674312 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dda90eae3301de545856ee63771154fd +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.meta new file mode 100644 index 00000000000..fe0048c2a11 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/MipGen/Shaders/DepthPyramidConstants.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7f6fd62f76461a0429f9b8049a8f339c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Overrides/SurfaceCacheGIVolumeOverride.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Overrides/SurfaceCacheGIVolumeOverride.cs new file mode 100644 index 00000000000..d1976b77143 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Overrides/SurfaceCacheGIVolumeOverride.cs @@ -0,0 +1,401 @@ +#if SURFACE_CACHE + +using System; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// Quality presets for Surface Cache Global Illumination. + /// + public enum SurfaceCacheGIQuality + { + /// + /// Low quality preset - minimal samples, maximum performance. + /// + Low, + + /// + /// Medium quality preset - balanced quality and performance (default). + /// + Medium, + + /// + /// High quality preset - higher quality with increased cost. + /// + High, + + /// + /// Ultra quality preset - maximum quality, highest cost. + /// + Ultra, + + /// + /// Custom quality - user-defined parameters. + /// + Custom + } + + /// + /// A volume component that holds settings for the Surface Cache Global Illumination feature. + /// + [Serializable, VolumeComponentMenu("Lighting/Surface Cache Global Illumination")] + [SupportedOnRenderPipeline(typeof(UniversalRenderPipelineAsset))] + public class SurfaceCacheGIVolumeOverride : VolumeComponent + { + /// + /// Quality preset for Surface Cache GI. Selecting a preset automatically configures all quality-related parameters. + /// Select Custom to manually adjust individual parameters. + /// + [Tooltip("Quality preset for Surface Cache GI. Select Custom to manually adjust individual parameters.")] + public SurfaceCacheGIQualityVolumeParameter quality = new SurfaceCacheGIQualityVolumeParameter(SurfaceCacheGIQuality.Medium); + + // ==================== + // Sampling Parameters + // ==================== + + /// + /// Enable multi-bounce global illumination. + /// + [Tooltip("Enable multi-bounce global illumination for more accurate light propagation.")] + public bool multiBounce + { + get => m_MultiBounce.value; + set => m_MultiBounce.value = value; + } + [SerializeField] + private BoolParameter m_MultiBounce = new BoolParameter(true); + + /// + /// Number of samples used for GI estimation. Higher values improve quality at performance cost. + /// + public int sampleCount + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_SampleCount.value; + else + return GetPresetSampleCount(quality.value); + } + set => m_SampleCount.value = value; + } + [SerializeField] + private ClampedIntParameter m_SampleCount = new ClampedIntParameter(2, 1, 32); + + // ============================ + // Patch Filtering Parameters + // ============================ + + /// + /// Temporal smoothing factor for patch data. Higher values produce more stable results but slower response to lighting changes. + /// + public float temporalSmoothing + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_TemporalSmoothing.value; + else + return GetPresetTemporalSmoothing(quality.value); + } + set => m_TemporalSmoothing.value = value; + } + [SerializeField] + private ClampedFloatParameter m_TemporalSmoothing = new ClampedFloatParameter(0.8f, 0.0f, 1.0f); + + /// + /// Enable spatial filtering for patch data. + /// + public bool spatialFilterEnabled + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_SpatialFilterEnabled.value; + else + return GetPresetSpatialFilterEnabled(quality.value); + } + set => m_SpatialFilterEnabled.value = value; + } + [SerializeField] + private BoolParameter m_SpatialFilterEnabled = new BoolParameter(true); + + /// + /// Number of samples for spatial filtering. Higher values improve quality at performance cost. + /// + public int spatialSampleCount + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_SpatialSampleCount.value; + else + return GetPresetSpatialSampleCount(quality.value); + } + set => m_SpatialSampleCount.value = value; + } + [SerializeField] + private ClampedIntParameter m_SpatialSampleCount = new ClampedIntParameter(4, 1, 8); + + /// + /// Radius for spatial filtering in world units. + /// + public float spatialRadius + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_SpatialRadius.value; + else + return GetPresetSpatialRadius(quality.value); + } + set => m_SpatialRadius.value = value; + } + [SerializeField] + private ClampedFloatParameter m_SpatialRadius = new ClampedFloatParameter(1.0f, 0.1f, 4.0f); + + /// + /// Enable temporal post-filtering for additional image stability. + /// + public bool temporalPostFilter + { + get => m_TemporalPostFilter.value; + set => m_TemporalPostFilter.value = value; + } + [SerializeField] + private BoolParameter m_TemporalPostFilter = new BoolParameter(true); + + // ============================ + // Screen Filtering Parameters + // ============================ + + /// + /// Number of samples for screen-space lookups. + /// + public int lookupSampleCount + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_LookupSampleCount.value; + else + return GetPresetLookupSampleCount(quality.value); + } + set => m_LookupSampleCount.value = value; + } + [SerializeField] + private ClampedIntParameter m_LookupSampleCount = new ClampedIntParameter(6, 0, 8); + + /// + /// Kernel size for upsampling filtering. + /// + public float upsamplingKernelSize + { + get => m_UpsamplingKernelSize.value; + set => m_UpsamplingKernelSize.value = value; + } + [SerializeField] + private ClampedFloatParameter m_UpsamplingKernelSize = new ClampedFloatParameter(5.0f, 0.0f, 8.0f); + + /// + /// Number of samples for upsampling. Higher values improve quality at performance cost. + /// + public int upsamplingSampleCount + { + get + { + if (quality.value == SurfaceCacheGIQuality.Custom) + return m_UpsamplingSampleCount.value; + else + return GetPresetUpsamplingSampleCount(quality.value); + } + set => m_UpsamplingSampleCount.value = value; + } + [SerializeField] + private ClampedIntParameter m_UpsamplingSampleCount = new ClampedIntParameter(2, 1, 16); + + // ======================= + // Volume Configuration + // ======================= + + /// + /// Size of the surface cache volume in world units. + /// This can be changed per-scene without causing a performance hitch. + /// + public float volumeSize + { + get => m_VolumeSize.value; + set => m_VolumeSize.value = value; + } + [SerializeField] + private MinFloatParameter m_VolumeSize = new MinFloatParameter(128.0f, 1.0f); + + /// + /// Spatial resolution of the surface cache volume. Higher values improve spatial detail but use more memory. + /// Changing this at runtime can cause a performance hitch as internal buffers are reallocated (BVH is preserved). + /// + public int volumeResolution + { + get => m_VolumeResolution.value; + set => m_VolumeResolution.value = value; + } + [SerializeField] + private ClampedIntParameter m_VolumeResolution = new ClampedIntParameter(32, 16, 128); + + /// + /// Number of cascades for the surface cache volume. More cascades extend the volume's reach. + /// Changing this at runtime can cause a performance hitch as internal buffers are reallocated (BVH is preserved). + /// + public int volumeCascadeCount + { + get => m_VolumeCascadeCount.value; + set => m_VolumeCascadeCount.value = value; + } + [SerializeField] + private ClampedIntParameter m_VolumeCascadeCount = new ClampedIntParameter(4, 1, 8); + + // ======================= + // Volume Behavior + // ======================= + + /// + /// Enable volume cascades to follow the camera. + /// + public bool cascadeMovement + { + get => m_CascadeMovement.value; + set => m_CascadeMovement.value = value; + } + [SerializeField] + private BoolParameter m_CascadeMovement = new BoolParameter(true); + + // ======================= + // Advanced Properties + // ======================= + + /// + /// Number of surface cache patches to defragment per frame. + /// + public int defragCount + { + get => m_DefragCount.value; + set => m_DefragCount.value = value; + } + [AdditionalProperty] + [SerializeField] + private ClampedIntParameter m_DefragCount = new ClampedIntParameter(2, 1, 32); + + // ======================= + // Preset Lookup Methods + // ======================= + + private static int GetPresetSampleCount(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => 1, + SurfaceCacheGIQuality.Medium => 2, + SurfaceCacheGIQuality.High => 4, + SurfaceCacheGIQuality.Ultra => 8, + _ => 2 + }; + } + + private static float GetPresetTemporalSmoothing(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => 0.9f, + SurfaceCacheGIQuality.Medium => 0.8f, + SurfaceCacheGIQuality.High => 0.7f, + SurfaceCacheGIQuality.Ultra => 0.6f, + _ => 0.8f + }; + } + + private static bool GetPresetSpatialFilterEnabled(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => false, + SurfaceCacheGIQuality.Medium => true, + SurfaceCacheGIQuality.High => true, + SurfaceCacheGIQuality.Ultra => true, + _ => true + }; + } + + private static int GetPresetSpatialSampleCount(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => 4, + SurfaceCacheGIQuality.Medium => 4, + SurfaceCacheGIQuality.High => 6, + SurfaceCacheGIQuality.Ultra => 8, + _ => 4 + }; + } + + private static float GetPresetSpatialRadius(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => 1.0f, + SurfaceCacheGIQuality.Medium => 1.0f, + SurfaceCacheGIQuality.High => 1.5f, + SurfaceCacheGIQuality.Ultra => 2.0f, + _ => 1.0f + }; + } + + private static int GetPresetLookupSampleCount(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => 4, + SurfaceCacheGIQuality.Medium => 6, + SurfaceCacheGIQuality.High => 8, + SurfaceCacheGIQuality.Ultra => 8, + _ => 6 + }; + } + + private static int GetPresetUpsamplingSampleCount(SurfaceCacheGIQuality quality) + { + return quality switch + { + SurfaceCacheGIQuality.Low => 1, + SurfaceCacheGIQuality.Medium => 2, + SurfaceCacheGIQuality.High => 4, + SurfaceCacheGIQuality.Ultra => 8, + _ => 2 + }; + } + + /// + /// Query if the effect is active and should be rendered. + /// + /// true if the effect should be rendered, false otherwise. + public bool IsActive() + { + return true; + } + } + + /// + /// A that holds a value. + /// + [Serializable] + public sealed class SurfaceCacheGIQualityVolumeParameter : VolumeParameter + { + /// + /// Creates a new instance. + /// + /// The initial value to store in the parameter. + /// The initial override state for the parameter. + public SurfaceCacheGIQualityVolumeParameter(SurfaceCacheGIQuality value, bool overrideState = false) : base(value, overrideState) { } + } +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Overrides/SurfaceCacheGIVolumeOverride.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/Overrides/SurfaceCacheGIVolumeOverride.cs.meta new file mode 100644 index 00000000000..ffe26456b11 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Overrides/SurfaceCacheGIVolumeOverride.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ac1e685d8f7565142b879339cd471764 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DepthNormalOnlyPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DepthNormalOnlyPass.cs index ed1a959a5d8..962b05d5b7d 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DepthNormalOnlyPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DepthNormalOnlyPass.cs @@ -30,12 +30,13 @@ public partial class DepthNormalOnlyPass : ScriptableRenderPass /// The RenderPassEvent to use. /// The RenderQueueRange to use for creating filtering settings that control what objects get rendered. /// The layer mask to use for creating filtering settings that control what objects get rendered. + /// The ProfilingSampler to use in the profiler and frame debugger for this pass. /// /// /// - public DepthNormalOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask) + public DepthNormalOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask, ProfilingSampler sampler = null) { - profilingSampler = ProfilingSampler.Get(URPProfileId.DrawDepthNormalPrepass); + profilingSampler = sampler ?? ProfilingSampler.Get(URPProfileId.DrawDepthNormalPrepass); m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask); renderPassEvent = evt; shaderTagIds = k_DepthNormals; @@ -83,6 +84,8 @@ private static void ExecutePass(RasterCommandBuffer cmd, PassData passData, Rend // Enable Rendering Layers if (passData.enableRenderingLayers) cmd.SetKeyword(ShaderGlobalKeywords.WriteRenderingLayers, true); + if (passData.outputSmoothness) + cmd.SetKeyword(ShaderGlobalKeywords.WriteSmoothness, true); // Draw cmd.DrawRendererList(rendererList); @@ -90,6 +93,8 @@ private static void ExecutePass(RasterCommandBuffer cmd, PassData passData, Rend // Clean up if (passData.enableRenderingLayers) cmd.SetKeyword(ShaderGlobalKeywords.WriteRenderingLayers, false); + if (passData.outputSmoothness) + cmd.SetKeyword(ShaderGlobalKeywords.WriteSmoothness, false); } /// @@ -110,14 +115,14 @@ public override void OnCameraCleanup(CommandBuffer cmd) private class PassData { internal bool enableRenderingLayers; + internal bool outputSmoothness; internal RenderingLayerUtils.MaskSize maskSize; internal RendererListHandle rendererList; } private RendererListParams InitRendererListParams(UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalLightData lightData) { - var sortFlags = cameraData.defaultOpaqueSortFlags; - var drawSettings = RenderingUtils.CreateDrawingSettings(this.shaderTagIds, renderingData, cameraData, lightData, sortFlags); + var drawSettings = RenderingUtils.CreateDrawingSettings(this.shaderTagIds, renderingData, cameraData, lightData, GetSortingCriteria(cameraData)); drawSettings.perObjectData = PerObjectData.None; return new RendererListParams(renderingData.cullResults, drawSettings, m_FilteringSettings); } @@ -143,6 +148,11 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData, in Tex builder.SetRenderAttachmentDepth(depthTexture, AccessFlags.ReadWrite); passData.enableRenderingLayers = enableRenderingLayers; +#if URP_SCREEN_SPACE_REFLECTION + passData.outputSmoothness = renderingData.writesSmoothnessToDepthNormalsAlpha; +#else + passData.outputSmoothness = false; +#endif if (passData.enableRenderingLayers) { @@ -175,8 +185,8 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData, in Tex if (setGlobalDepth) builder.SetGlobalTextureAfterPass(depthTexture, s_CameraDepthTextureID); - // Required here because of RenderingLayerUtils.SetupProperties - if (passData.enableRenderingLayers) + // Required here because of RenderingLayerUtils.SetupProperties, and for setting keywords in ExecutePass + if (passData.enableRenderingLayers || passData.outputSmoothness) builder.AllowGlobalStateModification(true); builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => @@ -187,5 +197,15 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData, in Tex }); } } + + /// + /// Gets the sorting criteria to use for a given camera. Override to customize behavior. + /// + /// The UniversalCameraData of the camera to get sorting criteria for. + /// The sorting criteria to use. + protected virtual SortingCriteria GetSortingCriteria(UniversalCameraData cameraData) + { + return cameraData.defaultOpaqueSortFlags; + } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs index 863e6ccaf23..43487c5792b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/DrawScreenSpaceUIPass.cs @@ -126,9 +126,15 @@ internal void RenderOffscreen(RenderGraph renderGraph, ContextContainer frameDat internal void RenderOverlay(RenderGraph renderGraph, ContextContainer frameData, in TextureHandle colorBuffer, in TextureHandle depthBuffer) { - UniversalCameraData cameraData = frameData.Get(); - UniversalResourceData resourceData = frameData.Get(); - UniversalRenderer renderer = cameraData.renderer as UniversalRenderer; + RenderOverlayUIToolkitAndUGUI(renderGraph, frameData, in colorBuffer, in depthBuffer); + RenderOverlayIMGUI(renderGraph, frameData, in colorBuffer, in depthBuffer); + } + + internal void RenderOverlayUIToolkitAndUGUI(RenderGraph renderGraph, ContextContainer frameData, in TextureHandle colorBuffer, in TextureHandle depthBuffer) + { + var cameraData = frameData.Get(); + var resourceData = frameData.Get(); + var renderer = cameraData.renderer as UniversalRenderer; // Render uGUI and UIToolkit overlays using (var builder = renderGraph.AddRasterRenderPass("Draw UIToolkit/uGUI Overlay", out var passData, profilingSampler)) @@ -147,6 +153,12 @@ internal void RenderOverlay(RenderGraph renderGraph, ContextContainer frameData, ExecutePass(context.cmd, data, data.rendererList); }); } + } + + internal void RenderOverlayIMGUI(RenderGraph renderGraph, ContextContainer frameData, in TextureHandle colorBuffer, in TextureHandle depthBuffer) + { + var cameraData = frameData.Get(); + // Render IMGUI overlay and software cursor in a UnsafePass // Doing so allow us to safely cover cases when graphics commands called through onGUI() in user scripts are not supported by RenderPass API // Besides, Vulkan backend doesn't support SetSRGWrite() in RenderPass API and we have some of them at IMGUI levels diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs index e2b2c9a7927..6c55569664c 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/ScreenSpaceAmbientOcclusionPass.cs @@ -127,39 +127,12 @@ internal ScreenSpaceAmbientOcclusionPass() m_CurrentSettings = new ScreenSpaceAmbientOcclusionSettings(); } - internal bool Setup(ScreenSpaceAmbientOcclusionSettings featureSettings, ScriptableRenderer renderer, Material material, Texture2D[] blueNoiseTextures) + internal bool Setup(ScreenSpaceAmbientOcclusionSettings featureSettings, ScreenSpaceAmbientOcclusionSettings.DepthSource depthSource, Material material, Texture2D[] blueNoiseTextures) { m_BlueNoiseTextures = blueNoiseTextures; m_Material = material; m_CurrentSettings = featureSettings; - - // RenderPass Event + Source Settings (Depth / Depth&Normals - if (renderer is UniversalRenderer { usesDeferredLighting: true }) - { - renderPassEvent = m_CurrentSettings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingPrePasses; - - m_CurrentSettings.Source = ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals; - } - else - { - // Rendering after PrePasses is usually correct except when depth priming is in play: - // then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSAO. - // Hence we set the event to RenderPassEvent.AfterRenderingPrePasses + 1 at the earliest. - renderPassEvent = m_CurrentSettings.AfterOpaque ? RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.AfterRenderingPrePasses + 1; - } - - // Ask for a Depth or Depth + Normals textures - switch (m_CurrentSettings.Source) - { - case ScreenSpaceAmbientOcclusionSettings.DepthSource.Depth: - ConfigureInput(ScriptableRenderPassInput.Depth); - break; - case ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals: - ConfigureInput(ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal); // need depthNormal prepass for forward-only geometry - break; - default: - throw new ArgumentOutOfRangeException(); - } + m_CurrentSettings.Source = depthSource; // Blur settings switch (m_CurrentSettings.BlurQuality) @@ -277,7 +250,6 @@ private class SSAOPassData internal MaterialPropertyBlock materialPropertyBlock; internal Material material; internal float directLightingStrength; - internal TextureHandle cameraColor; internal TextureHandle AOTexture; internal TextureHandle finalTexture; internal TextureHandle blurTexture; @@ -399,7 +371,6 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // Fill in the Pass data... InitSSAOPassData(passData); - passData.cameraColor = resourceData.cameraColor; passData.AOTexture = aoTexture; passData.finalTexture = finalTexture; passData.blurTexture = blurTexture; @@ -409,13 +380,6 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer // Declare input textures builder.SetRenderAttachment(passData.AOTexture, 0, AccessFlags.WriteAll); - // TODO: Refactor to eliminate the need for 'UseTexture'. - // Currently required only because 'PostProcessUtils.SetSourceSize' allocates an RTHandle, - // which expects a valid graphicsResource. Without this call, 'cameraColor.graphicsResource' - // may be null if it wasn't initialized in an earlier pass (e.g., DrawOpaque). - if (passData.cameraColor.IsValid()) - builder.UseTexture(passData.cameraColor, AccessFlags.Read); - if (cameraDepthTexture.IsValid()) builder.UseTexture(cameraDepthTexture, AccessFlags.Read); @@ -427,15 +391,15 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.SetRenderFunc(static (SSAOPassData data, RasterGraphContext ctx) => { - // Setup - PostProcessUtils.SetGlobalShaderSourceSize(ctx.cmd, data.cameraData.cameraTargetDescriptor.width, data.cameraData.cameraTargetDescriptor.height, data.cameraColor); + var desc = data.cameraData.cameraTargetDescriptor; + PostProcessUtils.SetGlobalShaderSourceSize(ctx.cmd, desc.width, desc.height, desc.useDynamicScale); + + data.materialPropertyBlock.Clear(); if (data.cameraNormalsTexture.IsValid()) data.materialPropertyBlock.SetTexture(s_CameraNormalsTextureID, data.cameraNormalsTexture); Vector4 viewScaleBias = new(1, 1, 0, 0); - - data.materialPropertyBlock.Clear(); data.materialPropertyBlock.SetVector(_BlitScaleBias, viewScaleBias); CoreUtils.DrawFullScreen(ctx.cmd, data.material, data.materialPropertyBlock, (int)ShaderPasses.AmbientOcclusion); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs index b08f32a148d..5bcdf649d9b 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/Passes/XRDepthMotionPass.cs @@ -18,6 +18,7 @@ public class XRDepthMotionPass : ScriptableRenderPass private RTHandle m_XRMotionVectorDepth; private TextureHandle xrMotionVectorDepth; private bool m_XRSpaceWarpRightHandedNDC; + private LayerMask m_transparentlayerMask; /// /// Creates a new XRDepthMotionPass instance. @@ -25,7 +26,7 @@ public class XRDepthMotionPass : ScriptableRenderPass /// The RenderPassEvent to use. /// The Shader used for rendering XR camera motion vector. /// - public XRDepthMotionPass(RenderPassEvent evt, Shader xrMotionVector) + public XRDepthMotionPass(RenderPassEvent evt, Shader xrMotionVector, LayerMask transparentLayerMask) { base.profilingSampler = new ProfilingSampler(nameof(XRDepthMotionPass)); renderPassEvent = evt; @@ -35,12 +36,14 @@ public XRDepthMotionPass(RenderPassEvent evt, Shader xrMotionVector) m_XRMotionVectorColor = null; xrMotionVectorDepth = TextureHandle.nullHandle; m_XRMotionVectorDepth = null; + m_transparentlayerMask = transparentLayerMask; } private const int k_XRViewCountPerPass = 2; private class PassData { internal RendererListHandle objMotionRendererList; + internal RendererListHandle objTransparentMotionRendererList; internal Matrix4x4[] previousViewProjectionStereo = new Matrix4x4[k_XRViewCountPerPass]; internal Matrix4x4[] viewProjectionStereo = new Matrix4x4[k_XRViewCountPerPass]; internal Material xrMotionVector; @@ -57,9 +60,9 @@ private class PassData // Motion Vector private Material m_XRMotionVectorMaterial; - private static DrawingSettings GetObjectMotionDrawingSettings(Camera camera) + private static DrawingSettings GetObjectMotionDrawingSettings(Camera camera, bool isTransparent = false) { - var sortingSettings = new SortingSettings(camera) { criteria = SortingCriteria.CommonOpaque }; + var sortingSettings = new SortingSettings(camera) { criteria = isTransparent ? SortingCriteria.CommonTransparent : SortingCriteria.CommonOpaque }; // Notes: Usually, PerObjectData.MotionVectors will filter the renderer nodes to only draw moving objects. // In our case, we use forceAllMotionVectorObjects in the filteringSettings to draw idle objects as well to populate depth. var drawingSettings = new DrawingSettings(k_MotionOnlyShaderTagId, sortingSettings) @@ -77,8 +80,6 @@ private void InitObjectMotionRendererLists(ref PassData passData, ref CullingRes { var objectMotionDrawingSettings = GetObjectMotionDrawingSettings(camera); - // XRTODO: Extend RenderQueueRange.all to support transparent objects? - // URP current' doesn't support this, missing motion override for transparent materials. var filteringSettings = new FilteringSettings(RenderQueueRange.opaque, camera.cullingMask); // Also render game objects that are not moved since last frame to save depth prepass requirement for camera motion. filteringSettings.forceAllMotionVectorObjects = true; @@ -86,6 +87,17 @@ private void InitObjectMotionRendererLists(ref PassData passData, ref CullingRes RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, objectMotionDrawingSettings, filteringSettings, renderStateBlock, ref passData.objMotionRendererList); } + private void InitTransparentObjectMotionRendererLists(ref PassData passData, ref CullingResults cullResults, RenderGraph renderGraph, Camera camera) + { + var objectMotionDrawingSettings = GetObjectMotionDrawingSettings(camera, true); + + var filteringSettings = new FilteringSettings(RenderQueueRange.transparent, m_transparentlayerMask); + // Also render game objects that are not moved since last frame to save depth prepass requirement for camera motion. + filteringSettings.forceAllMotionVectorObjects = true; + var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing); + + RenderingUtils.CreateRendererListWithRenderStateBlock(renderGraph, ref cullResults, objectMotionDrawingSettings, filteringSettings, renderStateBlock, ref passData.objTransparentMotionRendererList); + } /// /// Initialize the RenderGraph pass data. @@ -214,6 +226,8 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) // Setup RendererList InitObjectMotionRendererLists(ref passData, ref renderingData.cullResults, renderGraph, cameraData.camera); builder.UseRendererList(passData.objMotionRendererList); + InitTransparentObjectMotionRendererLists(ref passData, ref renderingData.cullResults, renderGraph, cameraData.camera); + builder.UseRendererList(passData.objTransparentMotionRendererList); // Allow setting up global matrix array builder.AllowGlobalStateModification(true); @@ -235,6 +249,11 @@ internal void Render(RenderGraph renderGraph, ContextContainer frameData) // Fill mv texturew with camera motion for pixels that don't have mv stencil bit. context.cmd.DrawProcedural(Matrix4x4.identity, data.xrMotionVector, 0, MeshTopology.Triangles, 3, 1); + + // Transparent Object Motion for both static and dynamic objects, fill stencil for mv filled pixels. + context.cmd.SetKeyword(ShaderGlobalKeywords.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT, true); + context.cmd.DrawRendererList(passData.objTransparentMotionRendererList); + context.cmd.SetKeyword(ShaderGlobalKeywords.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT, false); }); } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs index c8911530336..b3016bb3ca2 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/PostProcessUtils.cs @@ -284,6 +284,17 @@ internal static Vector4 CalcShaderSourceSize(float width, float height, RenderTe return new Vector4(width, height, 1.0f / width, 1.0f / height); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Vector4 CalcShaderSourceSize(float width, float height, bool useDynamicScale) + { + if (useDynamicScale) + { + width *= ScalableBufferManager.widthScaleFactor; + height *= ScalableBufferManager.heightScaleFactor; + } + return new Vector4(width, height, 1.0f / width, 1.0f / height); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Vector4 CalcShaderSourceSize(RTHandle source) { @@ -295,6 +306,14 @@ internal static void SetGlobalShaderSourceSize(RasterCommandBuffer cmd, float wi cmd.SetGlobalVector(ShaderConstants._SourceSize, CalcShaderSourceSize(width, height, rt)); } + /// + /// Sets the global shader _SourceSize vector from width, height and dynamic scale flag. Use this when no texture/RTHandle is available (e.g. in Render Graph to avoid UseTexture on camera color). + /// + internal static void SetGlobalShaderSourceSize(RasterCommandBuffer cmd, float width, float height, bool useDynamicScale) + { + cmd.SetGlobalVector(ShaderConstants._SourceSize, CalcShaderSourceSize(width, height, useDynamicScale)); + } + internal static void SetGlobalShaderSourceSize(CommandBuffer cmd, float width, float height, RenderTexture rt) { SetGlobalShaderSourceSize(CommandBufferHelpers.GetRasterCommandBuffer(cmd), width, height, rt); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RenderPipelineResources/UniversalRenderPipelineDebugShaders.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RenderPipelineResources/UniversalRenderPipelineDebugShaders.cs index 9c22009a540..3bec01e0021 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RenderPipelineResources/UniversalRenderPipelineDebugShaders.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RenderPipelineResources/UniversalRenderPipelineDebugShaders.cs @@ -8,7 +8,7 @@ namespace UnityEngine.Rendering.Universal /// /// You cannot edit these resources through the editor's UI; use the API for advanced changes. /// Changing this through the API is only allowed in the Editor. In the Player, this raises an error. - /// + /// /// This container is removed for non-development build. /// /// @@ -17,7 +17,7 @@ namespace UnityEngine.Rendering.Universal /// /// using UnityEngine.Rendering; /// using UnityEngine.Rendering.Universal; - /// + /// /// public static class URPUniversalRendererDebugShadersHelper /// { /// public static Shader replacementPS @@ -43,12 +43,7 @@ public class UniversalRenderPipelineDebugShaders : IRenderPipelineResources /// public int version => 0; - bool IRenderPipelineGraphicsSettings.isAvailableInPlayerBuild => -#if DEVELOPMENT_BUILD || UNITY_EDITOR - true; -#else - false; -#endif + bool IRenderPipelineGraphicsSettings.isAvailableInPlayerBuild => true; [SerializeField] [ResourcePath("Shaders/Debug/DebugReplacement.shader")] diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/FullScreenPassRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/FullScreenPassRendererFeature.cs index cb983d4c9d4..a127ee66a2a 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/FullScreenPassRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/FullScreenPassRendererFeature.cs @@ -82,6 +82,17 @@ internal override bool RequireRenderingLayers(bool isDeferred, bool needsGBuffer return false; } + /// + /// Returns true if the combination of settings is compatible with Tile-Only Mode on the Universal Renderer. + /// + internal bool IsCompatibleWithTileOnlyMode() + { + // These checks must match the Tile-Only Mode validation in FullScreenPassRendererFeatureEditor. + if (fetchColorBuffer) + return false; + return RenderingUtils.IsCompatibleWithTileOnlyMode(requirements, (RenderPassEvent)injectionPoint); + } + /// public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { @@ -99,12 +110,20 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD return; } + if (renderer is UniversalRenderer universalRenderer && universalRenderer.useTileOnlyMode && !IsCompatibleWithTileOnlyMode()) + { + Debug.LogErrorFormat( + "Full Screen Renderer Feature \"{0}\": the current settings are not compatible with Tile-Only Mode. Open the Universal Renderer \"{1}\" in the Inspector for more information.", + name, universalRenderer.name); + return; + } + m_FullScreenPass.renderPassEvent = (RenderPassEvent)injectionPoint; m_FullScreenPass.ConfigureInput(requirements); m_FullScreenPass.SetupMembers(passMaterial, passIndex, fetchColorBuffer, bindDepthStencilAttachment); m_FullScreenPass.requiresIntermediateTexture = fetchColorBuffer; - + renderer.EnqueuePass(m_FullScreenPass); } @@ -131,14 +150,14 @@ public void SetupMembers(Material material, int passIndex, bool fetchActiveColor m_BindDepthStencilAttachment = bindDepthStencilAttachment; } - private static void ExecuteMainPass(RasterCommandBuffer cmd, RTHandle sourceTexture, Material material, int passIndex) + private static void ExecuteMainPass(RasterCommandBuffer cmd, RTHandle sourceTexture, Material material, int passIndex, Vector4 blitScaleBias) { s_SharedPropertyBlock.Clear(); if (sourceTexture != null) s_SharedPropertyBlock.SetTexture(ShaderPropertyId.blitTexture, sourceTexture); // We need to set the "_BlitScaleBias" uniform for user materials with shaders relying on core Blit.hlsl to work - s_SharedPropertyBlock.SetVector(ShaderPropertyId.blitScaleBias, new Vector4(1, 1, 0, 0)); + s_SharedPropertyBlock.SetVector(ShaderPropertyId.blitScaleBias, blitScaleBias); cmd.DrawProcedural(Matrix4x4.identity, material, passIndex, MeshTopology.Triangles, 3, 1, s_SharedPropertyBlock); } @@ -150,20 +169,21 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer TextureHandle source, destination; - Debug.Assert(resourcesData.cameraColor.IsValid()); - if (m_FetchActiveColor) { + // The pass requests the intermediate textures so this should always be valid + Debug.Assert(resourcesData.cameraColor.IsValid()); + var targetDesc = renderGraph.GetTextureDesc(resourcesData.cameraColor); targetDesc.name = "_CameraColorFullScreenPass"; targetDesc.clearBuffer = false; - source = resourcesData.activeColorTexture; + source = resourcesData.cameraColor; destination = renderGraph.CreateTexture(targetDesc); renderGraph.AddBlitPass(source, destination, Vector2.one, Vector2.zero, passName: "Copy Color Full Screen"); - //Swap for next pass; + // Swap for next pass; source = destination; } else @@ -171,21 +191,11 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer source = TextureHandle.nullHandle; } + // If resourcesData.isActiveTargetBackBuffer == true, then the backbuffer is alread written to and this could overwrite it. + // However, the user might want to blend into the backbuffer so we allow it here. destination = resourcesData.activeColorTexture; - - // The AddBlitPass utility is not used when m_BindDepthStencilAttachment is active since SetRenderAttachmentDepth is not available with the returned builder of AddBlitPass. - bool useCustomPass = input != ScriptableRenderPassInput.None || m_BindDepthStencilAttachment; - - if (useCustomPass) - { - AddFullscreenRenderPassInputPass(renderGraph, resourcesData, cameraData, source, destination); - } - else - { - var blitMaterialParameters = new BlitMaterialParameters(source, destination, m_Material, m_PassIndex); - - renderGraph.AddBlitPass(blitMaterialParameters, passName: "Blit Color Full Screen"); - } + + AddFullscreenRenderPassInputPass(renderGraph, resourcesData, cameraData, source, destination); } private void AddFullscreenRenderPassInputPass(RenderGraph renderGraph, UniversalResourceData resourcesData, UniversalCameraData cameraData, in TextureHandle source, in TextureHandle destination) @@ -195,10 +205,11 @@ private void AddFullscreenRenderPassInputPass(RenderGraph renderGraph, Universal passData.material = m_Material; passData.passIndex = m_PassIndex; - passData.inputTexture = source; + passData.source = source; + passData.destination = destination; - if (passData.inputTexture.IsValid()) - builder.UseTexture(passData.inputTexture, AccessFlags.Read); + if (passData.source.IsValid()) + builder.UseTexture(passData.source, AccessFlags.Read); bool needsColor = (input & ScriptableRenderPassInput.Color) != ScriptableRenderPassInput.None; bool needsDepth = (input & ScriptableRenderPassInput.Depth) != ScriptableRenderPassInput.None; @@ -243,21 +254,17 @@ private void AddFullscreenRenderPassInputPass(RenderGraph renderGraph, Universal builder.SetRenderFunc(static (MainPassData data, RasterGraphContext rgContext) => { - ExecuteMainPass(rgContext.cmd, data.inputTexture, data.material, data.passIndex); + Vector4 scaleBias = RenderingUtils.GetFinalBlitScaleBias(rgContext, in data.source, in data.destination); + ExecuteMainPass(rgContext.cmd, data.source, data.material, data.passIndex, scaleBias); }); } } - - private class CopyPassData - { - internal TextureHandle inputTexture; - } - private class MainPassData { internal Material material; internal int passIndex; - internal TextureHandle inputTexture; + internal TextureHandle source; + internal TextureHandle destination; } } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessFeature.cs index a9353ca6a54..0f5f3434637 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessFeature.cs @@ -1,24 +1,18 @@ -using System.IO; -using UnityEditor; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; -using UnityEngine.Experimental.Rendering; -using UnityEngine.Rendering.RenderGraphModule; using UnityEngine.Rendering.Universal.Internal; /// /// The class for the On-Tile Post Processing renderer feature. This renderer feature provides a reduced scope alternative to the built-in URP post-processing features but that can run more optimally on tile-based graphics hardware (most untethered-XR devices) /// The renderer feature could only be added once. Adding multiple post processing passes is currently not supported. /// -[DisallowMultipleRendererFeature("On Tile Post Processing (Untethered XR)")] +[DisallowMultipleRendererFeature("On Tile Post Processing")] public partial class OnTilePostProcessFeature : ScriptableRendererFeature { [SerializeField, HideInInspector] PostProcessData m_PostProcessData; - Shader m_UberPostShader; - /// /// Specifies at which injection point the pass will be rendered. /// @@ -30,7 +24,7 @@ public partial class OnTilePostProcessFeature : ScriptableRendererFeature bool TryLoadResources() { - if (m_UberPostShader == null || m_OnTilePostProcessMaterial == null) + if (m_OnTilePostProcessMaterial == null) { if (!GraphicsSettings.TryGetRenderPipelineSettings(out var resources)) { @@ -39,10 +33,18 @@ bool TryLoadResources() return false; } - m_UberPostShader = resources.uberPostShader; - m_OnTilePostProcessMaterial = new Material(m_UberPostShader); - } + var uberPostShader = resources.uberPostShader; + + if (uberPostShader == null || !uberPostShader.isSupported) + { + Debug.LogErrorFormat( + $"Couldn't not create a supported shader for {nameof(OnTilePostProcessFeature)} render feature."); + return false; + } + m_OnTilePostProcessMaterial = new Material(uberPostShader); + } + return true; } @@ -56,60 +58,32 @@ public override void Create() #endif } - if (m_PostProcessData != null) - { - m_ColorGradingLutPass = new ColorGradingLutPass(RenderPassEvent.BeforeRenderingPrePasses, m_PostProcessData); - m_OnTilePostProcessPass = new OnTilePostProcessPass(m_PostProcessData); - // On-tile PP requries memoryless intermediate texture to work. In case intermediate texture is not memoryless, on-tile PP will falls back to offtile rendering. - m_OnTilePostProcessPass.requiresIntermediateTexture = true; - } - } - -#if ENABLE_VR && ENABLE_XR_MODULE - bool IsRuntimePlatformUntetheredXR() - { - // Return true if the current runtime platform is Android(untethered XR platform) - return Application.platform == RuntimePlatform.Android; - } - -#if UNITY_EDITOR - bool IsBuildTargetUntetheredXR() - { - // Return true if the current build target is Android(untethered XR platform). - return EditorUserBuildSettings.activeBuildTarget == BuildTarget.Android; + if (m_PostProcessData == null) + { + Debug.LogError($"{nameof(OnTilePostProcessFeature)} does not have a valid postProcessData instance."); + return; + } + + m_ColorGradingLutPass = new ColorGradingLutPass(RenderPassEvent.BeforeRenderingPrePasses, m_PostProcessData); + m_OnTilePostProcessPass = new OnTilePostProcessPass(m_PostProcessData); + // On-tile PP requires memoryless intermediate texture to work. In case intermediate texture is not memoryless, on-tile PP will falls back to off-tile rendering. + m_OnTilePostProcessPass.requiresIntermediateTexture = true; + + supportedRenderingFeatures.supportsHDR = true; + supportedRenderingFeatures.postProcessing = true; } -#endif -#endif /// public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { - bool useFallback = true; - -#if ENABLE_VR && ENABLE_XR_MODULE - // Enable on-tile post processing when running untethered XR - if (renderingData.cameraData.xr.enabled && IsRuntimePlatformUntetheredXR()) - { - useFallback = false; - } - -#if UNITY_EDITOR - // Enable on-tile post processing when running XR Editor Playmode (build target needs to be Android) - if (renderingData.cameraData.xr.enabled && IsBuildTargetUntetheredXR()) - { - useFallback = false; - } -#endif -#endif - - // Post processing needs to be enabled on the camera + // Post processing needs to be enabled on the camera. if (!renderingData.cameraData.postProcessEnabled) return; // NOTE: Ideally, we check here if the Post Processing is enabled on the UniversalRenderer asset through a public API. In that case, the built in post processing will be enabled. - // We currently do not have a public API for that, so we use internal API for now + // We currently do not have a public API for that, so we use internal API for now. var universalRenderer = renderer as UniversalRenderer; - if (universalRenderer.isPostProcessActive) + if (universalRenderer.postProcessEnabled) { Debug.LogError("URP renderer(Universal Renderer Data) has post processing enabled, which conflicts with the On-Tile post processing feature. Only one of the post processing should be enabled. On-Tile post processing feature will not be added."); return; @@ -121,32 +95,11 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD if (!TryLoadResources()) return; - var graphicsDeviceType = SystemInfo.graphicsDeviceType; - var deviceSupportsFbf = graphicsDeviceType == GraphicsDeviceType.Vulkan || graphicsDeviceType == GraphicsDeviceType.Metal || graphicsDeviceType == GraphicsDeviceType.Direct3D12; - if (!deviceSupportsFbf) - { - Debug.LogError("The On-Tile post processing feature is not supported on the graphics devices that don't support frame buffer fetch."); - return; - } - - // Internally force the correct mode we require while this is not a public setting. - UniversalRenderPipeline.renderTextureUVOriginStrategy = RenderTextureUVOriginStrategy.PropagateAttachmentOrientation; - m_ColorGradingLutPass.renderPassEvent = RenderPassEvent.BeforeRenderingPrePasses; m_OnTilePostProcessPass.Setup(ref m_OnTilePostProcessMaterial); m_OnTilePostProcessPass.renderPassEvent = postProcessingEvent; - - if (useFallback) - { - // Perform fallback logic to 1. use texture read(off-tile rendering) and 2. disable the UV origin propagation mode. - m_OnTilePostProcessPass.m_UseTextureReadFallback = true; - UniversalRenderPipeline.renderTextureUVOriginStrategy = RenderTextureUVOriginStrategy.BottomLeft; - } - else - { - m_OnTilePostProcessPass.m_UseTextureReadFallback = false; - } + m_OnTilePostProcessPass.m_UseTextureReadFallback = !universalRenderer.useTileOnlyMode; renderer.EnqueuePass(m_ColorGradingLutPass); renderer.EnqueuePass(m_OnTilePostProcessPass); @@ -155,7 +108,7 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD /// protected override void Dispose(bool disposing) { - // always dispose unmanaged resources + // Always dispose unmanaged resources. m_ColorGradingLutPass?.Cleanup(); } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs index a7b4c7cba9c..56ac604ee9e 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTilePostProcessPass.cs @@ -1,10 +1,8 @@ using UnityEngine; using UnityEngine.Rendering.RenderGraphModule; -using UnityEngine.Rendering.RenderGraphModule.Util; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine.Experimental.Rendering; -using UnityEngine.Rendering.Universal.Internal; /// /// Renders the on-tile post-processing stack. @@ -14,7 +12,7 @@ public class OnTilePostProcessPass : ScriptableRenderPass /// /// The override shader to use. /// - internal bool m_UseMultisampleShaderResolve = false; + internal readonly bool k_SupportsMultisampleShaderResolve = false; internal bool m_UseTextureReadFallback = false; RTHandle m_UserLut; @@ -27,17 +25,35 @@ public class OnTilePostProcessPass : ScriptableRenderPass const string m_PassName = "On Tile Post Processing"; const string m_FallbackPassName = "On Tile Post Processing (sampling fallback) "; + int m_PassOnTile, m_PassOnTileMsaa, m_PassTextureSample, m_PassOnTileVis, m_PassOnTileMsaaVis, m_PassTexureSampleVis; + internal OnTilePostProcessPass(PostProcessData postProcessData) { m_PostProcessData = postProcessData; -#if ENABLE_VR && ENABLE_XR_MODULE - m_UseMultisampleShaderResolve = SystemInfo.supportsMultisampledShaderResolve; + +#if ENABLE_VR && ENABLE_XR_MODULE + k_SupportsMultisampleShaderResolve = SystemInfo.supportsMultisampledShaderResolve; #endif } internal void Setup(ref Material onTileUberMaterial) { - m_OnTileUberMaterial = onTileUberMaterial; + Debug.Assert(onTileUberMaterial != null, "The material set in OnTilePostProcessPass can't be null."); + + if (m_OnTileUberMaterial == null) + { + m_OnTileUberMaterial = onTileUberMaterial; + + // We just do this once, assuming the shader never changes. + m_PassOnTile = onTileUberMaterial.FindPass("OnTileUberPost"); + m_PassOnTileMsaa = onTileUberMaterial.FindPass("OnTileUberPostMSSoftware"); + m_PassTextureSample = onTileUberMaterial.FindPass("OnTileUberPostTextureSample"); + m_PassOnTileVis = onTileUberMaterial.FindPass("OnTileUberPostVisMesh"); + m_PassOnTileMsaaVis = onTileUberMaterial.FindPass("OnTileUberPostMSSoftwareVisMesh"); + m_PassTexureSampleVis = onTileUberMaterial.FindPass("OnTileUberPostTextureSampleVisMesh"); + } + + m_OnTileUberMaterial = onTileUberMaterial; } /// @@ -52,7 +68,7 @@ public void Dispose() /// public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { - if (m_OnTileUberMaterial == null) return; + Debug.Assert(m_OnTileUberMaterial != null, "The material set in OnTilePostProcessPass can't be null."); var resourceData = frameData.Get(); var renderingData = frameData.Get(); @@ -81,9 +97,15 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer #endif TextureHandle source = resourceData.activeColorTexture; - TextureDesc srcDesc = renderGraph.GetTextureDesc(source); ; - + TextureDesc srcDesc = renderGraph.GetTextureDesc(source); + + TextureHandle destination = resourceData.backBufferColor; + var destInfo = renderGraph.GetRenderTargetInfo(destination); + + // This signals to URP (or the next pass) that rendering has switched to the backbuffer. URP will therefore not add the final blit pass. + // The code below can then also use resourceData.isActiveTargetBackBuffer correctly for robustness. + resourceData.SwitchActiveTexturesToBackbuffer(); SetupVignette(m_OnTileUberMaterial, cameraData.xr, srcDesc.width, srcDesc.height, vignette); SetupLut(m_OnTileUberMaterial, colorLookup, colorAdjustments, lutSize); @@ -91,95 +113,46 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer SetupGrain(m_OnTileUberMaterial, cameraData, filmgrain, m_PostProcessData); SetupDithering(m_OnTileUberMaterial, cameraData, m_PostProcessData); + CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.LinearToSRGBConversion, cameraData.requireSrgbConversion); + CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.UseFastSRGBLinearConversion, postProcessingData.useFastSRGBLinearConversion); CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings._ENABLE_ALPHA_OUTPUT, cameraData.isAlphaOutputEnabled); - UberShaderPasses shaderPass = useVisibilityMesh ? UberShaderPasses.NormalVisMesh : UberShaderPasses.Normal; -#if ENABLE_VR && ENABLE_XR_MODULE - bool setMultisamplesShaderResolveFeatureFlag = false; -#endif - if (srcDesc.msaaSamples != MSAASamples.None) - { - if (srcDesc.msaaSamples == MSAASamples.MSAA8x) - { - Debug.LogError("MSAA8x is enabled in Universal Render Pipeline Asset but it is not supported by the on-tile post-processing feature yet. Please use MSAA4x or MSAA2x instead."); - return; - } + int shaderPass; - var destInfo = renderGraph.GetRenderTargetInfo(destination); - -#if ENABLE_VR && ENABLE_XR_MODULE - if (m_UseMultisampleShaderResolve) - { - // If we have support for msaa shader resolve we can do MSAA -> non MSAA in our render pass. - shaderPass = useVisibilityMesh ? UberShaderPasses.MSAASoftwareResolveVisMesh : UberShaderPasses.MSAASoftwareResolve; - - // When rendering into the backbuffer, we could enable the shader resolve extension to resolve into the msaa1x surface directly on platforms that support auto resolve. - // For platforms that don't support auto resolve, the backbuffer is a multisampled surface and we don't need to enable the extension. This is to maximize the pass merging because shader resolve enabled pass has to be the last subpass. - if (SystemInfo.supportsMultisampleAutoResolve) - { - - setMultisamplesShaderResolveFeatureFlag = true; - } - } - else -#endif - { - if (destInfo.msaaSamples == (int)srcDesc.msaaSamples) - { - // If we have MSAA -> MSAA we can still resolve in the shader running at fragmnet rate - // and the hardware resolve will sometimes be optimized as a result. - shaderPass = useVisibilityMesh ? UberShaderPasses.MSAASoftwareResolveVisMesh : UberShaderPasses.MSAASoftwareResolve; - } - else - { - // We are going MSAA -> Non MSAA without shader resolve support which is not a valid render pass - // configuration. So we need to force a resolve before running our shader which will cause us not - // to be on tile anymore. - shaderPass = useVisibilityMesh ? UberShaderPasses.TextureReadVisMesh : UberShaderPasses.TextureRead; - } - } - } - - // Fallback to texture read mode when requested. if (m_UseTextureReadFallback) { - shaderPass = useVisibilityMesh ? UberShaderPasses.TextureReadVisMesh : UberShaderPasses.TextureRead; -#if ENABLE_VR && ENABLE_XR_MODULE - setMultisamplesShaderResolveFeatureFlag = false; -#endif + shaderPass = useVisibilityMesh ? m_PassTexureSampleVis : m_PassTextureSample; } - - // Fallback logic to handle the case where Frame Buffer Fetch is not compatible with the pass setup. - TextureDesc destDesc; - var info = renderGraph.GetRenderTargetInfo(destination); - destDesc = new TextureDesc(info.width, info.height); - destDesc.format = info.format; - destDesc.msaaSamples = (MSAASamples)info.msaaSamples; - destDesc.bindTextureMS = info.bindMS; - destDesc.slices = info.volumeDepth; - destDesc.dimension = info.volumeDepth > 1 ? TextureDimension.Tex2DArray : TextureDimension.Tex2D; - - // Falls back to texture read mode if texture dimension does not match between source and destination (invalid frame buffer fetch setup). - if (srcDesc.width != destDesc.width || srcDesc.height != destDesc.height || srcDesc.slices != destDesc.slices) + else { - shaderPass = useVisibilityMesh ? UberShaderPasses.TextureReadVisMesh : UberShaderPasses.TextureRead; -#if ENABLE_VR && ENABLE_XR_MODULE - setMultisamplesShaderResolveFeatureFlag = false; -#endif + Debug.Assert(srcDesc.width == destInfo.width && srcDesc.height == destInfo.height && srcDesc.slices == destInfo.volumeDepth + , "On Tile Post Processing expects the source and destination to have the same dimensions."); + + switch (srcDesc.msaaSamples) + { + case MSAASamples.None: + shaderPass = useVisibilityMesh ? m_PassOnTileVis : m_PassOnTile; + break; + case MSAASamples.MSAA8x: + Debug.LogError("MSAA8x is enabled in Universal Render Pipeline Asset but it is not supported by the on-tile post-processing feature yet. Please use MSAA4x or MSAA2x instead."); + return; + default: + shaderPass = useVisibilityMesh ? m_PassOnTileMsaaVis: m_PassOnTileMsaa; + break; + } } var lutTexture = resourceData.internalColorLut; var passName = m_UseTextureReadFallback ? m_FallbackPassName : m_PassName; using (var builder = renderGraph.AddRasterRenderPass(passName, out var passData)) - { - passData.source = source; - passData.destination = destination; + { passData.material = m_OnTileUberMaterial; passData.shaderPass = shaderPass; + passData.useTextureReadFallback = m_UseTextureReadFallback; - if (shaderPass == UberShaderPasses.TextureRead || shaderPass == UberShaderPasses.TextureReadVisMesh) + if (m_UseTextureReadFallback) { - builder.UseTexture(source, AccessFlags.Read); + builder.UseTexture(passData.source = source, AccessFlags.Read); } else { @@ -198,48 +171,41 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.UseTexture(userLutTexture, AccessFlags.Read); } - builder.SetRenderAttachment(destination, 0, AccessFlags.WriteAll); + builder.SetRenderAttachment(passData.destination = destination, 0, AccessFlags.WriteAll); builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => ExecuteFBFetchPass(data, context)); - passData.useXRVisibilityMesh = false; + passData.useXRVisibilityMesh = useVisibilityMesh; passData.msaaSamples = (int)srcDesc.msaaSamples; + // When rendering into the backbuffer, we could enable the shader resolve extension to resolve into the msaa1x surface directly on platforms that support auto resolve. + // For platforms that don't support auto resolve, the backbuffer is a multisampled surface and we don't need to enable the extension. This is to maximize the pass merging because shader resolve enabled pass has to be the last subpass. + bool useMultisampledShaderResolve = (int)srcDesc.msaaSamples > destInfo.msaaSamples && k_SupportsMultisampleShaderResolve; + + ExtendedFeatureFlags featureFlags = ExtendedFeatureFlags.None; + + if (useMultisampledShaderResolve) + { + featureFlags |= ExtendedFeatureFlags.MultisampledShaderResolve; + } + #if ENABLE_VR && ENABLE_XR_MODULE if (cameraData.xr.enabled) { - ExtendedFeatureFlags xrFeatureFlag = ExtendedFeatureFlags.MultiviewRenderRegionsCompatible; - if (setMultisamplesShaderResolveFeatureFlag) - { - xrFeatureFlag |= ExtendedFeatureFlags.MultisampledShaderResolve; - } - builder.SetExtendedFeatureFlags(xrFeatureFlag); + featureFlags |= ExtendedFeatureFlags.MultiviewRenderRegionsCompatible; // We want our foveation logic to match other geometry passes(eg. Opaque, Transparent, Skybox) because we want to merge with previous passes. bool passSupportsFoveation = cameraData.xrUniversal.canFoveateIntermediatePasses || resourceData.isActiveTargetBackBuffer; builder.EnableFoveatedRasterization( cameraData.xr.supportsFoveatedRendering && passSupportsFoveation); - passData.useXRVisibilityMesh = useVisibilityMesh; passData.xr = cameraData.xr; // Need to pass this down for the method call RenderVisibleMeshCustomMaterial() } #endif - } + builder.SetExtendedFeatureFlags(featureFlags); - //This will prevent the final blit pass from being added/needed (still internal API in trunk) - resourceData.activeColorID = UniversalResourceData.ActiveID.BackBuffer; - resourceData.activeDepthID = UniversalResourceData.ActiveID.BackBuffer; + } } - enum UberShaderPasses - { - Normal, - MSAASoftwareResolve, - TextureRead, - NormalVisMesh, - MSAASoftwareResolveVisMesh, - TextureReadVisMesh, - }; - // This static method is used to execute the pass and passed as the RenderFunc delegate to the RenderGraph render pass static void ExecuteFBFetchPass(PassData data, RasterGraphContext context) { @@ -249,15 +215,16 @@ static void ExecuteFBFetchPass(PassData data, RasterGraphContext context) if (data.userLutTexture.IsValid()) data.material.SetTexture(ShaderConstants._UserLut, data.userLutTexture); - bool IsHandleYFlipped = RenderingUtils.IsHandleYFlipped(context, in data.destination); + bool flip = context.GetTextureUVOrigin(data.source) != context.GetTextureUVOrigin(data.destination); + // We need to set the "_BlitScaleBias" uniform for user materials with shaders relying on core Blit.hlsl to work - data.material.SetVector(s_BlitScaleBias, !IsHandleYFlipped ? new Vector4(1, -1, 0, 1) : new Vector4(1, 1, 0, 0)); + data.material.SetVector(s_BlitScaleBias, flip ? new Vector4(1, -1, 0, 1) : new Vector4(1, 1, 0, 0)); - if (data.shaderPass == UberShaderPasses.TextureRead || data.shaderPass == UberShaderPasses.TextureReadVisMesh) + if (data.useTextureReadFallback) { data.material.SetTexture(s_BlitTexture, data.source); } - else if (data.shaderPass == UberShaderPasses.MSAASoftwareResolve || data.shaderPass == UberShaderPasses.MSAASoftwareResolveVisMesh) + else { // Setup MSAA samples switch (data.msaaSamples) @@ -301,11 +268,12 @@ private class PassData internal TextureHandle lutTexture; internal TextureHandle userLutTexture; internal Material material; - internal UberShaderPasses shaderPass; + internal int shaderPass; internal Vector4 scaleBias; internal bool useXRVisibilityMesh; internal XRPass xr; internal int msaaSamples; + internal bool useTextureReadFallback; } TextureHandle TryGetCachedUserLutTextureHandle(ColorLookup colorLookup, RenderGraph renderGraph) @@ -388,24 +356,29 @@ void SetupVignette(Material material, XRPass xrPass, int width, int height, Vign private void SetupTonemapping(Material onTileUberMaterial, Tonemapping tonemapping, bool isHdrGrading) { - if (isHdrGrading) - { - CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.HDRGrading, isHdrGrading); - } - else + CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.HDRGrading, isHdrGrading); + + if (!isHdrGrading) { CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.TonemapNeutral, tonemapping.mode.value == TonemappingMode.Neutral); CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.TonemapACES, tonemapping.mode.value == TonemappingMode.ACES); } + else + { + CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.TonemapNeutral, false); + CoreUtils.SetKeyword(m_OnTileUberMaterial, ShaderKeywordStrings.TonemapACES, false); + } } void SetupGrain(Material onTileUberMaterial, UniversalCameraData cameraData, FilmGrain filmgrain, PostProcessData data) { - if (filmgrain.IsActive()) + bool isActive = filmgrain.IsActive(); + CoreUtils.SetKeyword(onTileUberMaterial, ShaderKeywordStrings.FilmGrain, isActive); + + if (isActive) { - onTileUberMaterial.EnableKeyword(ShaderKeywordStrings.FilmGrain); PostProcessUtils.ConfigureFilmGrain( data, filmgrain, @@ -417,9 +390,10 @@ void SetupGrain(Material onTileUberMaterial, UniversalCameraData cameraData, Fil void SetupDithering(Material onTileUberMaterial, UniversalCameraData cameraData, PostProcessData data) { + CoreUtils.SetKeyword(onTileUberMaterial, ShaderKeywordStrings.Dithering, cameraData.isDitheringEnabled); + if (cameraData.isDitheringEnabled) { - onTileUberMaterial.EnableKeyword(ShaderKeywordStrings.Dithering); m_DitheringTextureIndex = PostProcessUtils.ConfigureDithering( data, m_DitheringTextureIndex, diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader index 4b3eb37127f..3d4e8497585 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/OnTileUberPost.shader @@ -4,6 +4,8 @@ Shader "OnTileUberPost" #pragma multi_compile_local_fragment _ _HDR_GRADING _TONEMAP_ACES _TONEMAP_NEUTRAL #pragma multi_compile_local_fragment _ _FILM_GRAIN #pragma multi_compile_local_fragment _ _DITHERING + #pragma multi_compile_local_fragment _ _GAMMA_20 _LINEAR_TO_SRGB_CONVERSION + #pragma multi_compile_local_fragment _ _USE_FAST_SRGB_LINEAR_CONVERSION #pragma multi_compile_local_fragment _ _ENABLE_ALPHA_OUTPUT #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" @@ -73,6 +75,14 @@ Shader "OnTileUberPost" { half3 color = inputColor.rgb; + // Gamma space... Just do the rest of Uber in linear and convert back to sRGB at the end + #if UNITY_COLORSPACE_GAMMA + { + color = GetSRGBToLinear(color); + inputColor = GetSRGBToLinear(inputColor); + } + #endif + // To save on variants we use an uniform branch for vignette. This may have performance impact on lower end platforms UNITY_BRANCH if (VignetteIntensity > 0) @@ -97,12 +107,26 @@ Shader "OnTileUberPost" } #endif + // When Unity is configured to use gamma color encoding, we ignore the request to convert to gamma 2.0 and instead fall back to sRGB encoding + #if _GAMMA_20 && !UNITY_COLORSPACE_GAMMA + { + color = LinearToGamma20(color); + inputColor = LinearToGamma20(inputColor); + } + // Back to sRGB + #elif UNITY_COLORSPACE_GAMMA || _LINEAR_TO_SRGB_CONVERSION + { + color = GetLinearToSRGB(color); + inputColor = LinearToSRGB(inputColor); + } + #endif + #if _DITHERING { color = ApplyDithering(color, uv, TEXTURE2D_ARGS(_BlueNoise_Texture, sampler_PointRepeat), DitheringScale, DitheringOffset, PaperWhite, OneOverPaperWhite); } #endif - + #if _ENABLE_ALPHA_OUTPUT // Saturate is necessary to avoid issues when additive blending pushes the alpha over 1. return half4(color, saturate(inputColor.a)); @@ -110,6 +134,20 @@ Shader "OnTileUberPost" return half4(color, 1); #endif } + + // Fallback shader to use when we can't keep things on tile, so usually in the editor when dealing with + // MSAA source targets to a non MSAA destination we can't perform a software resolve in the shader and + // so have to fall back to resolving the color target and reading it in as a texture. + // Where we have a MSAA destination we can avoid this. + half4 FragUberPostTextureSample(Varyings input) : SV_Target0 + { + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.texcoord)); + half4 inputColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv); + return UberPost(inputColor, uv); + } + ENDHLSL SubShader @@ -199,29 +237,13 @@ Shader "OnTileUberPost" Pass { - Name "OnTileUberPostTextureReadVersion" + Name "OnTileUberPostTextureSample" LOD 100 ZTest Always ZWrite Off Cull Off HLSLPROGRAM #pragma vertex Vert - #pragma fragment FragUberPostTextureReadVersion - #pragma target 5.0 - #pragma enable_debug_symbols - #pragma debug - - // Fallback shader to use when we can't keep things on tile, so usually in the editor when dealing with - // MSAA source targets to a non MSAA destination we can't perform a software resolve in the shader and - // so have to fall back to resolving the color target and reading it in as a texture. - // Where we have a MSAA destination we can avoid this. - half4 FragUberPostTextureReadVersion(Varyings input) : SV_Target0 - { - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); - - float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.texcoord)); - half4 inputColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv); - return UberPost(inputColor, uv); - } + #pragma fragment FragUberPostTextureSample ENDHLSL } @@ -311,29 +333,33 @@ Shader "OnTileUberPost" Pass { - Name "OnTileUberPostTextureReadVersionVisMesh" + Name "OnTileUberPostTextureSampleVisMesh" LOD 100 ZTest Always ZWrite Off Cull Off HLSLPROGRAM #include "Packages/com.unity.render-pipelines.universal/Shaders/XR/XRVisibilityMeshHelper.hlsl" #pragma vertex VertVisibilityMeshXR - #pragma fragment FragUberPostTextureReadVersion + #pragma fragment FragUberPostTextureSample #pragma target 5.0 - #pragma debug + ENDHLSL + } + } - // Fallback shader to use when we can't keep things on tile, so usually in the editor when dealing with - // MSAA source targets to a non MSAA destination we can't perform a software resolve in the shader and - // so have to fall back to resolving the color target and reading it in as a texture. - // Where we have a MSAA destination we can avoid this. - half4 FragUberPostTextureReadVersion(Varyings input) : SV_Target0 - { - UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + //Supported subshader for WebGL + SubShader + { + Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"} - float2 uv = SCREEN_COORD_APPLY_SCALEBIAS(UnityStereoTransformScreenSpaceTex(input.texcoord)); - half4 inputColor = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv); - return UberPost(inputColor, uv); - } + Pass + { + Name "OnTileUberPostTextureSample" + LOD 100 + ZTest Always ZWrite Off Cull Off + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FragUberPostTextureSample ENDHLSL } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs index aeb93976adf..cd756e945d8 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceAmbientOcclusion.cs @@ -171,7 +171,50 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD if (!TryPrepareResources()) return; - bool shouldAdd = m_SSAOPass.Setup(m_Settings, renderer, m_Material, m_BlueNoise256Textures); + bool usesDeferred = renderer is UniversalRenderer { usesDeferredLighting: true }; + ScriptableRenderPassInput requirements; + RenderPassEvent passEvent; + if (usesDeferred) + { + passEvent = m_Settings.AfterOpaque ? RenderPassEvent.AfterRenderingOpaques : RenderPassEvent.AfterRenderingPrePasses; + requirements = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal; + } + else + { + passEvent = m_Settings.AfterOpaque ? RenderPassEvent.BeforeRenderingTransparents : RenderPassEvent.AfterRenderingPrePasses + 1; + requirements = m_Settings.Source == ScreenSpaceAmbientOcclusionSettings.DepthSource.Depth ? ScriptableRenderPassInput.Depth : ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal; + } + + if (renderer is UniversalRenderer universalRenderer && universalRenderer.useTileOnlyMode) + { + if (!RenderingUtils.IsCompatibleWithTileOnlyMode(requirements, passEvent)) + { + Debug.LogErrorFormat( + "Screen Space Ambient Occlusion \"{0}\": the current settings are not compatible with Tile-Only Mode. Open the Universal Renderer \"{1}\" in the Inspector for more information.", + name, renderer.name); + return; + } + + // SSAO-specific: In Tile-Only Mode with After Opaque, Render Graph merges the Blit SSAO pass with + // earlier passes that use the backbuffer (e.g. TopLeft UV origin). The merged pass then stores the + // SSAO occlusion texture with that same origin. Later, the occlusion texture is sampled as a texture + // (blur, etc.) which expects a different UV origin (e.g. BottomLeft), causing "Texture attachment + // Backbuffer depth with uv origin X does not match with texture attachment _SSAO_OcclusionTexture0 + // with uv origin Y". Pass merging is currently too aggressive here, so disallow After Opaque with + // Depth Normals in Tile-Only Mode. + if (m_Settings.AfterOpaque && m_Settings.Source == ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals) + { + Debug.LogErrorFormat( + "Screen Space Ambient Occlusion \"{0}\": the current settings are not compatible with Tile-Only Mode. Open the Universal Renderer \"{1}\" in the Inspector for more information.", + name, renderer.name); + return; + } + } + + m_SSAOPass.renderPassEvent = passEvent; + m_SSAOPass.ConfigureInput(requirements); + var effectiveDepthSource = usesDeferred ? ScreenSpaceAmbientOcclusionSettings.DepthSource.DepthNormals : m_Settings.Source; + bool shouldAdd = m_SSAOPass.Setup(m_Settings, effectiveDepthSource, m_Material, m_BlueNoise256Textures); if (shouldAdd) renderer.EnqueuePass(m_SSAOPass); } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature.meta new file mode 100644 index 00000000000..a6a7e6066c9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b697a9bf7423546468db3365e062400a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/.001-screen-space-reflection-decisions.md b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/.001-screen-space-reflection-decisions.md new file mode 100644 index 00000000000..8a9a231d3d1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/.001-screen-space-reflection-decisions.md @@ -0,0 +1,146 @@ +# SSR in URP Architecture Decision Record + +Date Created: May 2, 2025 +Last Updated: December 09, 2025 +Author: Kasper Engelstoft + +1\. Context +URP (Universal Render Pipeline) lacked support for dynamic Screen Space Reflections (SSR). Both the Built-in pipeline and HDRP support SSR, but with divergent implementations. +The goal is that SSR in URP is performant, scalable and suitable for a wide range of platforms (from Switch and mobile to high-end consoles) and rendering paths while aligning with Unity’s broader render pipeline unification efforts. + +Key requirements and constraints: + +* Support all render loops : forward, forward+, deferred and deferred+. +* Support XR +* Deliver high performance and configurable quality, with optimizations for low-end hardware. +* Support rough/glossy reflections, transparency, and fallback to reflection probes and global environment probe. +* Integrate with Unity’s Volume framework for parameter blending. +* Provide a flexible, scalable solution with presets (low, medium, high, custom). +* Minimize UX divergence from HDRP and maximize code reuse where feasible. + +--- + +## 2\. Decisions + +### 2.1 SSR Integration + +* SSR is delivered as a Renderer Feature in URP. Integration points: + * Can be run as a post-process pass (After Opaque) or before the main shading pass (integrated into the light loop, Before Opaque). + * The code paths have different performance/quality trade-offs. + +### 2.2 Ray Marching + +* Both hierarchical (HiZ/depth pyramid) and fixed-step (linear) ray marching are supported. + * HiZ is recommended for high-end/desktop + * Linear is recommended for low-end/mobile. + * Bisection/binary search is available as a refinement step. + * The user can select via Volume settings. + +### 2.3 Rough/Glossy Reflections + +* A color pyramid MIP chain (generated using Gaussian or the driver provided box blur) is generated for rough reflection lookup. + * Roughness-to-mip-level heuristics are based on Filament, Godot, and Frostbite research. +* Roughness is packed into the alpha channel of the DepthNormals texture (deferred/forward). + * This is a change to the DepthNormals prepass. + * For forward, DepthNormals is always enabled if SSR is present. +* Stochastic SSR using multiple rays and denoising is an expensive technique and doesn’t fit the platform reach of URP. Physically based reflections will be added to URP later as part of the realtime GI program. + +### 2.4 Transparency + +* SSR supports transparent objects via a secondary depth buffer. +* Reflection on transparent objects is supported, with caveats noted in the UI/tooltips. + +### 2.5 Temporal Reprojection + +* Temporal reprojection is available (in the Before Opaque path), using motion vectors and last-frame color. +* AfterOpaque mode does not use motion vectors. + +### 2.6 Fallbacks + +* SSR uses the reflection hierarchy when on ray misses. The fallback first samples local reflection probes and then the global reflection probe. +* A constant color fallback can be achieved using a local ReflectionProbe set to Custom with a 1x1 color texture. +* "Reflect Sky" toggle allows for capturing sky reflections. + +### 2.7 Upscaling and Performance + +* SSR can be run at full, half, or quarter resolution. +* Edge-aware upscaling (bilateral, Kawase, etc.) is available, but simple upscaling is recommended for low-end. +* Early-out in shader disables SSR for fully rough pixels. +* Multiple performance presets are available, and settings are grouped by quality/performance impact. + +### 2.8 Volume Framework Integration + +* All user-facing SSR settings are exposed as Volume overrides, with the exception of a few renderer feature toggles (e.g. AfterOpaque, Respect HDR). +* Presets (Fast, Balanced, High, Best) are provided; custom settings are also supported. + +### 2.9 Platform and Render Path Coverage + +* Tested on metal, DX11, DX12, Vulkan, GLCore, GLES. + * Known issues remain on WebGL, the feature isn’t supported. +* XR, foveated rendering, and dynamic resolution are in scope, with some workarounds and ongoing investigations. +* Performance targets: + * Switch, midrange mobile: ≤4ms (half/quarter-res SSR). + * PS5: ≤2.7ms (full-res SSR). + +### 2.10 Shader Support + +* SSR is supported on: Lit, Complex Lit, Particles Lit, Terrain Lit, SpeedTree8. +* ShaderGraph support is present for Lit SSR materials. + +--- + +## 3\. Consequences + +### Positive Outcomes + +* URP achieves a balanced feature parity with HDRP and built-in for SSR. +* SSR is flexible, scalable, and performant across target platforms. +* Volume-based parameter blending and presets simplify authoring and tuning. +* Code reuse with HDRP for core algorithms (color/depth pyramid, marcher). + +### Trade-offs / Limitations + +* Forward rendering requires a DepthNormals prepass, which may impact performance. +* Some settings required shader variant management and stripping. +* HiZ marching is not always faster, linear stepping can be faster on some platforms/scenes. +* Some features (e.g., contact hardening, specular elongation, per-material disables) are not implemented but can be added in the future. +* Remaining bugs and edge cases (dynamic resolution, WebGL, multi-camera, etc.) are being tracked in Jira. + +--- + +## 4\. Alternatives Considered + +| Alternative | Pros | Cons / Reason Not Chosen | +| :---- | :---- | :---- | +| Realtime cubemap camera reflections | Simple for planar surfaces | Not scalable, not screen-space, perf. | +| Realtime raytracing | Highest quality | Not feasible for many target platforms | +| Porting built-in SSR | Not modern, less flexible, not scalable | | +| Porting HDRP SSR as-is | High quality, shared code | Too complex for URP’s platform reach | +| Per-object SSR (Shiny SSR style) | No mask needed, implicit roughness | More drawcalls, less flexible | + +--- + +## 5\. References + +* [PRD: Screen Space Reflections in URP](https://docs.google.com/document/d/1W7zztONjkkReThoZSySLoCoz984U3bD1BLKTOxXx-A8/edit?tab=t.gyhavq2l84im) +* [\[TDD\] Screen Space Reflections in URP](https://docs.google.com/document/d/1gKrDkFkqiYZ4yigPwiFM8GuE587URxSo-5SjmaHTRz4/edit?tab=t.0#heading=h.vfvplx8fy7nm) +* [Jira Epic: SSR implementation in URP](https://jira.unity3d.com/browse/GFXLIGHT-1542) +* [Tech Analysis Deck](https://docs.google.com/presentation/d/1ge3SHtF6z5o99VaqipsfuPdOssIjvQyaA_ToRslHHDY/edit?slide=id.g308e3868d11_0_52) +* [Slack channel \#temp-team-ssr-in-urp](https://unity.slack.com/archives/C08Q1V7BHPW) +* [Draft PR](https://github.cds.internal.unity3d.com/unity/unity/pull/76006) + +--- + +## 6\. Open Questions & Next Steps + +* How to best handle multi-camera and scene view support? +* Continue to collect feedback from Tech Art and QA, iterate on presets, and update documentation/tooltips. +* Performance pass to squeeze out more performance on mobile. + +--- + +## 7\. Revision History + +* May 2, 2025: Initial draft (Kasper Engelstoft) +* June 11, 2025: Major update with TDD alignment, design/UX feedback, Slack history, and current open issues (SSR team) +* December 09, 2025: Updated status to Final, converted to .md file and added it to the repo (Kasper Engelstoft) \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthNormalOnlyTransparentPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthNormalOnlyTransparentPass.cs new file mode 100644 index 00000000000..684efc3790e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthNormalOnlyTransparentPass.cs @@ -0,0 +1,84 @@ +#if URP_SCREEN_SPACE_REFLECTION +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.RenderGraphModule.Util; + +namespace UnityEngine.Rendering.Universal +{ + // A separate DepthNormal pass that renders only transparents. Used to support transparency in screen space reflections. + internal class ScreenSpaceReflectionDepthNormalOnlyTransparentPass : Internal.DepthNormalOnlyPass + { + static readonly ProfilingSampler m_ProfilingSampler = new ProfilingSampler("SSR Depth Normal Only Transparent"); + + readonly Internal.CopyDepthPass m_CopyDepthPass; + + public ScreenSpaceReflectionDepthNormalOnlyTransparentPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask) + : base(evt, renderQueueRange, layerMask, m_ProfilingSampler) + { + ConfigureInput(ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal); + + if (GraphicsSettings.TryGetRenderPipelineSettings( + out var universalRendererShaders)) + { + //Pass event not used because we call the render function directly. + m_CopyDepthPass = new(RenderPassEvent.AfterRenderingPrePasses, universalRendererShaders.copyDepthPS, false, true, false, "Copy Depth"); + } + else + { + Debug.LogError("Failed to create the copy depth path required for the SSR Depth Normal Only Transparent pass"); + } + } + + public void UpdateRenderPassEvent(RenderPassEvent evt) + { + renderPassEvent = evt; + } + + /// + protected override SortingCriteria GetSortingCriteria(UniversalCameraData cameraData) + { + // Sort for transparent without opaque. + var sortingCriteria = cameraData.defaultOpaqueSortFlags; + sortingCriteria = sortingCriteria & ~SortingCriteria.CommonOpaque | SortingCriteria.CommonTransparent; + return sortingCriteria; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + var resourceData = frameData.Get(); + var cameraData = frameData.Get(); + var ssrData = frameData.GetOrCreate(); + if (!ssrData.depthTransparentTexture.IsValid()) + { + var depthDescriptor = resourceData.cameraDepth.GetDescriptor(renderGraph); + depthDescriptor.msaaSamples = MSAASamples.None; // Depth-Only pass don't use MSAA + depthDescriptor.format = GraphicsFormat.None; + depthDescriptor.depthBufferBits = DepthBits.Depth32; + ssrData.depthTransparentTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, depthDescriptor, "SSRDepthTransparentTexture", false, Color.clear); + } + if (!ssrData.normalTransparentTexture.IsValid()) + { + var normalDescriptor = resourceData.cameraNormalsTexture.GetDescriptor(renderGraph); + normalDescriptor.msaaSamples = MSAASamples.None; // Never use MSAA for the normal texture! + normalDescriptor.format = GetGraphicsFormat(); + normalDescriptor.depthBufferBits = DepthBits.None; + ssrData.normalTransparentTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, normalDescriptor, "SSRNormalTransparentTexture", true, Color.clear); + } + + m_CopyDepthPass.Render(renderGraph, frameData, ssrData.depthTransparentTexture, resourceData.cameraDepthTexture); + renderGraph.AddCopyPass(resourceData.cameraNormalsTexture, ssrData.normalTransparentTexture, "Copy Normal Texture"); + + if (enableRenderingLayers) + { + Debug.LogError("DepthNormalOnlyPass does not support enableRenderingLayers when called as a reusable pass."); + return; + } + + if (ssrData.depthTransparentTexture.IsValid() && ssrData.normalTransparentTexture.IsValid()) + { + Render(renderGraph, frameData, ssrData.normalTransparentTexture, ssrData.depthTransparentTexture, TextureHandle.nullHandle, uint.MaxValue, false, false, false); + } + } + } +} +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthNormalOnlyTransparentPass.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthNormalOnlyTransparentPass.cs.meta new file mode 100644 index 00000000000..c230dc32d25 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionDepthNormalOnlyTransparentPass.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5aa83714c555c924a9a8b60e2608da99 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs new file mode 100644 index 00000000000..091533630a1 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs @@ -0,0 +1,637 @@ +#if URP_SCREEN_SPACE_REFLECTION +using System; +using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering.RenderGraphModule; +using UnityEngine.Rendering.RenderGraphModule.Util; +using static UnityEngine.Rendering.RenderGraphModule.Util.RenderGraphUtils; +using static UnityEngine.Rendering.Universal.ScreenSpaceReflectionVolumeSettings; + +namespace UnityEngine.Rendering.Universal +{ + internal class ScreenSpaceReflectionPass : ScriptableRenderPass + { + public class SharedSSRData : ContextItem + { + // Used for transparency support, outputs from transparency depthnormal prepass + public TextureHandle depthTransparentTexture = TextureHandle.nullHandle; + public TextureHandle normalTransparentTexture = TextureHandle.nullHandle; + + public override void Reset() + { + depthTransparentTexture = TextureHandle.nullHandle; + normalTransparentTexture = TextureHandle.nullHandle; + } + } + + // Enums + private enum ShaderPasses + { + Reflection = 0, // Generate reflected color texture + BlitAfterOpaque = 1, // Blit to screen (only when using After Opaque mode) + + // Bilateral blur passes, 8-12 taps each. + BilateralBlurHorizontal = 2, + BilateralBlurVertical = 3, + BilateralBlurFinal = 4, + + // Gaussian blur passes, 4 taps each + GaussianBlurHorizontal = 5, + GaussianBlurVertical = 6, + + // Single pass kawase blur. + KawaseBlur = 7, + } + + // Constants + const string k_ScreenSpaceReflectionTextureName = "_ScreenSpaceReflectionTexture"; + const string k_HiZTrace = "_HIZ_TRACE"; + const string k_UseMotionVectors = "_USE_MOTION_VECTORS"; + const string k_RefineDepth = "_REFINE_DEPTH"; + + // Statics + internal static class ShaderConstants + { + internal static readonly int _ReflectionParam = Shader.PropertyToID("_ScreenSpaceReflectionParam"); + internal static readonly int _MaxRayLength = Shader.PropertyToID("_MaxRayLength"); + internal static readonly int _MaxRaySteps = Shader.PropertyToID("_MaxRaySteps"); + internal static readonly int _Downsample = Shader.PropertyToID("_Downsample"); + internal static readonly int _ThicknessScaleAndBias = Shader.PropertyToID("_ThicknessScaleAndBias"); + internal static readonly int _ScreenSpaceReflectionFinalTexture = Shader.PropertyToID(k_ScreenSpaceReflectionTextureName); + internal static readonly int _ProjectionParams2 = Shader.PropertyToID("_ProjectionParams2"); + internal static readonly int _CameraProjections = Shader.PropertyToID("_CameraProjections"); + internal static readonly int _CameraInverseProjections = Shader.PropertyToID("_CameraInverseProjections"); + internal static readonly int _CameraInverseViewProjections = Shader.PropertyToID("_CameraInverseViewProjections"); + internal static readonly int _CameraViews = Shader.PropertyToID("_CameraViews"); + internal static readonly int _CameraColorTexture = Shader.PropertyToID("_CameraColorTexture"); + internal static readonly int _CameraDepthTexture = Shader.PropertyToID("_CameraDepthTexture"); + internal static readonly int _CameraNormalsTexture = Shader.PropertyToID("_CameraNormalsTexture"); + internal static readonly int _SmoothnessTexture = Shader.PropertyToID("_SmoothnessTexture"); + internal static readonly int _MotionVectorColorTexture = Shader.PropertyToID("_MotionVectorColorTexture"); + internal static readonly int _SsrDepthPyramidMaxMip = Shader.PropertyToID("_SsrDepthPyramidMaxMip"); + internal static readonly int _SsrDepthPyramid = Shader.PropertyToID("_DepthPyramid"); + internal static readonly int _MinimumSmoothnessAndFadeStart = Shader.PropertyToID("_MinimumSmoothnessAndFadeStart"); + internal static readonly int _ScreenEdgeFadeAndViewConeDot = Shader.PropertyToID("_ScreenEdgeFadeAndViewConeDot"); + internal static readonly int _ReflectSky = Shader.PropertyToID("_ReflectSky"); + internal static readonly int _HitRefinementSteps = Shader.PropertyToID("_HitRefinementSteps"); + internal static readonly int _DepthPyramidMipLevelOffsets = Shader.PropertyToID("_DepthPyramidMipLevelOffsets"); + internal static readonly int _SourceSize = Shader.PropertyToID("_SourceSize"); + } + + // Private Variables + Material m_Material; + LocalKeywordSet m_LocalKeywords; + bool m_AfterOpaque; + + struct LocalKeywordSet + { + public LocalKeyword hiZTraceKeyword; + public LocalKeyword useMotionVectorsKeyword; + public LocalKeyword refineDepthKeyword; + + public void Init(Shader shader) + { + hiZTraceKeyword = new(shader, k_HiZTrace); + useMotionVectorsKeyword = new(shader, k_UseMotionVectors); + refineDepthKeyword = new(shader, k_RefineDepth); + } + }; + + readonly ProfilingSampler m_ProfilingSampler = ProfilingSampler.Get(URPProfileId.SSR); + readonly ProfilingSampler m_DepthPyramidSampler = new("SSR - Depth Pyramid Generation"); + readonly ProfilingSampler m_UpscalingSampler = new("SSR - Upscaling"); + readonly ProfilingSampler m_FinalBlitSampler = new("SSR - Final Blit"); + + MipGenerator m_MipGenerator = new(); + //We need to have this struct as a member in order to only allocate the arrays once. + PackedMipChainInfo m_PackedMipChainInfo; + + public ScreenSpaceReflectionPass() + { + m_PackedMipChainInfo.Allocate(); + } + + public void Dispose() + { + m_MipGenerator.Release(); + } + + internal bool Setup(ScriptableRenderer renderer, Material material, bool afterOpaque, UniversalRenderingData renderingData, CameraType cameraType) + { + m_AfterOpaque = afterOpaque; + + if (m_Material != material) + { + m_Material = material; + if (m_Material != null) + { + m_LocalKeywords.Init(m_Material.shader); + } + } + + var settings = VolumeManager.instance.stack.GetComponent(); + + // Rendering after PrePasses is usually correct except when depth priming is in play: + // then we rely on a depth resolve taking place after the PrePasses in order to have it ready for SSR. + + ScriptableRenderPassInput requiredInputs; + if (renderer is UniversalRenderer { usesDeferredLighting: true }) + { + renderPassEvent = m_AfterOpaque ? (settings.ShouldRenderTransparents() ? RenderPassEvent.AfterRenderingTransparents + 25 : RenderPassEvent.AfterRenderingSkybox + 25) : RenderPassEvent.AfterRenderingPrePasses + 5; + + requiredInputs = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal; + + // Deferred rendering before opaques, need to generate smoothness in depth normals prepass as GBuffer isn't ready yet. + if (!m_AfterOpaque) + renderingData.writesSmoothnessToDepthNormalsAlpha = true; + } + else + { + renderPassEvent = m_AfterOpaque ? (settings.ShouldRenderTransparents() ? RenderPassEvent.AfterRenderingTransparents + 25 : RenderPassEvent.BeforeRenderingTransparents + 25) : RenderPassEvent.AfterRenderingPrePasses + 5; + + // Request DepthNormals texture. + requiredInputs = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal; + + // With forward rendering, we are forced to generate a smoothness in depth normals prepass. + renderingData.writesSmoothnessToDepthNormalsAlpha = true; + } + + // Before opaque needs motion vectors for reprojection. + if (!m_AfterOpaque && (cameraType == CameraType.VR || cameraType == CameraType.Game)) + requiredInputs |= ScriptableRenderPassInput.Motion; + + ConfigureInput(requiredInputs); + + return m_Material != null; + } + + + private class ScreenSpaceReflectionPassData + { + // Camera data. This is not expected to change during a frame. + internal UniversalCameraData cameraData; + internal Matrix4x4[] cameraInverseViewProjections = new Matrix4x4[2]; + internal Matrix4x4[] cameraProjections = new Matrix4x4[2]; + internal Matrix4x4[] cameraInverseProjections = new Matrix4x4[2]; + internal Matrix4x4[] cameraViews = new Matrix4x4[2]; + internal Vector4[] depthPyramidMipOffsets = new Vector4[15]; + + // Material containg SSR pass, and keywords. + internal Material material; + internal LocalKeywordSet localKeywords; + + // MipInfo for HiZ marching. + internal PackedMipChainInfo mipsInfo; + + // Required textures. + internal TextureHandle cameraColor; // Camera target texture. + internal TextureHandle cameraDepth; // Camera depth target texture. + internal TextureHandle cameraNormalsTexture; // Normals. + internal TextureHandle smoothnessTexture; // Texture containing smoothness in the alpha channel. + internal TextureHandle ssrTexture; // Output texture containing reflected colors. + internal TextureHandle blackTexture; // A black fallback texture. + + // Optional textures. + internal TextureHandle lastFrameCameraColor; // Camera target texture from last frame (only needed if AfterOpaque=false). + internal TextureHandle motionVectorColor; // Motion vectors (only needed if AfterOpaque=false). + internal TextureHandle depthPyramidTexture; // Depth pyramid texture for HiZ marching (only needed if LinearMarching=false). + + // Settings. + internal float minimumSmoothness; + internal float smoothnessFadeStart; + internal float normalFade; + internal float screenEdgeFade; + internal float maxRayLength; + internal float rayLengthFade; + internal float thicknessScale; + internal float thicknessBias; + internal float thicknessScaleFine; + internal float thicknessBiasFine; + internal int hitRefinementSteps; + internal int maxRaySteps; + internal int resolutionScale; + internal bool reflectSky; + internal bool afterOpaque; + internal bool linearMarching; + } + + public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) + { + var settings = VolumeManager.instance.stack.GetComponent(); + + UniversalCameraData cameraData = frameData.Get(); + UniversalResourceData resourceData = frameData.Get(); + + // Create the texture handles... + CreateRenderTextureHandles(renderGraph, + resourceData, + settings, + out TextureHandle ssrTexture, + out TextureHandle blurTexture, + out TextureHandle upscaleTexture, + out TextureHandle mipGenTexture, + out TextureHandle finalTexture, + out TextureHandle depthPyramidTexture); + + // Get input resources. + SharedSSRData ssrData = frameData.GetOrCreate(); + TextureHandle cameraDepthTexture = resourceData.cameraDepthTexture; + TextureHandle cameraNormalsTexture = resourceData.cameraNormalsTexture; + TextureHandle cameraColorTexture = resourceData.cameraColor; + TextureHandle motionVectorColorTexture = resourceData.motionVectorColor; + TextureHandle smoothnessTexture = settings.ShouldRenderTransparents() ? ssrData.normalTransparentTexture : cameraNormalsTexture; + if (settings.ShouldRenderTransparents()) + { + cameraDepthTexture = ssrData.depthTransparentTexture; + cameraNormalsTexture = ssrData.normalTransparentTexture; + } + + using (new RenderGraphProfilingScope(renderGraph, m_ProfilingSampler)) + { + if (!settings.ShouldUseLinearMarching()) + { + using (new RenderGraphProfilingScope(renderGraph, m_DepthPyramidSampler)) + { + renderGraph.AddBlitPass(cameraDepthTexture, depthPyramidTexture, new(1f, 2f), Vector2.zero, filterMode: BlitFilterMode.ClampNearest, passName: "Copy depth to mip 0"); + m_PackedMipChainInfo.ComputePackedMipChainInfo(new Vector2Int(cameraData.cameraTargetDescriptor.width / (int)settings.resolution.value, cameraData.cameraTargetDescriptor.height / (int)settings.resolution.value), 0); + m_MipGenerator.RenderMinDepthPyramid(renderGraph, depthPyramidTexture, ref m_PackedMipChainInfo); + } + } + + using (var builder = renderGraph.AddRasterRenderPass("SSR - Main Pass", out var passData)) + { + // Shader keyword changes are considered as global state modifications + builder.AllowGlobalStateModification(true); + + // Set required pass data. + passData.cameraData = cameraData; + passData.afterOpaque = m_AfterOpaque; + passData.linearMarching = settings.ShouldUseLinearMarching(); + passData.minimumSmoothness = settings.minimumSmoothness.value; + passData.smoothnessFadeStart = settings.smoothnessFadeStart.value; + passData.normalFade = settings.normalFade.value; + passData.screenEdgeFade = Mathf.Max(0.001f, settings.screenEdgeFadeDistance.value * 0.5f); + passData.reflectSky = settings.reflectSky.value; + passData.hitRefinementSteps = settings.hitRefinementSteps.value; + passData.maxRayLength = settings.maxRayLength.value; + passData.rayLengthFade = settings.rayLengthFade.value; + passData.maxRaySteps = settings.maxRaySteps.value; + passData.resolutionScale = (int)settings.resolution.value; + passData.material = m_Material; + passData.localKeywords = m_LocalKeywords; + passData.mipsInfo = m_PackedMipChainInfo; + passData.cameraColor = cameraColorTexture; + passData.cameraDepth = cameraDepthTexture; + passData.ssrTexture = ssrTexture; + passData.cameraNormalsTexture = cameraNormalsTexture; + passData.smoothnessTexture = smoothnessTexture; + passData.blackTexture = (TextureXR.slices > 1 && TextureXR.initialized) ? renderGraph.defaultResources.blackTextureXR : renderGraph.defaultResources.blackTexture; + CalculateThicknessScaleAndBias(cameraData.camera.nearClipPlane, cameraData.camera.farClipPlane, settings.objectThickness.value, + out passData.thicknessScale, out passData.thicknessBias); + CalculateThicknessScaleAndBias(cameraData.camera.nearClipPlane, cameraData.camera.farClipPlane, settings.objectThickness.value * settings.finalThicknessMultiplier.value, + out passData.thicknessScaleFine, out passData.thicknessBiasFine); + + // Set optional input textures to black by default. + passData.lastFrameCameraColor = passData.blackTexture; + passData.motionVectorColor = passData.blackTexture; + passData.depthPyramidTexture = passData.blackTexture; + + // Declare required input textures. + builder.SetRenderAttachment(passData.ssrTexture, 0, AccessFlags.ReadWrite); + builder.UseTexture(passData.cameraDepth); + builder.UseTexture(passData.cameraColor); + builder.UseTexture(passData.cameraNormalsTexture); + builder.UseTexture(passData.smoothnessTexture); + builder.UseTexture(passData.blackTexture); + + // If we are using HiZ marching, set the depth pyramid texture. + if (!settings.ShouldUseLinearMarching()) + { + passData.depthPyramidTexture = depthPyramidTexture; + builder.UseTexture(passData.depthPyramidTexture); + } + + // If AfterOpaque=false, set the motion vector and last frame color textures. + // When AfterOpaque=true, we use the current frame color instead, and need no motion vectors. + if (!passData.afterOpaque && cameraData.historyManager != null) + { + int multipassId = 0; +#if ENABLE_VR && ENABLE_XR_MODULE + multipassId = cameraData.xr.multipassId; +#endif + + // If we are rendering transparents in SSR, we want the last frame color to include transparents. + // Otherwise, we want last frame color before rendering transparents. + RTHandle historyTexture; + if (settings.ShouldRenderTransparents()) + { + cameraData.historyManager.RequestAccess(); + RawColorHistory history = cameraData.historyManager.GetHistoryForRead(); + historyTexture = history?.GetPreviousTexture(multipassId); + } + else + { + cameraData.historyManager.RequestAccess(); + BeforeTransparentsColorHistory history = cameraData.historyManager.GetHistoryForRead(); + historyTexture = history?.GetPreviousTexture(multipassId); + } + + if (historyTexture != null) + { + passData.lastFrameCameraColor = renderGraph.ImportTexture(historyTexture); + builder.UseTexture(passData.lastFrameCameraColor); + } + + // We also need motion vectors to reproject. + if (input.HasFlag(ScriptableRenderPassInput.Motion)) + { + passData.motionVectorColor = motionVectorColorTexture; + builder.UseTexture(passData.motionVectorColor); + } + } + + // If running before opaque pass, we need to export the SSR texture as a global uniform, + // so it can be sampled in the opaque pass. + if (!passData.afterOpaque) + { + builder.UseTexture(finalTexture, AccessFlags.ReadWrite); + builder.SetGlobalTextureAfterPass(finalTexture, ShaderConstants._ScreenSpaceReflectionFinalTexture); + } + + builder.SetRenderFunc(static (ssrData, rgContext) => + { + SetupKeywordsAndParameters(ref ssrData); + + var cmd = rgContext.cmd; + ssrData.material.SetVector(ShaderConstants._SourceSize, PostProcessUtils.CalcShaderSourceSize(ssrData.cameraColor)); + + ssrData.material.SetTexture(ShaderConstants._CameraDepthTexture, ssrData.cameraDepth); + if (ssrData.afterOpaque) + ssrData.material.SetTexture(ShaderConstants._CameraColorTexture, ssrData.cameraColor); + // Somehow this texture can be null even when TextureHandle.IsValid() is true, guard against that. + else if (((RTHandle)ssrData.lastFrameCameraColor)?.rt == null) + ssrData.material.SetTexture(ShaderConstants._CameraColorTexture, ssrData.blackTexture); + else + ssrData.material.SetTexture(ShaderConstants._CameraColorTexture, ssrData.lastFrameCameraColor); + + ssrData.material.SetTexture(ShaderConstants._CameraNormalsTexture, ssrData.cameraNormalsTexture); + ssrData.material.SetTexture(ShaderConstants._SmoothnessTexture, ssrData.smoothnessTexture); + ssrData.material.SetTexture(ShaderConstants._MotionVectorColorTexture, ssrData.motionVectorColor); + + // Main SSR Pass + Blitter.BlitTexture(cmd, ssrData.ssrTexture, new Vector4(1, 1, 0, 0), ssrData.material, (int)ShaderPasses.Reflection); + + if (!ssrData.afterOpaque) + { + // We only want URP shaders to sample SSR if After Opaque is disabled... + cmd.SetKeyword(ShaderGlobalKeywords.ScreenSpaceReflection, true); + cmd.SetGlobalVector(ShaderConstants._ReflectionParam, new Vector4(1f, ssrData.minimumSmoothness, ssrData.smoothnessFadeStart, 0f)); + } + }); + } + + // Upscale pass. + TextureHandle fullResSSRTexture = ssrTexture; + using (new RenderGraphProfilingScope(renderGraph, m_UpscalingSampler)) + { + if (settings.resolution != ScreenSpaceReflectionVolumeSettings.Resolution.Full) + { + fullResSSRTexture = upscaleTexture; + + if (settings.upscalingMethod == UpscalingMethod.None) + { + renderGraph.AddBlitPass(ssrTexture, upscaleTexture, Vector2.one, Vector2.zero, passName: "Nearest", filterMode: RenderGraphModule.Util.RenderGraphUtils.BlitFilterMode.ClampNearest); + } + else if (settings.upscalingMethod == UpscalingMethod.Kawase) + { + var blitParam = new BlitMaterialParameters(ssrTexture, upscaleTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.KawaseBlur); + renderGraph.AddBlitPass(blitParam, passName: "KawaseBlur"); + } + else if (settings.upscalingMethod == UpscalingMethod.Gaussian) + { + var blitParam = new BlitMaterialParameters(ssrTexture, blurTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.GaussianBlurHorizontal); + renderGraph.AddBlitPass(blitParam, passName: "GaussianBlurHorizontal"); + blitParam = new BlitMaterialParameters(blurTexture, upscaleTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.GaussianBlurVertical); + renderGraph.AddBlitPass(blitParam, passName: "GaussianBlurVertical"); + } + else if (settings.upscalingMethod == UpscalingMethod.Bilateral) + { + var blitParam = new BlitMaterialParameters(ssrTexture, blurTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.BilateralBlurHorizontal); + renderGraph.AddBlitPass(blitParam, passName: "BilateralBlurHorizontal"); + blitParam = new BlitMaterialParameters(blurTexture, ssrTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.BilateralBlurVertical); + renderGraph.AddBlitPass(blitParam, passName: "BilateralBlurVertical"); + + blitParam = new BlitMaterialParameters(ssrTexture, upscaleTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.BilateralBlurFinal); + renderGraph.AddBlitPass(blitParam, passName: "BilateralBlurFinal"); + } + } + } + + // Final blit pass. + using (new RenderGraphProfilingScope(renderGraph, m_FinalBlitSampler)) + { + var viewportSizeWithScale = new Vector2Int(cameraData.cameraTargetDescriptor.width, cameraData.cameraTargetDescriptor.height); + if (m_AfterOpaque) + { + TextureHandle textureToBlit = fullResSSRTexture; + if (settings.ShouldUseGaussianBlurRoughness()) + { + textureToBlit = mipGenTexture; + m_MipGenerator.RenderColorGaussianPyramid(renderGraph, viewportSizeWithScale, fullResSSRTexture, mipGenTexture); + } + var blitParam = new BlitMaterialParameters(textureToBlit, finalTexture, Vector2.one, Vector2.zero, m_Material, (int)ShaderPasses.BlitAfterOpaque); + renderGraph.AddBlitPass(blitParam, passName: "Final blit"); + } + else + { + if (settings.ShouldUseGaussianBlurRoughness()) + m_MipGenerator.RenderColorGaussianPyramid(renderGraph, viewportSizeWithScale, fullResSSRTexture, finalTexture); + else + { + renderGraph.AddCopyPass(fullResSSRTexture, finalTexture, passName: "Final blit"); + } + } + } + } + } + + static void SetupKeywordsAndParameters(ref ScreenSpaceReflectionPassData data) + { + UniversalCameraData cameraData = data.cameraData; +#if ENABLE_VR && ENABLE_XR_MODULE + int eyeCount = cameraData.xr.enabled && cameraData.xr.singlePassEnabled ? 2 : 1; +#else + int eyeCount = 1; +#endif + for (int eyeIndex = 0; eyeIndex < eyeCount; eyeIndex++) + { + Matrix4x4 view = cameraData.GetViewMatrix(eyeIndex); + Matrix4x4 proj = cameraData.GetGPUProjectionMatrix(true, eyeIndex); + data.cameraProjections[eyeIndex] = proj; + data.cameraInverseProjections[eyeIndex] = proj.inverse; + data.cameraViews[eyeIndex] = view; + data.cameraInverseViewProjections[eyeIndex] = (proj * view).inverse; + } + + data.material.SetVector(ShaderConstants._ProjectionParams2, new Vector4(1.0f / cameraData.camera.nearClipPlane, 0.0f, 0.0f, 0.0f)); + data.material.SetMatrixArray(ShaderConstants._CameraProjections, data.cameraProjections); + data.material.SetMatrixArray(ShaderConstants._CameraInverseProjections, data.cameraInverseProjections); + data.material.SetMatrixArray(ShaderConstants._CameraViews, data.cameraViews); + data.material.SetMatrixArray(ShaderConstants._CameraInverseViewProjections, data.cameraInverseViewProjections); + data.material.SetVector(ShaderConstants._MinimumSmoothnessAndFadeStart, new Vector4(data.minimumSmoothness, data.smoothnessFadeStart)); + data.material.SetVector(ShaderConstants._ScreenEdgeFadeAndViewConeDot, new Vector4(data.screenEdgeFade, 1.0f - data.screenEdgeFade, 2.0f * data.normalFade - 1.0f)); + data.material.SetInteger(ShaderConstants._ReflectSky, data.reflectSky ? 1 : 0); + data.material.SetInteger(ShaderConstants._HitRefinementSteps, data.hitRefinementSteps); + data.material.SetVector(ShaderConstants._MaxRayLength, new Vector4(data.maxRayLength, data.maxRayLength - Math.Max(0.01f, data.rayLengthFade))); + data.material.SetInteger(ShaderConstants._MaxRaySteps, data.maxRaySteps); + data.material.SetInteger(ShaderConstants._Downsample, data.resolutionScale); + data.material.SetVector(ShaderConstants._ThicknessScaleAndBias, new Vector4(data.thicknessScale, data.thicknessBias, data.thicknessScaleFine, data.thicknessBiasFine)); + + if (!data.linearMarching) + { + for (int i = 0; i < data.mipsInfo.mipLevelCount; i++) + { + data.depthPyramidMipOffsets[i] = new Vector4(data.mipsInfo.mipLevelOffsets[i].x, data.mipsInfo.mipLevelOffsets[i].y, 0, 0); + } + + data.material.SetVectorArray(ShaderConstants._DepthPyramidMipLevelOffsets, data.depthPyramidMipOffsets); + data.material.SetInteger(ShaderConstants._SsrDepthPyramidMaxMip, data.mipsInfo.mipLevelCount); + data.material.SetTexture(ShaderConstants._SsrDepthPyramid, data.depthPyramidTexture); + } + + CoreUtils.SetKeyword(data.material, data.localKeywords.hiZTraceKeyword, !data.linearMarching); + CoreUtils.SetKeyword(data.material, data.localKeywords.refineDepthKeyword, data.hitRefinementSteps > 0); + CoreUtils.SetKeyword(data.material, data.localKeywords.useMotionVectorsKeyword, !data.afterOpaque && !cameraData.isSceneViewCamera); + } + + // Instead of calculating the 'floor' depth by adding a constant thickness to the linear depth from the depth buffer, we treat thickness as a multiplier + // on the linear depth, i.e. linearFloorDepth = (1.0 + thickness) * linearDepth. To avoid converting to/from linear depth during marching, we precalculate + // a scale and bias on the device depth which lets us do the comparison on it directly. + private void CalculateThicknessScaleAndBias(float nearClip, float farClip, float thickness, out float thicknessScale, out float thicknessBias) + { + // Derivation below. 'b' is the floor device depth, 'd' is device depth, 'f' and 'n' are the far and near clip, and 'k_s', 'k_b' are the scale and bias. + // b = DeviceDepth((1 + thickness) * LinearDepth(d)) + // b = ((f - n) * d + n * (1 - (1 + thickness))) / ((f - n) * (1 + thickness)) + // b = ((f - n) * d - n * thickness) / ((f - n) * (1 + thickness)) + // b = d / (1 + thickness) - n / (f - n) * (thickness / (1 + thickness)) + // b = d * k_s + k_b + + // For non-reversed-Z (OpenGL), the derivation of thicknessScale is the same, but the derivation of thicknessBias becomes: + // thicknessBiasOpenGL = farClip / (farClip - nearClip) * (thickness * thicknessScale) + + thicknessScale = 1.0f / (1.0f + thickness); + if (SystemInfo.usesReversedZBuffer) + thicknessBias = -nearClip / (farClip - nearClip) * (thickness * thicknessScale); + else + thicknessBias = farClip / (farClip - nearClip) * (thickness * thicknessScale); + } + + private void CreateRenderTextureHandles( + RenderGraph renderGraph, + UniversalResourceData resourceData, + ScreenSpaceReflectionVolumeSettings settings, + out TextureHandle ssrTexture, + out TextureHandle blurTexture, + out TextureHandle upscaleTexture, + out TextureHandle mipGenTexture, + out TextureHandle finalTexture, + out TextureHandle depthPyramidTexture) + { + bool needRoughnessMips = settings.roughReflections.value != RoughReflectionsQuality.Disabled; + bool boxBlurRoughness = settings.roughReflections.value == RoughReflectionsQuality.BoxBlur; + + TextureDesc cameraDesc = resourceData.cameraColor.GetDescriptor(renderGraph); + bool useHdrRendering = GraphicsFormatUtility.IsHDRFormat(cameraDesc.format); + GraphicsFormat colorFormat = useHdrRendering ? GraphicsFormat.R16G16B16A16_SFloat : GraphicsFormat.R8G8B8A8_UNorm; + + TextureDesc fullResWithMips = cameraDesc; + fullResWithMips.format = colorFormat; + fullResWithMips.msaaSamples = MSAASamples.None; + fullResWithMips.useMipMap = needRoughnessMips; + fullResWithMips.autoGenerateMips = boxBlurRoughness; + fullResWithMips.enableRandomWrite = SystemInfo.supportsComputeShaders; + + TextureDesc fullResNoMips = fullResWithMips; + fullResNoMips.useMipMap = false; + + TextureDesc lowResWithMips = cameraDesc; + lowResWithMips.format = colorFormat; + lowResWithMips.msaaSamples = MSAASamples.None; + lowResWithMips.useMipMap = needRoughnessMips; + lowResWithMips.autoGenerateMips = boxBlurRoughness; + lowResWithMips.enableRandomWrite = false; + lowResWithMips.width /= (int)settings.resolution.value; + lowResWithMips.height /= (int)settings.resolution.value; + + TextureDesc lowResNoMips = lowResWithMips; + lowResNoMips.useMipMap = false; + + // Main output texture for SSR pass. Potentially low res. Only needs mips if we are relying on automips rather than gaussian mipchain, so there is no mipGenTexture. + TextureDesc ssrTextureDescriptor = boxBlurRoughness ? lowResWithMips : lowResNoMips; + ssrTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, ssrTextureDescriptor, "_SSR_ReflectionTexture", false, Color.clear, FilterMode.Bilinear); + + // Temporary texture for bilateral and gaussian blur. No mips. + bool gaussian = settings.upscalingMethod.value == UpscalingMethod.Gaussian; + bool bilateral = settings.upscalingMethod.value == UpscalingMethod.Bilateral; + if (settings.resolution != ScreenSpaceReflectionVolumeSettings.Resolution.Full && (gaussian || bilateral)) + blurTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, lowResNoMips, "_SSR_BlurTexture", false, Color.clear, FilterMode.Bilinear); + else + blurTexture = TextureHandle.nullHandle; + + // Temporary texture storing output of upscale. Only needs mips if we are relying on automips rather than gaussian mipchain, so there is no mipGenTexture. + TextureDesc upscaleTextureDescriptor = boxBlurRoughness ? fullResWithMips : fullResNoMips; + if (settings.resolution != ScreenSpaceReflectionVolumeSettings.Resolution.Full) + upscaleTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, upscaleTextureDescriptor, "_SSR_UpscaleTexture", false, Color.clear, FilterMode.Bilinear); + else + upscaleTexture = TextureHandle.nullHandle; + + // Temporary texture storing mipchain from color pyramid generator for rough reflections. Full res, with mips. + // Only needed in AfterOpaque, otherwise mips generated directly to final texture. + if (settings.ShouldUseGaussianBlurRoughness() && m_AfterOpaque) + mipGenTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, fullResWithMips, "_SSR_MipGenTexture", false, Color.clear, FilterMode.Bilinear); + else + mipGenTexture = TextureHandle.nullHandle; + + // Final texture. If after opaque, this is the screen target, otherwise a persistent texture with mips. + finalTexture = m_AfterOpaque ? resourceData.activeColorTexture : UniversalRenderer.CreateRenderGraphTexture(renderGraph, fullResWithMips, k_ScreenSpaceReflectionTextureName, false, Color.clear, FilterMode.Bilinear); + + // Depth pyramid for Hi-Z tracing. + if (!settings.ShouldUseLinearMarching()) + { + // Base format on precision of input depth. + // If the selected format isn't supported as UAV, try to fall back to a format with wider support. + TextureDesc depthDesc = resourceData.cameraDepthTexture.GetDescriptor(renderGraph); + GraphicsFormat depthFormat = depthDesc.format; + if (GraphicsFormatUtility.IsDepthFormat(depthDesc.format)) + depthFormat = GraphicsFormatUtility.GetDepthBits(depthDesc.format) > 16 ? GraphicsFormat.R32_SFloat : GraphicsFormat.R16_SFloat; + if (!SystemInfo.IsFormatSupported(depthFormat, GraphicsFormatUsage.LoadStore)) + depthFormat = GraphicsFormat.R32_SFloat; + if (!SystemInfo.IsFormatSupported(depthFormat, GraphicsFormatUsage.LoadStore)) + depthFormat = GraphicsFormat.R32G32B32A32_SFloat; + + TextureDesc depthPyramidDesc = cameraDesc; + depthPyramidDesc.height *= 2; + depthPyramidDesc.format = depthFormat; + depthPyramidDesc.msaaSamples = MSAASamples.None; + depthPyramidDesc.useMipMap = false; + depthPyramidDesc.autoGenerateMips = false; + depthPyramidDesc.enableRandomWrite = true; + depthPyramidDesc.width /= (int)settings.resolution.value; + depthPyramidDesc.height /= (int)settings.resolution.value; + depthPyramidTexture = UniversalRenderer.CreateRenderGraphTexture(renderGraph, depthPyramidDesc, "_SSR_DepthPyramid", false, Color.clear, FilterMode.Point); + } + else + depthPyramidTexture = TextureHandle.nullHandle; + } + + /// + public override void OnCameraCleanup(CommandBuffer cmd) + { + if (cmd == null) + throw new ArgumentNullException(nameof(cmd)); + + if (!m_AfterOpaque) + cmd.SetKeyword(ShaderGlobalKeywords.ScreenSpaceReflection, false); + } + } +} +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs.meta new file mode 100644 index 00000000000..a59cdc7fca9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPass.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0953ad13244b62d44989cf390cd1a2c3 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs new file mode 100644 index 00000000000..63654f65406 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs @@ -0,0 +1,28 @@ +using System; + +namespace UnityEngine.Rendering.Universal +{ + [Serializable] + [SupportedOnRenderPipeline(typeof(UniversalRenderPipelineAsset))] + [Categorization.CategoryInfo(Name = "R: SSR Resources", Order = 1010)] + [Categorization.ElementInfo(Order = 0)] + class ScreenSpaceReflectionPersistentResources : IRenderPipelineResources + { + [SerializeField] [ResourcePath("Shaders/Utils/ComputeScreenSpaceReflection.shader")] + Shader m_Shader; + + public Shader Shader + { + get => m_Shader; + set => this.SetValueAndNotify(ref m_Shader, value); + } + + public bool isAvailableInPlayerBuild => true; + + [SerializeField] [HideInInspector] + int m_Version = 0; + + /// Current version of the resource container. Used only for upgrading a project. + public int version => m_Version; + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs.meta new file mode 100644 index 00000000000..ebf0636b4f9 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionPersistentResources.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7d889ceca5f694540a4607aa3c632402 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs new file mode 100644 index 00000000000..165157c34cb --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs @@ -0,0 +1,109 @@ +#if URP_SCREEN_SPACE_REFLECTION +namespace UnityEngine.Rendering.Universal +{ + /// + /// The class for the SSR renderer feature. + /// + [SupportedOnRenderer(typeof(UniversalRendererData))] + [DisallowMultipleRendererFeature("Screen Space Reflection")] + [Tooltip("The Screen Space Reflection produces realtime reflections without the need for reflection probes.")] + public class ScreenSpaceReflectionRendererFeature : ScriptableRendererFeature + { + /// Whether to apply screen space reflections after the opaque pass or before the opaque pass. + [Tooltip("Whether to apply screen space reflections after the opaque pass or before the opaque pass. Enabling this feature may improve performance on low-end platforms, but will result in less physically correct reflections.")] + public bool afterOpaque; + + ScreenSpaceReflectionDepthNormalOnlyTransparentPass m_TransparentDepthNormalPass = null; + ScreenSpaceReflectionPass m_SSRPass = null; + + Shader m_Shader = null; + Material m_Material = null; + + /// + public override void Create() + { + if (m_SSRPass == null) + m_SSRPass = new ScreenSpaceReflectionPass(); + } + + /// + protected override void Dispose(bool disposing) + { + m_SSRPass?.Dispose(); + m_TransparentDepthNormalPass = null; + m_SSRPass = null; + CoreUtils.Destroy(m_Material); + } + + /// + public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) + { + var universalRenderingData = renderingData.universalRenderingData; + var universalCameraData = renderingData.frameData.Get(); + + if (UniversalRenderer.IsOffscreenDepthTexture(universalCameraData)) + return; + + // Currently no orthographic support, so ignore these cameras. + if (universalCameraData.camera.orthographic) + return; + + var settings = VolumeManager.instance.stack.GetComponent(); + if (settings.mode == ScreenSpaceReflectionVolumeSettings.ReflectionMode.Disabled) + return; + + if (!TryPrepareResources(universalRenderingData.transparentLayerMask, settings)) + return; + + if (!settings.linearMarching.value && !SystemInfo.supportsComputeShaders) + Debug.LogWarning("Screen Space Reflection settings are incompatible with the current platform. Linear Marching must be enabled on platforms without computer shader support. Falling back to linear marching."); + + bool shouldAdd = m_SSRPass.Setup(renderer, m_Material, afterOpaque, universalRenderingData, universalCameraData.cameraType); + if (shouldAdd) + { + if (settings.ShouldRenderTransparents()) + { + var renderPassEvent = afterOpaque ? RenderPassEvent.AfterRenderingTransparents : RenderPassEvent.AfterRenderingPrePasses; + m_TransparentDepthNormalPass.UpdateRenderPassEvent(renderPassEvent); + renderer.EnqueuePass(m_TransparentDepthNormalPass); + } + + renderer.EnqueuePass(m_SSRPass); + } + } + + bool TryPrepareResources(LayerMask transparentLayerMask, ScreenSpaceReflectionVolumeSettings settings) + { + if (settings.ShouldRenderTransparents()) + { + if (m_TransparentDepthNormalPass == null) + m_TransparentDepthNormalPass = new(RenderPassEvent.AfterRenderingPrePasses, RenderQueueRange.transparent, transparentLayerMask); + } + + if (m_Shader == null) + { + if (!GraphicsSettings.TryGetRenderPipelineSettings(out var ssrPersistentResources)) + { + Debug.LogErrorFormat( + $"Couldn't find the required resources for the {nameof(ScreenSpaceReflectionRendererFeature)}. If this exception appears in the Player, make sure at least one {nameof(ScreenSpaceReflectionRendererFeature)} is enabled or adjust your stripping settings."); + return false; + } + + m_Shader = ssrPersistentResources.Shader; + } + + if (m_Material == null && m_Shader != null) + m_Material = CoreUtils.CreateEngineMaterial(m_Shader); + + if (m_Material == null) + { + Debug.LogError($"{GetType().Name}.AddRenderPasses(): Missing material. {name} render pass will not be added."); + return false; + } + + return true; + + } + } +} +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs.meta new file mode 100644 index 00000000000..e5897634f20 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionRendererFeature.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fb9f2fe3baf0e8c46bf390df937e6187 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs new file mode 100644 index 00000000000..5f978723706 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs @@ -0,0 +1,130 @@ +#if URP_SCREEN_SPACE_REFLECTION +using System; + +namespace UnityEngine.Rendering.Universal +{ + /// + /// A volume component that holds settings for the Screen Space Reflections Renderer Feature. + /// + [Serializable, VolumeComponentMenu("Lighting/Screen Space Reflection"), SupportedOnRenderPipeline] + [DisplayInfo(name = "Screen Space Reflection")] + public class ScreenSpaceReflectionVolumeSettings : VolumeComponent + { + /// + /// An enum specifying which resolution to render Screen Space Reflections at. + /// + public enum Resolution + { + Full = 1, + Half = 2, + Quarter = 4, + } + + /// + /// An enum specifying which technique to use for upscaling Screen Space Reflections. + /// + public enum UpscalingMethod + { + None, + Kawase, + Gaussian, + Bilateral, + } + + /// + /// An enum specifying which quality to use for Screen Space Reflections. + /// + public enum RoughReflectionsQuality + { + Disabled, + BoxBlur, + GaussianBlur, + } + + /// + /// An enum specifying which objects to reflect using Screen Space Reflections. + /// + public enum ReflectionMode + { + Disabled, + OpaquesOnly, + OpaquesAndTransparents, + } + + /// The mode determining which objects to reflect using Screen Space Reflections. + [Tooltip("The mode determining which objects to reflect using Screen Space Reflections. 'Opaques Only' will only render opaque objects in reflections, while 'Opaques And Transparents' will also render transparent objects in reflections.")] + public EnumParameter mode = new(ReflectionMode.OpaquesOnly); + + /// The resolution to render Screen Space Reflections at. + [Tooltip("The resolution to render Screen Space Reflections at. Lower values will yield better performance, but lower quality.")] + public EnumParameter resolution = new(Resolution.Full); + + /// The technique to use for upscaling Screen Space Reflections. + [Tooltip("The method to use for upscaling the low resolution SSR texture. 'Kawase' is the most performant method, followed by 'Gaussian', and finally 'Bilateral'.")] + public EnumParameter upscalingMethod = new(UpscalingMethod.Bilateral); + + /// Whether to use linear marching to calculate Screen Space Reflections, rather than hierarchical depth buffer marching. + [Tooltip("Whether to use linear marching to calculate Screen Space Reflections, rather than hierarchical depth buffer marching. With the option disabled, Unity generates a depth pyramid and uses its for hierarchical marching. This is more accurate, but may be less performant on low-end devices.")] + public BoolParameter linearMarching = new(false); + + /// Amount of binary search steps applied at the end of the ray to refine hit results, reducing stair-stepping artifacts and gaps in reflections caused by linear marching, where initial steps may be imprecise and miss fine details. + [Tooltip("Amount of binary search steps applied at the end of the ray to refine hit results, reducing stair-stepping artifacts and gaps in reflections caused by linear marching, where initial steps may be imprecise and miss fine details.")] + public MinIntParameter hitRefinementSteps = new(4,0); + + /// Multiplies the regular thickness to compute a finer value, used with additional refinement steps to achieve more precise hit detection. + [Tooltip("Multiplies the regular thickness to compute a finer value, used with additional refinement steps to achieve more precise hit detection.")] + public ClampedFloatParameter finalThicknessMultiplier = new(0.25f, 0.0f, 1f); + + /// Whether to enable rough reflections by blurring the reflected color. + [Tooltip("Whether to enable rough reflections by blurring the reflected color. Disabling will improve performance, but all reflections will be mirror-like.")] + public EnumParameter roughReflections = new(RoughReflectionsQuality.GaussianBlur); + + /// The minimum amount of surface smoothness at which Screen Space Reflections are used. + [Tooltip("The minimum amount of surface smoothness at which Screen Space Reflections are used. Higher values will result in less objects receiving Screen Space Reflections.")] + public ClampedFloatParameter minimumSmoothness = new(0.05f, 0.0f, 1.0f); + + /// The smoothness value at which the smoothness-controlled fade out starts. + [Tooltip("The smoothness value at which the smoothness-controlled fade out starts. The fade is in the range [Min Smoothness, Smoothness Fade Start].")] + public ClampedFloatParameter smoothnessFadeStart = new(0.1f, 0.0f, 1.0f); + + /// How much to fade reflections based on the reflection normal. + [Tooltip("How much to fade reflections based on the reflection normal.")] + public ClampedFloatParameter normalFade = new(0.0f, 0.0f, 1.0f); + + /// The distance at which the reflection fades out near the edge of the screen. + [Tooltip("The distance at which the reflection fades out near the edge of the screen.")] + public ClampedFloatParameter screenEdgeFadeDistance = new(0.2f, 0.0f, 1.0f); + + /// Whether to use Screen Space Reflections to handle reflections of the sky. + [Tooltip("Whether to use SSR to handle sky reflection. If you disable this property, pixels that reflect the sky will sample from nearby reflection probes, or the skybox.")] + public BoolParameter reflectSky = new(false); + + /// The maximum distance in world space units a ray can travel. Only has an effect when linearMarching is enabled. + [Tooltip("The maximum distance in world space units a ray can travel.")] + public MinFloatParameter maxRayLength = new(10f, 0f); + + /// The fade distance in world space units before the maximum ray length. Only has an effect when linearMarching is enabled. + [Tooltip("The fade distance in world space units before the maximum ray length. Only has an effect when Linear Marching is enabled.")] + public MinFloatParameter rayLengthFade = new(1f, 0f); + + /// The maximum amount of steps to take when tracing rays. + [Tooltip("The maximum amount of steps to take when tracing rays.")] + public MinIntParameter maxRaySteps = new(48, 1); + + /// How close to the depth buffer a ray must be to be considered a hit. + [Tooltip("How close to the depth buffer a ray must be to be considered a hit. Higher values will result in less accurate reflections, but may help mitigate shimmering artifacts.")] + public ClampedFloatParameter objectThickness = new(0.02f, 0f, 1f); + + // Helpers + internal bool ShouldRenderTransparents() => mode.value == ReflectionMode.OpaquesAndTransparents; + internal bool ShouldUseGaussianBlurRoughness() => roughReflections.value == RoughReflectionsQuality.GaussianBlur; + internal bool ShouldUseLinearMarching() => linearMarching.value || !SystemInfo.supportsComputeShaders; + + // Allow listening for property changes, to support presets in the presence of undo and changing values from script etc. +#if UNITY_EDITOR + internal event Action propertyChanged; + private void OnValidate() => propertyChanged?.Invoke(); +#endif + } +} +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs.meta new file mode 100644 index 00000000000..40d75232d67 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceReflectionRendererFeature/ScreenSpaceReflectionVolumeSettings.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2274cd80d4e22254d98d0282578183e0 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceShadows.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceShadows.cs index 29010dd6f13..281158c7aeb 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceShadows.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/ScreenSpaceShadows.cs @@ -104,6 +104,18 @@ private bool LoadMaterial() return m_Material != null; } + /// + /// Pass that renders screen-space shadows by sampling the main light shadow map. + /// + /// This pass reconstructs world positions from the depth prepass (cameraDepthTexture), + /// transforms them to shadow space, and samples the shadow map to produce a screen-space + /// shadow texture. This is more efficient than traditional forward shadow sampling per-pixel. + /// + /// IMPORTANT: World position reconstruction from depth requires the inverse view-projection matrix + /// (unity_MatrixInvVP) to match the UV origin of the depth texture. In Tile-Only Mode and + /// direct-to-backbuffer scenarios, the depth texture orientation may differ from the active + /// render target, requiring explicit matrix setup. See ExecutePass for details. + /// private class ScreenSpaceShadowsPass : ScriptableRenderPass { // Private Variables @@ -126,20 +138,26 @@ internal bool Setup(ScreenSpaceShadowsSettings featureSettings, Material materia return m_Material != null; } - + private class PassData { internal TextureHandle target; + internal TextureHandle cameraDepthTexture; + internal TextureHandle activeTarget; internal Material material; + internal UniversalCameraData cameraData; } /// /// Initialize the shared pass data. /// /// - private void InitPassData(ref PassData passData) + private void InitPassData(ref PassData passData, in TextureHandle cameraDepthTexture, in TextureHandle activeTarget, UniversalCameraData cameraData) { passData.material = m_Material; + passData.cameraDepthTexture = cameraDepthTexture; + passData.activeTarget = activeTarget; + passData.cameraData = cameraData; } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) @@ -149,7 +167,9 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer Debug.LogErrorFormat("{0}.Execute(): Missing material. ScreenSpaceShadows pass will not execute. Check for missing reference in the renderer resources.", GetType().Name); return; } - UniversalCameraData cameraData = frameData.Get(); + var cameraData = frameData.Get(); + var resourceData = frameData.Get(); + var desc = cameraData.cameraTargetDescriptor; desc.depthStencilFormat = GraphicsFormat.None; desc.msaaSamples = 1; @@ -170,8 +190,10 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer { passData.target = color; builder.UseTexture(color, AccessFlags.WriteAll); + builder.UseTexture(resourceData.cameraDepthTexture); - InitPassData(ref passData); + // activeColorTexture is always valid here since AddRenderPasses returns early for offscreen depth cameras + InitPassData(ref passData, resourceData.cameraDepthTexture, resourceData.activeColorTexture, cameraData); builder.AllowGlobalStateModification(true); if (color.IsValid()) @@ -179,17 +201,44 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.SetRenderFunc(static (PassData data, UnsafeGraphContext rgContext) => { - ExecutePass(rgContext.cmd, data, data.target); + ExecutePass(rgContext, data); }); } } - private static void ExecutePass(UnsafeCommandBuffer cmd, PassData data, RTHandle target) + private static void ExecutePass(UnsafeGraphContext rgContext, PassData data) { - Blitter.BlitTexture(cmd, target, Vector2.one, data.material, 0); + var cmd = rgContext.cmd; + + // CRITICAL FIX for Tile-Only Mode and direct-to-backbuffer rendering: + // + // The shader reconstructs world positions from depth using: + // float3 wpos = ComputeWorldSpacePosition(uv, depth, unity_MatrixInvVP); + // + // The global unity_MatrixInvVP might be set for the active render target's orientation (e.g., TopLeft in Tile-Only Mode), + // but cameraDepthTexture was rendered with a potentially different orientation (always BottomLeft - it's an intermediate texture). + // + // When orientations don't match, the Y-coordinate in world-space reconstruction is inverted, causing shadow lookups + // to sample from the wrong world positions → shadows appear upside down. + // + // FIX: Temporarily set unity_MatrixInvVP to match cameraDepthTexture's orientation for correct position reconstruction. + TextureUVOrigin depthOrigin = rgContext.GetTextureUVOrigin(data.cameraDepthTexture); + Matrix4x4 depthInvVP = RenderingUtils.ComputeInverseViewProjectionMatrix(depthOrigin, data.cameraData); + cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, depthInvVP); + + // Perform the shadow sampling blit + Blitter.BlitTexture(cmd, data.target, Vector2.one, data.material, 0); + + // Set shadow keywords cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadows, false); cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowCascades, false); cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowScreen, true); + + // Restore unity_MatrixInvVP to match the active target's orientation for subsequent passes. + // Without this, later passes that rely on the global matrix might get incorrect results. + TextureUVOrigin activeOrigin = rgContext.GetTextureUVOrigin(data.activeTarget); + Matrix4x4 activeInvVP = RenderingUtils.ComputeInverseViewProjectionMatrix(activeOrigin, data.cameraData); + cmd.SetGlobalMatrix(ShaderPropertyId.inverseViewAndProjectionMatrix, activeInvVP); } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs index 96b9c419577..b6d0ae016c0 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheGIRendererFeature.cs @@ -1,19 +1,22 @@ #if SURFACE_CACHE using System; -using System.Collections.Generic; using Unity.Mathematics; using UnityEngine.Experimental.Rendering; using UnityEngine.PathTracing.Core; using UnityEngine.Rendering.LiveGI; using UnityEngine.Rendering.RenderGraphModule; using UnityEngine.Rendering.UnifiedRayTracing; -using InstanceHandle = UnityEngine.PathTracing.Core.Handle; -using LightHandle = UnityEngine.PathTracing.Core.Handle; -using MaterialHandle = UnityEngine.PathTracing.Core.Handle; namespace UnityEngine.Rendering.Universal { + internal struct SurfaceCacheScreenFilteringParameterSet + { + public uint LookupSampleCount; + public float UpsamplingKernelSize; + public uint UpsamplingSampleCount; + } + [Serializable] [SupportedOnRenderPipeline] [Categorization.CategoryInfo(Name = "R: Surface Cache URP Integration", Order = 1000), HideInInspector] @@ -94,6 +97,13 @@ public enum DebugViewMode_ FlatNormal } + public static readonly string k_StaticBatchingErrorMesssage = "Surface Cache GI cannot run because it is incompatible with Static Batching. You can disable the option in the Player Settings."; + + private const uint DEFAULT_DEFRAG_COUNT = 2; // Default value for how many patches to defragment per frame. + private const float DEFAULT_VOLUME_SIZE = 128.0f; // Default value for the size of the volume in world units. + private const uint DEFAULT_VOLUME_RESOLUTION = 32; // Default value for the voxel resolution of the volume. + private const uint DEFAULT_VOLUME_CASCADE_COUNT = 4; // Default value for the number of cascades in the volume. + // URP currently cannot render motion vectors properly in Scene View, so we disable it. // https://jira.unity3d.com/browse/SRP-743 // When this is fixed, we probably want to enable this always. @@ -164,6 +174,8 @@ private class WorldUpdatePassData internal SurfaceCacheWorld World; internal uint EnvCubemapResolution; internal Light Sun; + internal Matrix4x4 RestoreViewMatrix; + internal Matrix4x4 RestoreProjectionMatrix; } private class DebugPassData @@ -296,9 +308,8 @@ private class ScreenIrradianceUpsamplingPassData private GraphicsBuffer _worldUpdateScratch; private readonly SceneUpdatesTracker _sceneTracker; - private readonly WorldAdapter _worldAdapter; + private readonly SurfaceCacheWorldAdapter _worldAdapter; private readonly SurfaceCacheWorld _world; - private readonly Material _fallbackMaterial; private readonly ComputeShader _screenResolveLookupShader; private readonly ComputeShader _screenResolveUpsamplingShader; @@ -321,23 +332,31 @@ private class ScreenIrradianceUpsamplingPassData private uint3 _flatNormalResolutionKernelGroupSize; private uint _frameIdx; - private bool _cascadeMovement; // Debug private readonly bool _debugEnabled; private readonly DebugViewMode_ _debugViewMode; private readonly bool _debugShowSamplePosition; - // Screen Filtering - private readonly uint _lookupSampleCount; - private readonly float _upsamplingKernelSize; - private readonly uint _upsamplingSampleCount; - private SurfaceCache _cache; private Matrix4x4 _prevClipToWorldTransform = Matrix4x4.identity; - readonly private uint _environmentCubemapResolution = 32; + private readonly uint _environmentCubemapResolution = 32; + private const int k_UpscaleFactor = 4; + + // Defaults, used as fallback when no volume override is active. + private const uint DEFAULT_ESTIMATION_SAMPLE_COUNT = 2; + private const float DEFAULT_TEMPORAL_SMOOTHING = 0.8f; + private const uint DEFAULT_SPATIAL_FILTER_SAMPLE_COUNT = 4; + private const float DEFAULT_SPATIAL_FILTER_RADIUS = 1.0f; + private const uint DEFAULT_LOOKUP_SAMPLE_COUNT = 6; + private const float DEFAULT_UPSAMPLING_KERNEL_SIZE = 5.0f; + private const uint DEFAULT_UPSAMPLING_SAMPLE_COUNT = 2; + + // Stored for runtime cache recreation when resolution or cascade count changes + private readonly Rendering.SurfaceCacheResourceSet _coreResources; + private uint _defragCount; public SurfaceCachePass( RayTracingContext rtContext, @@ -352,14 +371,8 @@ public SurfaceCachePass( bool debugEnabled, DebugViewMode_ debugViewMode, bool debugShowSamplePosition, - uint lookupSampleCount, - float upsamplingKernelSize, - uint upsamplingSampleCount, uint defragCount, - SurfaceCacheVolumeParameterSet volParams, - SurfaceCacheEstimationParameterSet estimationParams, - SurfaceCachePatchFilteringParameterSet patchFilteringParams, - bool cascadeMovement) + SurfaceCacheVolumeParameterSet volParams) { Debug.Assert(volParams.CascadeCount != 0); Debug.Assert(volParams.CascadeCount <= SurfaceCache.CascadeMax); @@ -377,8 +390,6 @@ public SurfaceCachePass( _debugKernel = _debugShader.FindKernel("Visualize"); _flatNormalResolutionKernel = _flatNormalResolutionShader.FindKernel("ResolveFlatNormals"); - _cascadeMovement = cascadeMovement; - _screenResolveLookupShader.GetKernelThreadGroupSizes(_screenResolveLookupKernel, out _screenResolveLookupKernelGroupSize.x, out _screenResolveLookupKernelGroupSize.y, out _screenResolveLookupKernelGroupSize.z); _screenResolveUpsamplingShader.GetKernelThreadGroupSizes(_screenResolveUpsamplingKernel, out _screenResolveUpsamplingKernelGroupSize.x, out _screenResolveUpsamplingKernelGroupSize.y, out _screenResolveUpsamplingKernelGroupSize.z); _patchAllocationShader.GetKernelThreadGroupSizes(_patchAllocationKernel, out _patchAllocationKernelGroupSize.x, out _patchAllocationKernelGroupSize.y, out _patchAllocationKernelGroupSize.z); @@ -391,18 +402,16 @@ public SurfaceCachePass( _debugViewMode = debugViewMode; _debugShowSamplePosition = debugShowSamplePosition; - _upsamplingKernelSize = upsamplingKernelSize; - _upsamplingSampleCount = upsamplingSampleCount; - _lookupSampleCount = lookupSampleCount; + _coreResources = resourceSet; + _defragCount = defragCount; - _cache = new SurfaceCache(resourceSet, defragCount, volParams, estimationParams, patchFilteringParams); + _cache = new SurfaceCache(resourceSet, defragCount, volParams); _sceneTracker = new SceneUpdatesTracker(); _world = new SurfaceCacheWorld(); _world.Init(_rtContext, worldResources); - _fallbackMaterial = fallbackMaterial; - _worldAdapter = new WorldAdapter(_world, _fallbackMaterial); + _worldAdapter = new SurfaceCacheWorldAdapter(_world, fallbackMaterial); } public void Dispose() @@ -421,7 +430,71 @@ public void Dispose() _worldUpdateScratch?.Dispose(); } - const int k_UpscaleFactor = 4; + private static VolumeParameterSet GetVolumeParametersOrDefaults(SurfaceCacheGIVolumeOverride volume) + { + if (volume != null && volume.IsActive()) + { + // Use volume parameters + return new VolumeParameterSet + { + EstimationParams = new SurfaceCacheEstimationParameterSet + { + MultiBounce = volume.multiBounce, + SampleCount = (uint)volume.sampleCount, + }, + PatchFilteringParams = new SurfaceCachePatchFilteringParameterSet + { + TemporalSmoothing = volume.temporalSmoothing, + SpatialFilterEnabled = volume.spatialFilterEnabled, + SpatialFilterSampleCount = (uint)volume.spatialSampleCount, + SpatialFilterRadius = volume.spatialRadius, + TemporalPostFilterEnabled = volume.temporalPostFilter + }, + ScreenFilteringParams = new SurfaceCacheScreenFilteringParameterSet + { + LookupSampleCount = (uint)volume.lookupSampleCount, + UpsamplingKernelSize = volume.upsamplingKernelSize, + UpsamplingSampleCount = (uint)volume.upsamplingSampleCount, + }, + CascadeMovement = volume.cascadeMovement, + VolumeSize = volume.volumeSize, + VolumeResolution = (uint)volume.volumeResolution, + VolumeCascadeCount = (uint)volume.volumeCascadeCount, + DefragCount = (uint)volume.defragCount + }; + } + else + { + // Fallback to defaults. + return new VolumeParameterSet + { + EstimationParams = new SurfaceCacheEstimationParameterSet + { + MultiBounce = true, + SampleCount = DEFAULT_ESTIMATION_SAMPLE_COUNT, + }, + PatchFilteringParams = new SurfaceCachePatchFilteringParameterSet + { + TemporalSmoothing = DEFAULT_TEMPORAL_SMOOTHING, + SpatialFilterEnabled = true, + SpatialFilterSampleCount = DEFAULT_SPATIAL_FILTER_SAMPLE_COUNT, + SpatialFilterRadius = DEFAULT_SPATIAL_FILTER_RADIUS, + TemporalPostFilterEnabled = true + }, + ScreenFilteringParams = new SurfaceCacheScreenFilteringParameterSet + { + LookupSampleCount = DEFAULT_LOOKUP_SAMPLE_COUNT, + UpsamplingKernelSize = DEFAULT_UPSAMPLING_KERNEL_SIZE, + UpsamplingSampleCount = DEFAULT_UPSAMPLING_SAMPLE_COUNT, + }, + CascadeMovement = true, + VolumeSize = DEFAULT_VOLUME_SIZE, + VolumeResolution = DEFAULT_VOLUME_RESOLUTION, + VolumeCascadeCount = DEFAULT_VOLUME_CASCADE_COUNT, + DefragCount = DEFAULT_DEFRAG_COUNT + }; + } + } public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { @@ -442,6 +515,34 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer if (cameraData.cameraType != CameraType.Game && cameraData.cameraType != CameraType.SceneView) return; + // Get volume parameters that can change per-frame. + var stack = VolumeManager.instance.stack; + var volume = stack.GetComponent(); + var volumeParams = GetVolumeParametersOrDefaults(volume); + _defragCount = volumeParams.DefragCount; + + // Detect structural changes that require buffer reallocation. + if (volumeParams.VolumeResolution != _cache.Volume.SpatialResolution || volumeParams.VolumeCascadeCount != _cache.Volume.CascadeCount) + { + uint newResolution = volumeParams.VolumeResolution; + uint newCascadeCount = volumeParams.VolumeCascadeCount; + Debug.Assert(newCascadeCount != 0 && newCascadeCount <= SurfaceCache.CascadeMax); + + _cache.Dispose(); + var newVolParams = new SurfaceCacheVolumeParameterSet + { + Resolution = newResolution, + Size = volumeParams.VolumeSize, + CascadeCount = newCascadeCount + }; + _cache = new SurfaceCache(_coreResources, _defragCount, newVolParams); + _frameIdx = 0; + } + + _cache.SetEstimationParams(volumeParams.EstimationParams); + _cache.SetPatchFilteringParams(volumeParams.PatchFilteringParams); + _cache.UpdateVolumeSize(volumeParams.VolumeSize); + bool useMotionVectorPatchSeeding = UseMotionVectorPatchSeeding(cameraData.cameraType); if (_fullResScreenIrradiances == null || _fullResScreenIrradiances.GetScaledSize() != new Vector2Int(screenResolution.x, screenResolution.y)) @@ -469,7 +570,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer _lowResScreenNdcDepths = RTHandles.Alloc(lowResWidth, lowResHeight, 1, DepthBits.None, GraphicsFormat.R16_UNorm, FilterMode.Point, TextureWrapMode.Clamp, TextureDimension.Tex2D, true, name: "_lowResScreenNdcDepths"); } - if (_cascadeMovement || _frameIdx == 0) + if (volumeParams.CascadeMovement || _frameIdx == 0) { _cache.Volume.TargetPos = cameraData.camera.transform.position; } @@ -558,44 +659,15 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.SetRenderFunc((PatchAllocationPassData data, ComputeGraphContext cgContext) => AllocatePatches(data, cgContext)); } + _worldAdapter.Update(_sceneTracker, RenderSettings.ambientMode, RenderSettings.skybox, RenderSettings.ambientSkyColor, _world); + using (var builder = renderGraph.AddUnsafePass("Surface Cache World Update", out WorldUpdatePassData passData)) { - const bool filterBakedLights = true; - var changes = _sceneTracker.GetChanges(filterBakedLights); - - _worldAdapter.UpdateMaterials(_world, changes.addedMaterials, changes.removedMaterials, changes.changedMaterials); - _worldAdapter.UpdateMeshRenderers( - _world, - changes.addedMeshRenderers, - changes.changedMeshRenderers, - changes.removedMeshRenderers, - _fallbackMaterial); - _worldAdapter.UpdateTerrains( - _world, - changes.addedTerrains, - changes.changedTerrains, - changes.removedTerrains, - _fallbackMaterial); - - const bool multiplyPunctualLightIntensityByPI = false; - _worldAdapter.UpdateLights(_world, changes.addedLights, changes.removedLights, changes.changedLights, multiplyPunctualLightIntensityByPI); - - if (RenderSettings.ambientMode == AmbientMode.Skybox) - { - _world.SetEnvironmentMode(CubemapRender.Mode.Material); - _world.SetEnvironmentMaterial(RenderSettings.skybox); - } - else if (RenderSettings.ambientMode == AmbientMode.Flat) - { - _world.SetEnvironmentMode(CubemapRender.Mode.Color); - _world.SetEnvironmentColor(RenderSettings.ambientSkyColor); - } - passData.World = _world; passData.EnvCubemapResolution = _environmentCubemapResolution; passData.Sun = RenderSettings.sun; - - + passData.RestoreProjectionMatrix = cameraData.GetProjectionMatrix(); + passData.RestoreViewMatrix = worldToViewTransform; builder.AllowGlobalStateModification(true); builder.SetRenderFunc((WorldUpdatePassData data, UnsafeGraphContext graphCtx) => UpdateWorld(data, graphCtx, ref _worldUpdateScratch)); @@ -625,7 +697,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer data.VolumeSpatialResolution = _cache.Volume.SpatialResolution; data.VolumeVoxelMinSize = _cache.Volume.VoxelMinSize; data.VolumeCascadeCount = _cache.Volume.CascadeCount; - data.SampleCount = _lookupSampleCount; + data.SampleCount = volumeParams.ScreenFilteringParams.LookupSampleCount; data.FrameIndex = _frameIdx; builder.UseBuffer(cellAllocationMarkHandle, AccessFlags.Read); @@ -695,8 +767,8 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer data.LowResScreenIrradiancesL11 = lowResScreenIrradiancesL11Handle; data.LowResScreenIrradiancesL12 = lowResScreenIrradiancesL12Handle; data.FullResIrradiances = fullResScreenIrradiancesHandle; - data.FilterRadius = _upsamplingKernelSize; - data.SampleCount = _upsamplingSampleCount; + data.FilterRadius = volumeParams.ScreenFilteringParams.UpsamplingKernelSize; + data.SampleCount = volumeParams.ScreenFilteringParams.UpsamplingSampleCount; builder.UseTexture(data.FullResIrradiances, AccessFlags.Write); builder.UseTexture(resourceData.cameraDepthTexture, AccessFlags.Read); @@ -721,7 +793,11 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer static void UpdateWorld(WorldUpdatePassData data, UnsafeGraphContext graphCtx, ref GraphicsBuffer scratch) { var cmd = CommandBufferHelpers.GetNativeCommandBuffer(graphCtx.cmd); - data.World.Commit(cmd, ref scratch, data.EnvCubemapResolution, data.Sun); + data.World.Commit(cmd, ref scratch, data.EnvCubemapResolution, data.Sun, out bool viewAndProjectionMatricesChanged); + if (viewAndProjectionMatricesChanged) + { + cmd.SetViewProjectionMatrices(data.RestoreViewMatrix, data.RestoreProjectionMatrix); + } } static void LookupScreenIrradiance(ScreenIrradianceLookupPassData data, ComputeGraphContext cgContext) @@ -861,369 +937,15 @@ static void RenderDebug(DebugPassData data, ComputeGraphContext cgContext) private static uint2 DivUp(uint2 x, uint2 y) => (x + y - 1) / y; } - class WorldAdapter : IDisposable - { - // This dictionary maps from Unity EntityID for MeshRenderer or Terrain, to corresponding InstanceHandle for accessing World. - private readonly Dictionary _entityIDToWorldInstanceHandles = new(); - - // Same as above but for Lights - private readonly Dictionary _entityIDToWorldLightHandles = new(); - - // Same as above but for Materials - private Dictionary _entityIDToWorldMaterialHandles = new(); - - // We also keep track of associated material descriptors, so we can free temporary temporary textures when a material is removed - private Dictionary _entityIDToWorldMaterialDescriptors = new(); - - private MaterialPool.MaterialDescriptor _fallbackMaterialDescriptor; - private MaterialHandle _fallbackMaterialHandle; - - public WorldAdapter(SurfaceCacheWorld world, Material fallbackMaterial) - { - _fallbackMaterialDescriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(fallbackMaterial); - _fallbackMaterialHandle = world.AddMaterial(in _fallbackMaterialDescriptor, UVChannel.UV0); - _entityIDToWorldMaterialHandles.Add(fallbackMaterial.GetEntityId(), _fallbackMaterialHandle); - _entityIDToWorldMaterialDescriptors.Add(fallbackMaterial.GetEntityId(), _fallbackMaterialDescriptor); - } - - public void UpdateMaterials(SurfaceCacheWorld world, List addedMaterials, List removedMaterials, List changedMaterials) - { - UpdateMaterials(world, _entityIDToWorldMaterialHandles, _entityIDToWorldMaterialDescriptors, addedMaterials, removedMaterials, changedMaterials); - } - - private static void UpdateMaterials(SurfaceCacheWorld world, Dictionary entityIDToHandle, Dictionary entityIDToDescriptor, List addedMaterials, List removedMaterials, List changedMaterials) - { - static void DeleteTemporaryTextures(ref MaterialPool.MaterialDescriptor desc) - { - CoreUtils.Destroy(desc.Albedo); - CoreUtils.Destroy(desc.Emission); - CoreUtils.Destroy(desc.Transmission); - } - - foreach (var entityID in removedMaterials) - { - // Clean up temporary textures in the descriptor - Debug.Assert(entityIDToDescriptor.ContainsKey(entityID)); - var descriptor = entityIDToDescriptor[entityID]; - DeleteTemporaryTextures(ref descriptor); - entityIDToDescriptor.Remove(entityID); - - // Remove the material from the world - Debug.Assert(entityIDToHandle.ContainsKey(entityID)); - world.RemoveMaterial(entityIDToHandle[entityID]); - entityIDToHandle.Remove(entityID); - } - - foreach (var material in addedMaterials) - { - // Add material to the world - var descriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(material); - var handle = world.AddMaterial(in descriptor, UVChannel.UV0); - entityIDToHandle.Add(material.GetEntityId(), handle); - - // Keep track of the descriptor - entityIDToDescriptor.Add(material.GetEntityId(), descriptor); - } - - foreach (var material in changedMaterials) - { - // Clean up temporary textures in the old descriptor - Debug.Assert(entityIDToDescriptor.ContainsKey(material.GetEntityId())); - var oldDescriptor = entityIDToDescriptor[material.GetEntityId()]; - DeleteTemporaryTextures(ref oldDescriptor); - - // Update the material in the world using the new descriptor - Debug.Assert(entityIDToHandle.ContainsKey(material.GetEntityId())); - var newDescriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(material); - world.UpdateMaterial(entityIDToHandle[material.GetEntityId()], in newDescriptor, UVChannel.UV0); - entityIDToDescriptor[material.GetEntityId()] = newDescriptor; - } - } - - internal void UpdateLights(SurfaceCacheWorld world, List addedLights, List removedLights, - List changedLights, bool multiplyPunctualLightIntensityByPI) - { - UpdateLights(world, _entityIDToWorldLightHandles, addedLights, removedLights, changedLights, multiplyPunctualLightIntensityByPI); - } - - private static void UpdateLights( - SurfaceCacheWorld world, - Dictionary entityIDToHandle, List addedLights, List removedLights, - List changedLights, - bool multiplyPunctualLightIntensityByPI) - { - // Remove deleted lights - LightHandle[] handlesToRemove = new LightHandle[removedLights.Count]; - for (int i = 0; i < removedLights.Count; i++) - { - var lightEntityID = removedLights[i]; - handlesToRemove[i] = entityIDToHandle[lightEntityID]; - entityIDToHandle.Remove(lightEntityID); - } - world.RemoveLights(handlesToRemove); - - // Add new lights - var lightDescriptors = ConvertUnityLightsToLightDescriptors(addedLights.ToArray(), multiplyPunctualLightIntensityByPI); - LightHandle[] addedHandles = world.AddLights(lightDescriptors); - for (int i = 0; i < addedLights.Count; ++i) - entityIDToHandle.Add(addedLights[i].GetEntityId(), addedHandles[i]); - - // Update changed lights - LightHandle[] handlesToUpdate = new LightHandle[changedLights.Count]; - for (int i = 0; i < changedLights.Count; i++) - handlesToUpdate[i] = entityIDToHandle[changedLights[i].GetEntityId()]; - - world.UpdateLights(handlesToUpdate, ConvertUnityLightsToLightDescriptors(changedLights.ToArray(), multiplyPunctualLightIntensityByPI)); - } - - internal void UpdateMeshRenderers( - SurfaceCacheWorld world, - List addedMeshRenderers, - List changedMeshRenderers, - List removedMeshRenderers, - Material fallbackMaterial) - { - UpdateMeshRenderers(world, _entityIDToWorldInstanceHandles, _entityIDToWorldMaterialHandles, addedMeshRenderers, changedMeshRenderers, removedMeshRenderers, fallbackMaterial); - } - - internal void UpdateTerrains( - SurfaceCacheWorld world, - List addedTerrains, - List changedTerrains, - List removedTerrains, - Material fallbackMaterial) - { - UpdateTerrains(world, _entityIDToWorldInstanceHandles, _entityIDToWorldMaterialHandles, addedTerrains, changedTerrains, removedTerrains, fallbackMaterial); - } - - private static void UpdateMeshRenderers( - SurfaceCacheWorld world, - Dictionary entityIDToInstanceHandle, - Dictionary entityIDToMaterialHandle, - List addedMeshRenderers, - List changedMeshRenderers, - List removedMeshRenderers, - Material fallbackMaterial) - { - foreach (var meshRendererEntityID in removedMeshRenderers) - { - if (entityIDToInstanceHandle.TryGetValue(meshRendererEntityID, out var instanceHandle)) - { - world.RemoveInstance(instanceHandle); - entityIDToInstanceHandle.Remove(meshRendererEntityID); - } - } - - foreach (var meshRenderer in addedMeshRenderers) - { - Debug.Assert(!meshRenderer.isPartOfStaticBatch); - - var mesh = meshRenderer.GetComponent().sharedMesh; - - if (mesh == null || mesh.vertexCount == 0) - continue; - - var localToWorldMatrix = meshRenderer.transform.localToWorldMatrix; - - var materials = Util.GetMaterials(meshRenderer); - var materialHandles = new MaterialHandle[materials.Length]; - for (int i = 0; i < materials.Length; i++) - { - var matEntityId = materials[i] == null ? fallbackMaterial.GetEntityId() : materials[i].GetEntityId(); - materialHandles[i] = entityIDToMaterialHandle[matEntityId]; - } - uint[] masks = new uint[materials.Length]; - for (int i = 0; i < masks.Length; i++) - { - masks[i] = materials[i] != null ? 1u : 0u; - } - - InstanceHandle instance = world.AddInstance(mesh, materialHandles, masks, in localToWorldMatrix); - var entityID = meshRenderer.GetEntityId(); - Debug.Assert(!entityIDToInstanceHandle.ContainsKey(entityID)); - entityIDToInstanceHandle.Add(entityID, instance); - } - - foreach (var meshRendererUpdate in changedMeshRenderers) - { - var meshRenderer = meshRendererUpdate.instance; - var gameObject = meshRenderer.gameObject; - - Debug.Assert(entityIDToInstanceHandle.ContainsKey(meshRenderer.GetEntityId())); - var instanceHandle = entityIDToInstanceHandle[meshRenderer.GetEntityId()]; - - if ((meshRendererUpdate.changes & ModifiedProperties.Transform) != 0) - { - world.UpdateInstanceTransform(instanceHandle, gameObject.transform.localToWorldMatrix); - } - - if ((meshRendererUpdate.changes & ModifiedProperties.Material) != 0) - { - var materials = Util.GetMaterials(meshRenderer); - var materialHandles = new MaterialHandle[materials.Length]; - for (int i = 0; i < materials.Length; i++) - { - var matEntityId = materials[i] == null ? fallbackMaterial.GetEntityId() : materials[i].GetEntityId(); - materialHandles[i] = entityIDToMaterialHandle[matEntityId]; - } - - world.UpdateInstanceMaterials(instanceHandle, materialHandles); - - uint[] masks = new uint[materials.Length]; - for (int i = 0; i < masks.Length; i++) - { - masks[i] = materials[i] != null ? 1u : 0u; - } - - world.UpdateInstanceMask(instanceHandle, masks); - } - } - } - - private void UpdateTerrains( - SurfaceCacheWorld world, - Dictionary entityIDToInstanceHandle, - Dictionary entityIDToMaterialHandle, - List addedTerrains, - List changedTerrains, - List removedTerrains, - Material fallbackMaterial) - { - foreach (var terrainEntityID in removedTerrains) - { - if (entityIDToInstanceHandle.TryGetValue(terrainEntityID, out var instanceHandle)) - { - world.RemoveInstance(instanceHandle); - entityIDToInstanceHandle.Remove(terrainEntityID); - } - } - - foreach (var terrain in addedTerrains) - { - var localToWorldMatrix = terrain.transform.localToWorldMatrix; - - var material = terrain.splatBaseMaterial; - var matEntityId = material == null ? fallbackMaterial.GetEntityId() : material.GetEntityId(); - var materialHandle = entityIDToMaterialHandle[matEntityId]; - uint mask = 1u; - - InstanceHandle instance = world.AddInstance(terrain, materialHandle, mask, in localToWorldMatrix); - var entityID = terrain.GetEntityId(); - Debug.Assert(!entityIDToInstanceHandle.ContainsKey(entityID)); - entityIDToInstanceHandle.Add(entityID, instance); - } - - foreach (var terrainUpdate in changedTerrains) - { - var terrain = terrainUpdate.instance; - var gameObject = terrain.gameObject; - - Debug.Assert(entityIDToInstanceHandle.ContainsKey(terrain.GetEntityId())); - var instanceHandle = entityIDToInstanceHandle[terrain.GetEntityId()]; - - if ((terrainUpdate.changes & ModifiedProperties.Transform) != 0) - { - world.UpdateInstanceTransform(instanceHandle, gameObject.transform.localToWorldMatrix); - } - - if ((terrainUpdate.changes & ModifiedProperties.Material) != 0) - { - var material = terrain.splatBaseMaterial; - - var matEntityId = material == null ? fallbackMaterial.GetEntityId() : material.GetEntityId(); - var materialHandle = entityIDToMaterialHandle[matEntityId]; - - world.UpdateInstanceMaterials(instanceHandle, new MaterialHandle[] { materialHandle }); - - var mask = material != null ? 1u : 0u; - - world.UpdateInstanceMask(instanceHandle, new uint[] { mask } ); - } - } - } - - public void Dispose() - { - CoreUtils.Destroy(_fallbackMaterialDescriptor.Albedo); - CoreUtils.Destroy(_fallbackMaterialDescriptor.Emission); - CoreUtils.Destroy(_fallbackMaterialDescriptor.Transmission); - } - - internal static SurfaceCacheWorld.LightDescriptor[] ConvertUnityLightsToLightDescriptors(Light[] lights, bool multiplyPunctualLightIntensityByPI) - { - var descriptors = new SurfaceCacheWorld.LightDescriptor[lights.Length]; - for (int i = 0; i < lights.Length; i++) - { - Light light = lights[i]; - ref SurfaceCacheWorld.LightDescriptor descriptor = ref descriptors[i]; - descriptor.Type = light.type; - descriptor.LinearLightColor = Util.GetLinearLightColor(light) * light.bounceIntensity; - if (multiplyPunctualLightIntensityByPI && Util.IsPunctualLightType(light.type)) - descriptor.LinearLightColor *= Mathf.PI; - descriptor.Transform = light.transform.localToWorldMatrix; - descriptor.ColorTemperature = light.colorTemperature; - descriptor.SpotAngle = light.spotAngle; - descriptor.InnerSpotAngle = light.innerSpotAngle; - descriptor.Range = light.range; - } - return descriptors; - } - } - private SurfaceCachePass _pass; private RayTracingContext _rtContext; [SerializeField] private ParameterSet _parameterSet = new ParameterSet(); - [Serializable] - class EstimationParameterSet - { - public uint SampleCount = 2; - } - - [Serializable] - class PatchFilteringParameterSet - { - public float TemporalSmoothing = 0.8f; - public bool SpatialFilterEnabled = true; - public uint SpatialFilterSampleCount = 4; - public float SpatialFilterRadius = 1.0f; - public bool TemporalPostFilterEnabled = true; - } - - [Serializable] - class ScreenFilteringParameterSet - { - public uint LookupSampleCount = 8; - public float UpsamplingKernelSize = 5.0f; - public uint UpsamplingSampleCount = 3; - } - - [Serializable] - class VolumeParameterSet - { - public uint Resolution = 32; - public float Size = 128.0f; - public uint CascadeCount = 4; - public bool Movement = true; - } - - [Serializable] - class AdvancedParameterSet - { - public uint DefragCount = 2; - } - + // Main parameter set containing advanced and debug settings. [Serializable] class ParameterSet { - public bool MultiBounce = true; - - public EstimationParameterSet EstimationParams = new EstimationParameterSet(); - public PatchFilteringParameterSet PatchFilteringParams = new PatchFilteringParameterSet(); - public ScreenFilteringParameterSet ScreenFilteringParams = new ScreenFilteringParameterSet(); - public VolumeParameterSet VolumeParams = new VolumeParameterSet(); - public AdvancedParameterSet AdvancedParams = new AdvancedParameterSet(); - + // Debug settings (will be moved to rendering debugger in the future) public bool DebugEnabled = false; public DebugViewMode_ DebugViewMode = DebugViewMode_.CellIndex; public bool DebugShowSamplePosition = false; @@ -1237,85 +959,98 @@ void ClearResources() _rtContext = null; } + // Parameters extracted from Volume override each frame + private struct VolumeParameterSet + { + public SurfaceCacheEstimationParameterSet EstimationParams; + public SurfaceCachePatchFilteringParameterSet PatchFilteringParams; + public SurfaceCacheScreenFilteringParameterSet ScreenFilteringParams; + public bool CascadeMovement; + public float VolumeSize; + public uint VolumeResolution; + public uint VolumeCascadeCount; + public uint DefragCount; + } + + bool ResourcesCreated() + { + return _pass != null; + } + public override void Create() { ClearResources(); - if (isActive) - { - var rtBackend = RayTracingBackend.Compute; + if (!isActive) + return; - { - var resources = new RayTracingResources(); #if UNITY_EDITOR - resources.Load(); -#else - resources.LoadFromRenderPipelineResources(); + if (CheckStaticBatchingStatus()) + return; #endif - _rtContext = new RayTracingContext(rtBackend, resources); - } - var universalRenderPipelineResources = GraphicsSettings.GetRenderPipelineSettings(); - Debug.Assert(universalRenderPipelineResources != null); + var rtBackend = SystemInfo.supportsRayTracing + ? RayTracingBackend.Hardware + : RayTracingBackend.Compute; - var worldResources = new WorldResourceSet(); - var worldLoadResult = worldResources.LoadFromRenderPipelineResources(); - Debug.Assert(worldLoadResult); + { + var resources = new RayTracingResources(); +#if UNITY_EDITOR + resources.Load(); +#else + resources.LoadFromRenderPipelineResources(); +#endif + _rtContext = new RayTracingContext(rtBackend, resources); + } - var coreResources = new Rendering.SurfaceCacheResourceSet((uint)SystemInfo.computeSubGroupSize); - var coreResourceLoadResult = coreResources.LoadFromRenderPipelineResources(_rtContext); - Debug.Assert(coreResourceLoadResult); + var universalRenderPipelineResources = GraphicsSettings.GetRenderPipelineSettings(); + Debug.Assert(universalRenderPipelineResources != null); - var volParams = new SurfaceCacheVolumeParameterSet - { - Resolution = _parameterSet.VolumeParams.Resolution, - Size = _parameterSet.VolumeParams.Size, - CascadeCount = _parameterSet.VolumeParams.CascadeCount - }; + var worldResources = new WorldResourceSet(); + var worldLoadResult = worldResources.LoadFromRenderPipelineResources(); + Debug.Assert(worldLoadResult); - var estimationParams = new SurfaceCacheEstimationParameterSet - { - MultiBounce = _parameterSet.MultiBounce, - SampleCount = _parameterSet.EstimationParams.SampleCount, - }; + var coreResources = new Rendering.SurfaceCacheResourceSet((uint)SystemInfo.computeSubGroupSize); + var coreResourceLoadResult = coreResources.LoadFromRenderPipelineResources(_rtContext); + Debug.Assert(coreResourceLoadResult); - var patchFilteringParams = new SurfaceCachePatchFilteringParameterSet - { - TemporalSmoothing = _parameterSet.PatchFilteringParams.TemporalSmoothing, - SpatialFilterEnabled = _parameterSet.PatchFilteringParams.SpatialFilterEnabled, - SpatialFilterSampleCount = _parameterSet.PatchFilteringParams.SpatialFilterSampleCount, - SpatialFilterRadius = _parameterSet.PatchFilteringParams.SpatialFilterRadius, - TemporalPostFilterEnabled = _parameterSet.PatchFilteringParams.TemporalPostFilterEnabled - }; - - _pass = new SurfaceCachePass( - _rtContext, - coreResources, - worldResources, - universalRenderPipelineResources.allocationShader, - universalRenderPipelineResources.screenResolveLookupShader, - universalRenderPipelineResources.screenResolveUpsamplingShader, - universalRenderPipelineResources.debugShader, - universalRenderPipelineResources.flatNormalResolutionShader, - universalRenderPipelineResources.fallbackMaterial, - _parameterSet.DebugEnabled, - _parameterSet.DebugViewMode, - _parameterSet.DebugShowSamplePosition, - _parameterSet.ScreenFilteringParams.LookupSampleCount, - _parameterSet.ScreenFilteringParams.UpsamplingKernelSize, - _parameterSet.ScreenFilteringParams.UpsamplingSampleCount, - _parameterSet.AdvancedParams.DefragCount, - volParams, - estimationParams, - patchFilteringParams, - _parameterSet.VolumeParams.Movement); - - _pass.renderPassEvent = RenderPassEvent.AfterRenderingPrePasses + 1; - } + // Use defaults for initial volume configuration; runtime values come from the Volume override per-frame + var volParams = new SurfaceCacheVolumeParameterSet + { + Resolution = DEFAULT_VOLUME_RESOLUTION, + Size = DEFAULT_VOLUME_SIZE, + CascadeCount = DEFAULT_VOLUME_CASCADE_COUNT + }; + + _pass = new SurfaceCachePass( + _rtContext, + coreResources, + worldResources, + universalRenderPipelineResources.allocationShader, + universalRenderPipelineResources.screenResolveLookupShader, + universalRenderPipelineResources.screenResolveUpsamplingShader, + universalRenderPipelineResources.debugShader, + universalRenderPipelineResources.flatNormalResolutionShader, + universalRenderPipelineResources.fallbackMaterial, + _parameterSet.DebugEnabled, + _parameterSet.DebugViewMode, + _parameterSet.DebugShowSamplePosition, + defragCount: DEFAULT_DEFRAG_COUNT, + volParams); + + _pass.renderPassEvent = RenderPassEvent.AfterRenderingPrePasses + 1; } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { +#if UNITY_EDITOR + if (CheckStaticBatchingStatus()) + return; + + if (!ResourcesCreated()) // can happen if static batching is disabled after the SurfaceCacheGIRendererFeature has been created + Create(); +#endif + ScriptableRenderPassInput inputs = ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal; if (UseMotionVectorPatchSeeding(renderingData.cameraData.cameraType)) { @@ -1330,6 +1065,20 @@ protected override void Dispose(bool disposing) ClearResources(); base.Dispose(disposing); } + +#if UNITY_EDITOR + bool _staticBatchingEnabled; + bool CheckStaticBatchingStatus() + { + bool previousStatus = _staticBatchingEnabled; + _staticBatchingEnabled = UnityEditor.PlayerSettings.GetStaticBatchingForPlatform(UnityEditor.EditorUserBuildSettings.activeBuildTarget); + + if (_staticBatchingEnabled && _staticBatchingEnabled != previousStatus) + Debug.LogError(k_StaticBatchingErrorMesssage); + + return _staticBatchingEnabled; + } +#endif } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs new file mode 100644 index 00000000000..d255a20f55a --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs @@ -0,0 +1,576 @@ +#if SURFACE_CACHE + +using System; +using System.Collections.Generic; +using UnityEngine.PathTracing.Core; +using UnityEngine.Rendering.LiveGI; +using InstanceHandle = UnityEngine.PathTracing.Core.Handle; +using LightHandle = UnityEngine.PathTracing.Core.Handle; +using MaterialHandle = UnityEngine.PathTracing.Core.Handle; + +namespace UnityEngine.Rendering.Universal +{ + class SurfaceCacheWorldAdapter : IDisposable + { + // This dictionary maps from Unity EntityID for MeshRenderer or Terrain, to corresponding InstanceHandle for accessing World. + private readonly Dictionary _entityIDToWorldInstanceHandles = new(); + + // Same as above but for Lights + private readonly Dictionary _entityIDToWorldLightHandles = new(); + + // Same as above but for Materials + private Dictionary _entityIDToWorldMaterialHandles = new(); + + // We also keep track of associated material descriptors, so we can free temporary temporary textures when a material is removed + private Dictionary _entityIDToWorldMaterialDescriptors = new(); + + private Material _fallbackMaterial; + private MaterialPool.MaterialDescriptor _fallbackMaterialDescriptor; + private MaterialHandle _fallbackMaterialHandle; + + // Maps TerrainData EntityID to list of Terrains that use that TerrainData + private readonly Dictionary> _terrainDataToTerrains = new(); + +#if UNITY_EDITOR + private class TerrainRebuild + { + public Terrain terrain; + public double timeSinceLastChange; + public EntityId materialEntityId; + } + + private readonly Dictionary _deferredTerrainRebuilds = new(); + private const double k_TerrainRebuildDelay = 0.5; +#endif + + public SurfaceCacheWorldAdapter(SurfaceCacheWorld world, Material fallbackMaterial) + { + _fallbackMaterial = fallbackMaterial; + _fallbackMaterialDescriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(fallbackMaterial, EmissionMode.Realtime); + _fallbackMaterialHandle = world.AddMaterial(in _fallbackMaterialDescriptor, UVChannel.UV0); + _entityIDToWorldMaterialHandles.Add(fallbackMaterial.GetEntityId(), _fallbackMaterialHandle); + _entityIDToWorldMaterialDescriptors.Add(fallbackMaterial.GetEntityId(), _fallbackMaterialDescriptor); + } + + internal void Update(SceneUpdatesTracker sceneTracker, AmbientMode ambientMode, Material skyboxMaterial, Color ambientSkycolor, SurfaceCacheWorld world) + { + const bool filterBakedLights = true; + var changes = sceneTracker.GetChanges(filterBakedLights); + + UpdateMaterials(world, changes.addedMaterials, changes.removedMaterials, changes.changedMaterials); + UpdateMeshRenderers( + world, + changes.addedMeshRenderers, + changes.changedMeshRenderers, + changes.removedMeshRenderers); + UpdateTerrains( + world, + changes.addedTerrains, + changes.changedTerrains, + changes.removedTerrains, + changes.addedTerrainData, + changes.changedTerrainData, + changes.removedTerrainData); + + const bool multiplyPunctualLightIntensityByPI = false; + UpdateLights(world, changes.addedLights, changes.removedLights, changes.changedLights, multiplyPunctualLightIntensityByPI); + + if (ambientMode == AmbientMode.Skybox) + { + world.SetEnvironmentMode(CubemapRender.Mode.Material); + world.SetEnvironmentMaterial(skyboxMaterial); + } + else if (ambientMode == AmbientMode.Flat) + { + world.SetEnvironmentMode(CubemapRender.Mode.Color); + world.SetEnvironmentColor(ambientSkycolor); + } + else + { + world.SetEnvironmentMode(CubemapRender.Mode.Color); + world.SetEnvironmentColor(Color.black); + } + } + + private void UpdateMaterials(SurfaceCacheWorld world, List addedMaterials, List removedMaterials, List changedMaterials) + { + UpdateMaterials(world, _entityIDToWorldMaterialHandles, _entityIDToWorldMaterialDescriptors, addedMaterials, removedMaterials, changedMaterials); + } + + private static void UpdateMaterials(SurfaceCacheWorld world, Dictionary entityIDToHandle, Dictionary entityIDToDescriptor, List addedMaterials, List removedMaterials, List changedMaterials) + { + static void DeleteTemporaryTextures(ref MaterialPool.MaterialDescriptor desc) + { + CoreUtils.Destroy(desc.Albedo); + CoreUtils.Destroy(desc.Emission); + CoreUtils.Destroy(desc.Transmission); + } + + foreach (var entityID in removedMaterials) + { + // Clean up temporary textures in the descriptor + Debug.Assert(entityIDToDescriptor.ContainsKey(entityID)); + var descriptor = entityIDToDescriptor[entityID]; + DeleteTemporaryTextures(ref descriptor); + entityIDToDescriptor.Remove(entityID); + + // Remove the material from the world + Debug.Assert(entityIDToHandle.ContainsKey(entityID)); + world.RemoveMaterial(entityIDToHandle[entityID]); + entityIDToHandle.Remove(entityID); + } + + foreach (var material in addedMaterials) + { + // Add material to the world + var descriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(material, EmissionMode.Realtime); + var handle = world.AddMaterial(in descriptor, UVChannel.UV0); + entityIDToHandle.Add(material.GetEntityId(), handle); + + // Keep track of the descriptor + entityIDToDescriptor.Add(material.GetEntityId(), descriptor); + } + + foreach (var material in changedMaterials) + { + // Clean up temporary textures in the old descriptor + Debug.Assert(entityIDToDescriptor.ContainsKey(material.GetEntityId())); + var oldDescriptor = entityIDToDescriptor[material.GetEntityId()]; + DeleteTemporaryTextures(ref oldDescriptor); + + // Update the material in the world using the new descriptor + Debug.Assert(entityIDToHandle.ContainsKey(material.GetEntityId())); + var newDescriptor = MaterialPool.ConvertUnityMaterialToMaterialDescriptor(material, EmissionMode.Realtime); + world.UpdateMaterial(entityIDToHandle[material.GetEntityId()], in newDescriptor, UVChannel.UV0); + entityIDToDescriptor[material.GetEntityId()] = newDescriptor; + } + } + + private void UpdateLights(SurfaceCacheWorld world, List addedLights, List removedLights, + List changedLights, bool multiplyPunctualLightIntensityByPI) + { + UpdateLights(world, _entityIDToWorldLightHandles, addedLights, removedLights, changedLights, multiplyPunctualLightIntensityByPI); + } + + private static void UpdateLights( + SurfaceCacheWorld world, + Dictionary entityIDToHandle, List addedLights, List removedLights, + List changedLights, + bool multiplyPunctualLightIntensityByPI) + { + // Remove deleted lights + LightHandle[] handlesToRemove = new LightHandle[removedLights.Count]; + for (int i = 0; i < removedLights.Count; i++) + { + var lightEntityID = removedLights[i]; + handlesToRemove[i] = entityIDToHandle[lightEntityID]; + entityIDToHandle.Remove(lightEntityID); + } + world.RemoveLights(handlesToRemove); + + // Add new lights + var lightDescriptors = ConvertUnityLightsToLightDescriptors(addedLights.ToArray(), multiplyPunctualLightIntensityByPI); + LightHandle[] addedHandles = world.AddLights(lightDescriptors); + for (int i = 0; i < addedLights.Count; ++i) + entityIDToHandle.Add(addedLights[i].GetEntityId(), addedHandles[i]); + + // Update changed lights + LightHandle[] handlesToUpdate = new LightHandle[changedLights.Count]; + for (int i = 0; i < changedLights.Count; i++) + handlesToUpdate[i] = entityIDToHandle[changedLights[i].GetEntityId()]; + + world.UpdateLights(handlesToUpdate, ConvertUnityLightsToLightDescriptors(changedLights.ToArray(), multiplyPunctualLightIntensityByPI)); + } + + private void UpdateMeshRenderers( + SurfaceCacheWorld world, + List addedMeshRenderers, + List changedMeshRenderers, + List removedMeshRenderers) + { + UpdateMeshRenderers(world, _entityIDToWorldInstanceHandles, _entityIDToWorldMaterialHandles, addedMeshRenderers, changedMeshRenderers, removedMeshRenderers, _fallbackMaterial); + } + + private static void UpdateMeshRenderers( + SurfaceCacheWorld world, + Dictionary entityIDToInstanceHandle, + Dictionary entityIDToMaterialHandle, + List addedMeshRenderers, + List changedMeshRenderers, + List removedMeshRenderers, + Material fallbackMaterial) + { + foreach (var meshRendererEntityID in removedMeshRenderers) + { + if (entityIDToInstanceHandle.TryGetValue(meshRendererEntityID, out var instanceHandle)) + { + world.RemoveInstance(instanceHandle); + entityIDToInstanceHandle.Remove(meshRendererEntityID); + } + } + + foreach (var meshRenderer in addedMeshRenderers) + { + Debug.Assert(!meshRenderer.isPartOfStaticBatch, "Static Batching is not supported by Surface Cache GI."); + + var mesh = meshRenderer.GetComponent().sharedMesh; + + if (mesh == null || mesh.vertexCount == 0) + continue; + + var localToWorldMatrix = meshRenderer.transform.localToWorldMatrix; + + var materials = Util.GetMaterials(meshRenderer); + var materialHandles = new MaterialHandle[materials.Length]; + for (int i = 0; i < materials.Length; i++) + { + var matEntityId = materials[i] == null ? fallbackMaterial.GetEntityId() : materials[i].GetEntityId(); + materialHandles[i] = entityIDToMaterialHandle[matEntityId]; + } + uint[] masks = new uint[materials.Length]; + for (int i = 0; i < masks.Length; i++) + { + masks[i] = materials[i] != null ? 1u : 0u; + } + + InstanceHandle instance = world.AddInstance(mesh, materialHandles, masks, in localToWorldMatrix); + var entityID = meshRenderer.GetEntityId(); + Debug.Assert(!entityIDToInstanceHandle.ContainsKey(entityID)); + entityIDToInstanceHandle.Add(entityID, instance); + } + + foreach (var meshRendererUpdate in changedMeshRenderers) + { + var meshRenderer = meshRendererUpdate.meshRenderer; + var gameObject = meshRenderer.gameObject; + + Debug.Assert(entityIDToInstanceHandle.ContainsKey(meshRenderer.GetEntityId())); + var instanceHandle = entityIDToInstanceHandle[meshRenderer.GetEntityId()]; + + if ((meshRendererUpdate.changes & ModifiedProperties.Transform) != 0) + { + world.UpdateInstanceTransform(instanceHandle, gameObject.transform.localToWorldMatrix); + } + + if ((meshRendererUpdate.changes & ModifiedProperties.Material) != 0) + { + var materials = Util.GetMaterials(meshRenderer); + var materialHandles = new MaterialHandle[materials.Length]; + for (int i = 0; i < materials.Length; i++) + { + var matEntityId = materials[i] == null ? fallbackMaterial.GetEntityId() : materials[i].GetEntityId(); + materialHandles[i] = entityIDToMaterialHandle[matEntityId]; + } + + world.UpdateInstanceMaterials(instanceHandle, materialHandles); + + uint[] masks = new uint[materials.Length]; + for (int i = 0; i < masks.Length; i++) + { + masks[i] = materials[i] != null ? 1u : 0u; + } + + world.UpdateInstanceMask(instanceHandle, masks); + } + } + } + + private void UpdateTerrains( + SurfaceCacheWorld world, + List addedTerrains, + List changedTerrains, + List removedTerrains, + List addedTerrainData, + List changedTerrainData, + List removedTerrainData) + { + UpdateTerrains(world, _entityIDToWorldInstanceHandles, _entityIDToWorldMaterialHandles, addedTerrains, changedTerrains, removedTerrains, addedTerrainData, changedTerrainData, removedTerrainData, _terrainDataToTerrains +#if UNITY_EDITOR + , _deferredTerrainRebuilds +#endif + , _fallbackMaterial); + } + + private static void UpdateTerrains( + SurfaceCacheWorld world, + Dictionary entityIDToInstanceHandle, + Dictionary entityIDToMaterialHandle, + List addedTerrains, + List changedTerrains, + List removedTerrains, + List addedTerrainData, + List changedTerrainData, + List removedTerrainData, + Dictionary> terrainDataToTerrains +#if UNITY_EDITOR + , Dictionary deferredTerrainRebuilds +#endif + , Material fallbackMaterial) + { + foreach (var terrainEntityID in removedTerrains) + { +#if UNITY_EDITOR + deferredTerrainRebuilds.Remove(terrainEntityID); +#endif + + if (entityIDToInstanceHandle.TryGetValue(terrainEntityID, out var instanceHandle)) + { + world.RemoveInstance(instanceHandle); + entityIDToInstanceHandle.Remove(terrainEntityID); + } + + foreach (var entry in terrainDataToTerrains) + { + var terrainToRemove = entry.Value.Find(t => t.GetEntityId() == terrainEntityID); + if (terrainToRemove != null) + { + entry.Value.Remove(terrainToRemove); + break; + } + } + } +#if UNITY_EDITOR + // Rebuild terrains whose heightmap/tree changes have been idle past the delay + ProcessDeferredTerrainRebuilds(world, entityIDToInstanceHandle, entityIDToMaterialHandle, deferredTerrainRebuilds, fallbackMaterial); +#endif + // Register existing terrains that were reassigned to this newly seen TerrainData + foreach (var terrainData in addedTerrainData) + { + var terrainDataEntityID = terrainData.GetEntityId(); + if (!terrainDataToTerrains.TryGetValue(terrainDataEntityID, out var terrainList)) + { + terrainList = new List(); + terrainDataToTerrains[terrainDataEntityID] = terrainList; + } + + var toMove = new List(); + foreach (var entry in terrainDataToTerrains) + { + if (entry.Key == terrainDataEntityID) + continue; + foreach (var terrain in entry.Value) + { + if (terrain.terrainData == terrainData && entityIDToInstanceHandle.ContainsKey(terrain.GetEntityId())) + toMove.Add(terrain); + } + } + + // Remove each reassigned terrain from its old list, add to this TerrainData's list, + // and rebuild the world instance so geometry matches the new TerrainData + foreach (var terrain in toMove) + { + foreach (var entry in terrainDataToTerrains) + { + if (entry.Value.Remove(terrain)) + break; + } + terrainList.Add(terrain); + var terrainEntityID = terrain.GetEntityId(); + if (!entityIDToInstanceHandle.TryGetValue(terrainEntityID, out var instanceHandle)) + continue; + var material = terrain.splatBaseMaterial; + var matEntityId = material == null ? fallbackMaterial.GetEntityId() : material.GetEntityId(); + RebuildTerrainInstance(world, entityIDToInstanceHandle, entityIDToMaterialHandle, + terrain, terrainEntityID, instanceHandle, matEntityId, fallbackMaterial); + } + } + + foreach (var terrain in addedTerrains) + { + var localToWorldMatrix = terrain.transform.localToWorldMatrix; + + var material = terrain.splatBaseMaterial; + var matEntityId = material == null ? fallbackMaterial.GetEntityId() : material.GetEntityId(); + var materialHandle = entityIDToMaterialHandle[matEntityId]; + uint mask = 1u; + + InstanceHandle instance = world.AddInstance(terrain, materialHandle, mask, in localToWorldMatrix); + var entityID = terrain.GetEntityId(); + Debug.Assert(!entityIDToInstanceHandle.ContainsKey(entityID)); + entityIDToInstanceHandle.Add(entityID, instance); + + var terrainData = terrain.terrainData; + if (terrainData != null) + { + var terrainDataEntityID = terrainData.GetEntityId(); + if (!terrainDataToTerrains.TryGetValue(terrainDataEntityID, out var terrainList)) + { + terrainList = new List(); + terrainDataToTerrains[terrainDataEntityID] = terrainList; + } + + if (!terrainList.Contains(terrain)) + { + terrainList.Add(terrain); + } + } + } + + foreach (var terrainUpdate in changedTerrains) + { + var terrain = terrainUpdate.terrain; + var gameObject = terrain.gameObject; + + Debug.Assert(entityIDToInstanceHandle.ContainsKey(terrain.GetEntityId())); + var instanceHandle = entityIDToInstanceHandle[terrain.GetEntityId()]; + + if ((terrainUpdate.changes & ModifiedProperties.Transform) != 0) + { + world.UpdateInstanceTransform(instanceHandle, gameObject.transform.localToWorldMatrix); + } + + if ((terrainUpdate.changes & ModifiedProperties.Material) != 0) + { + var material = terrain.splatBaseMaterial; + + var matEntityId = material == null ? fallbackMaterial.GetEntityId() : material.GetEntityId(); + var materialHandle = entityIDToMaterialHandle[matEntityId]; + + world.UpdateInstanceMaterials(instanceHandle, new MaterialHandle[] { materialHandle }); + + var mask = material != null ? 1u : 0u; + + world.UpdateInstanceMask(instanceHandle, new uint[] { mask }); + } + } + + foreach (var terrainDataEntityID in removedTerrainData) + { + terrainDataToTerrains.Remove(terrainDataEntityID); + } + + foreach (var terrainDataUpdate in changedTerrainData) + { + var terrainData = terrainDataUpdate.terrainData; + var changes = terrainDataUpdate.changes; + + var terrainDataEntityID = terrainData.GetEntityId(); + if (!terrainDataToTerrains.TryGetValue(terrainDataEntityID, out var affectedTerrains)) + continue; + + if ((changes & ModifiedProperties.Heightmap) == 0 && (changes & ModifiedProperties.Holes) == 0) + continue; + + foreach (var terrain in affectedTerrains) + { + var terrainEntityID = terrain.GetEntityId(); + + if (!entityIDToInstanceHandle.TryGetValue(terrainEntityID, out var instanceHandle)) + continue; + + var material = terrain.splatBaseMaterial; + var matEntityId = material == null ? fallbackMaterial.GetEntityId() : material.GetEntityId(); + +#if UNITY_EDITOR + // Delay the removing and re-adding the terrain when in the editor + // to avoid lag when the user is actively editing the terrain + if (deferredTerrainRebuilds.TryGetValue(terrainEntityID, out var pending)) + { + pending.timeSinceLastChange = UnityEditor.EditorApplication.timeSinceStartup; + pending.materialEntityId = matEntityId; + } + else + { + deferredTerrainRebuilds[terrainEntityID] = new TerrainRebuild + { + terrain = terrain, + timeSinceLastChange = UnityEditor.EditorApplication.timeSinceStartup, + materialEntityId = matEntityId + }; + } +#else + // Immediately remove and re-add the terrain to World in a Player + RebuildTerrainInstance(world, entityIDToInstanceHandle, entityIDToMaterialHandle, + terrain, terrainEntityID, instanceHandle, matEntityId, fallbackMaterial); +#endif + } + } + } + +#if UNITY_EDITOR + private static void ProcessDeferredTerrainRebuilds( + SurfaceCacheWorld world, + Dictionary entityIDToInstanceHandle, + Dictionary entityIDToMaterialHandle, + Dictionary terrainRebuilds, + Material fallbackMaterial) + { + // Rebuild terrains that have been idle past the delay (avoids lag while editing) + var currentTime = UnityEditor.EditorApplication.timeSinceStartup; + var terrainsToRebuild = new List(); + + foreach (var entry in terrainRebuilds) + { + if (currentTime - entry.Value.timeSinceLastChange >= k_TerrainRebuildDelay) + { + terrainsToRebuild.Add(entry.Key); + } + } + + foreach (var terrainEntityID in terrainsToRebuild) + { + var pending = terrainRebuilds[terrainEntityID]; + + if (entityIDToInstanceHandle.TryGetValue(terrainEntityID, out var instanceHandle)) + { + RebuildTerrainInstance(world, entityIDToInstanceHandle, entityIDToMaterialHandle, pending.terrain, terrainEntityID, instanceHandle, pending.materialEntityId, fallbackMaterial); + } + + terrainRebuilds.Remove(terrainEntityID); + } + } +#endif + + private static void RebuildTerrainInstance( + SurfaceCacheWorld world, + Dictionary entityIDToInstanceHandle, + Dictionary entityIDToMaterialHandle, + Terrain terrain, + EntityId terrainEntityID, + InstanceHandle instanceHandle, + EntityId materialEntityId, + Material fallbackMaterial) + { + world.RemoveInstance(instanceHandle); + entityIDToInstanceHandle.Remove(terrainEntityID); + + var localToWorldMatrix = terrain.transform.localToWorldMatrix; + var fallbackMaterialHandle = entityIDToMaterialHandle[fallbackMaterial.GetEntityId()]; + var materialHandle = entityIDToMaterialHandle.GetValueOrDefault(materialEntityId, fallbackMaterialHandle); + uint mask = 1u; + + InstanceHandle instance = world.AddInstance(terrain, materialHandle, mask, in localToWorldMatrix); + Debug.Assert(!entityIDToInstanceHandle.ContainsKey(terrainEntityID)); + entityIDToInstanceHandle.Add(terrainEntityID, instance); + } + + public void Dispose() + { + CoreUtils.Destroy(_fallbackMaterialDescriptor.Albedo); + CoreUtils.Destroy(_fallbackMaterialDescriptor.Emission); + CoreUtils.Destroy(_fallbackMaterialDescriptor.Transmission); + } + + internal static SurfaceCacheWorld.LightDescriptor[] ConvertUnityLightsToLightDescriptors(Light[] lights, bool multiplyPunctualLightIntensityByPI) + { + var descriptors = new SurfaceCacheWorld.LightDescriptor[lights.Length]; + for (int i = 0; i < lights.Length; i++) + { + Light light = lights[i]; + ref SurfaceCacheWorld.LightDescriptor descriptor = ref descriptors[i]; + descriptor.Type = light.type; + descriptor.LinearLightColor = Util.GetLinearLightColor(light, light.bounceIntensity); + if (multiplyPunctualLightIntensityByPI && Util.IsPunctualLightType(light.type)) + descriptor.LinearLightColor *= Mathf.PI; + descriptor.Transform = light.transform.localToWorldMatrix; + descriptor.ColorTemperature = light.colorTemperature; + descriptor.OuterSpotAngle = light.spotAngle; + descriptor.InnerSpotAngle = light.innerSpotAngle; + descriptor.Range = light.range; + } + return descriptors; + } + } +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs.meta b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs.meta new file mode 100644 index 00000000000..dda7ca459d7 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RendererFeatures/SurfaceCacheGIRendererFeature/SurfaceCacheWorldAdapter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6c248cf2ddea4b50b8f4e25e0e157a93 +timeCreated: 1773046475 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs b/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs index e1e5e6953f2..3daca3a2cd4 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs @@ -3,6 +3,7 @@ using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; using UnityEngine.Experimental.Rendering; +using UnityEngine.Rendering; using UnityEngine.Rendering.RenderGraphModule; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -95,6 +96,35 @@ internal static bool SupportsLightLayers(GraphicsDeviceType type) return true; } + /// + /// Returns true if the given ScriptableRenderPassInput requirements are compatible with Tile-Only Mode on the Universal Renderer. + /// Reusable for any ScriptableRenderPass. + /// + /// The pass input requirements. + /// The event at which the pass runs. When only Depth (or Motion) is requested without Normal, a pass before or at BeforeRenderingOpaques gets a prepass instead of a depth copy, so it remains compatible. + /// + /// This method mirrors how the render pipeline fulfills pass input requirements. Keep it in sync with pipeline behavior: + /// + /// Color: The pipeline adds a copy color pass and exposes the result as a global texture. That store/load cannot stay on tile and triggers Tile-Only validation. + /// Depth without Normal: The pipeline fulfills depth-only by adding a depth copy pass when the pass runs after opaque. When the pass runs at or before BeforeRenderingOpaques, the pipeline adds a prepass instead, which is compatible. + /// Motion without Normal: Motion implies depth; same as Depth without Normal with respect to prepass vs copy and renderPassEvent. + /// + /// When adding or changing requirements or pipeline behavior, update this method and the corresponding editor validation (e.g. FullScreenPassRendererFeatureEditor) so they stay consistent. + /// + internal static bool IsCompatibleWithTileOnlyMode(ScriptableRenderPassInput requirements, RenderPassEvent renderPassEvent) + { + if ((requirements & ScriptableRenderPassInput.Color) != ScriptableRenderPassInput.None) + return false; + // Depth without Normal: pipeline uses a depth copy when the pass runs after opaque; when pass is before or at opaque, pipeline adds a prepass instead (compatible). + if ((requirements & ScriptableRenderPassInput.Depth) != ScriptableRenderPassInput.None && (requirements & ScriptableRenderPassInput.Normal) == ScriptableRenderPassInput.None + && renderPassEvent > RenderPassEvent.BeforeRenderingOpaques) + return false; + if ((requirements & ScriptableRenderPassInput.Motion) != ScriptableRenderPassInput.None && (requirements & ScriptableRenderPassInput.Normal) == ScriptableRenderPassInput.None + && renderPassEvent > RenderPassEvent.BeforeRenderingOpaques) + return false; + return true; + } + static Material s_ErrorMaterial; static Material errorMaterial { @@ -809,12 +839,98 @@ internal static Vector4 GetFinalBlitScaleBias(in RasterGraphContext renderGraphC { RTHandle srcRTHandle = source; Vector2 scale = srcRTHandle is { useScaling: true } ? new Vector2(srcRTHandle.rtHandleProperties.rtHandleScale.x, srcRTHandle.rtHandleProperties.rtHandleScale.y) : Vector2.one; + var yflip = renderGraphContext.GetTextureUVOrigin(in source) != renderGraphContext.GetTextureUVOrigin(in destination); + Vector4 scaleBias = yflip ? new Vector4(scale.x, -scale.y, 0, scale.y) : new Vector4(scale.x, scale.y, 0, 0); return scaleBias; } + /// + /// Returns the TextureUVOrigin of the real backbuffer for the current graphics API. In modern graphics APIs like + /// Vulkan or Metal, this will return TopLeft. For OpenGL, WebGL, GLES, this will return BottomLeft. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static TextureUVOrigin GetRealBackBufferUVOrientation() + { + return SystemInfo.graphicsUVStartsAtTop ? TextureUVOrigin.TopLeft : TextureUVOrigin.BottomLeft; + } + + /// + /// Returns the TextureUVOrigin of the UniversalResourceData.backBuffer. This resource is not always the real backbuffer. + /// To get the TextureUVOrigin of the real backbuffer, use GetRealBackBufferUVOrientation(). + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static TextureUVOrigin GetBackBufferUVOrientation(UniversalCameraData cameraData) + { + // Backbuffer orientation is used for either the actual backbuffer (not a texture), or in XR for the eye texture. + bool useRealBackbufferOrientation = !cameraData.isSceneViewCamera && !cameraData.isPreviewCamera && cameraData.targetTexture == null; + return useRealBackbufferOrientation ? RenderingUtils.GetRealBackBufferUVOrientation() : TextureUVOrigin.BottomLeft; + } + /// + /// Returns the TextureUVOrigin of the camera targets. These include the intermediate textures (UniversalResourceData.cameraColor, cameraDepth), + /// the Gbuffers (UniversalResourceData.gbuffer) and any copy of those. Since these are all textures, they normally are all using the + /// Unity texture convention of BottomLeft. However, in the On-Tile Renderer, these can adopt the backbuffer UV orientation. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static TextureUVOrigin GetCameraTargetsUVOrientation(UniversalCameraData cameraData) + { + var universalRenderer = cameraData.renderer as UniversalRenderer; + bool onTileRenderer = (universalRenderer == null) ? false : universalRenderer.useTileOnlyMode; + + if (onTileRenderer) + { + // The On-Tile renderer guarantees that the backbuffer orientation is propagated to + // the camera targets. + return GetBackBufferUVOrientation(cameraData); + } + else + { + return TextureUVOrigin.BottomLeft; + } + } + + /// + /// Computes the inverse view-projection matrix for a given texture UV origin. + /// This is critical for passes that reconstruct world positions from depth textures. + /// + /// THE PROBLEM: + /// Many rendering passes (ScreenSpaceShadows, SSAO, SSR, etc.) need to reconstruct world positions from screen-space depth. + /// The reconstruction process uses screen UVs [0,1] and depth to build clip-space coordinates [-1,1], then transforms + /// them to world space using the inverse view-projection matrix (unity_MatrixInvVP). + /// + /// However, the Y-axis direction in clip space depends on the texture's UV origin: + /// - BottomLeft (standard texture): UV(0,0) is bottom-left → clip(-1,-1) is bottom-left → Y increases upward + /// - TopLeft (backbuffer on modern APIs): UV(0,0) is top-left → clip(-1,+1) is top-left → Y increases downward + /// + /// The inverse VP matrix encodes this Y-flip assumption via _ProjectionParams.x. If the matrix was computed for TopLeft + /// but you're reconstructing from a BottomLeft depth texture, the Y-coordinate is inverted, resulting in incorrect + /// world positions (and thus wrong shadow lookups, SSAO samples, etc.). + /// + /// WHEN IT BREAKS: + /// - Tile-Only Mode: The active render target can be TopLeft (backbuffer), so unity_MatrixInvVP is set for TopLeft. + /// But cameraDepthTexture is always BottomLeft (intermediate texture). Mismatch → broken. + /// - Direct-to-backbuffer: Similar issue when rendering directly to a TopLeft backbuffer but sampling BottomLeft depth. + /// - After prepass: Camera properties are restored for the active target, overwriting the matrix that was correct + /// during the prepass. + /// + /// THE FIX: + /// Query the texture's actual UV origin (via GetTextureUVOrigin) and compute the inverse VP matrix that matches + /// how that texture was rendered. This ensures the reconstruction math is consistent with the source data. + /// + /// The UV origin of the texture (typically from GetTextureUVOrigin) + /// Camera data containing view and projection matrices + /// The inverse view-projection matrix matching the texture orientation + internal static Matrix4x4 ComputeInverseViewProjectionMatrix(TextureUVOrigin textureUVOrigin, UniversalCameraData cameraData) + { + bool isFlipped = (textureUVOrigin == TextureUVOrigin.BottomLeft); + Matrix4x4 projection = cameraData.GetGPUProjectionMatrix(isFlipped); + Matrix4x4 view = cameraData.GetViewMatrix(); + Matrix4x4 viewProj = CoreMatrixUtils.MultiplyProjectionMatrix(projection, view, cameraData.camera.orthographic); + return Matrix4x4.Inverse(viewProj); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static RTHandleAllocInfo CreateRTHandleAllocInfo(in RenderTextureDescriptor descriptor, FilterMode filterMode, TextureWrapMode wrapMode, int anisoLevel, float mipMapBias, string name) { diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index afbb82f563b..45d2f28b029 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -57,6 +57,8 @@ private static class Profiling internal static readonly ProfilingSampler setEditorTarget = new ProfilingSampler($"Set Editor Target"); } + internal string name { get; set; } + /// /// This setting controls if the camera editor should display the camera stack category. /// If your scriptable renderer is not supporting stacking this one should return 0. @@ -132,12 +134,23 @@ public class RenderingFeatures /// /// [Obsolete("cameraStacking has been deprecated use SupportedCameraRenderTypes() in ScriptableRenderer instead. #from(2022.2) #breakingFrom(2023.1)", true)] - public bool cameraStacking { get; set; } = false; + public bool cameraStacking { get; set; } = false; /// /// This setting controls if the Universal Render Pipeline asset should expose the MSAA option. /// public bool msaa { get; set; } = true; + + // Keeping these internal for now to validate the API. Once these would become public, carefully decide which setters should remain internal (with public getter). + internal bool overlayCamera { get; set; } = false; + internal bool supportsHDR { get; set; } = false; + internal bool postProcessing { get; set; } = false; + internal bool upscaling { get; set; } = false; + internal bool gpuOcclusionCulling { get; set; } = false; + internal bool antiAliasing { get; set; } = false; + internal bool cameraOpaqueTexture { get; set; } = false; + internal bool cameraDepthTexture { get; set; } = false; + internal bool deferredLighting { get; set; } = false; } /// @@ -430,6 +443,8 @@ protected List activeRenderPassQueue /// public RenderingFeatures supportedRenderingFeatures { get; set; } = new RenderingFeatures(); + internal virtual void UpdateSupportedRenderingFeatures() { } + /// /// List of unsupported Graphics APIs for this renderer.The scriptable renderer framework will use the returned information /// to adjust things like inspectors, etc. @@ -1138,6 +1153,9 @@ static void ClearRenderingState(IBaseCommandBuffer cmd) cmd.SetKeyword(ShaderGlobalKeywords.LightLayers, false); cmd.SetKeyword(ShaderGlobalKeywords.ScreenSpaceOcclusion, false); cmd.SetGlobalVector(ScreenSpaceAmbientOcclusionPass.s_AmbientOcclusionParamID, Vector4.zero); +#if URP_SCREEN_SPACE_REFLECTION + cmd.SetGlobalVector(ScreenSpaceReflectionPass.ShaderConstants._ReflectionParam, Vector4.zero); +#endif } // Scene filtering is enabled when in prefab editing mode @@ -1171,22 +1189,31 @@ void InternalFinishRenderingCommon(CommandBuffer cmd, bool resolveFinalTarget) } } - private protected int AdjustAndGetScreenMSAASamples(RenderGraph renderGraph, bool useIntermediateColorTarget) + private protected int AdjustAndGetScreenMSAASamples(RenderGraph renderGraph, bool intermediateTexturesAreSampledAsTextures) { // In the editor (ConfigureTargetTexture in PlayModeView.cs) and many platforms, the system render target is always allocated without MSAA if (!SystemInfo.supportsMultisampledBackBuffer) return 1; + // For mobile platforms, when URP main rendering is done to an intermediate target and NRP enabled // we disable multisampling for the system render target as a bandwidth optimization // doing so, we avoid storing costly MSAA samples back to system memory for nothing bool canOptimizeScreenMSAASamples = UniversalRenderPipeline.canOptimizeScreenMSAASamples - && useIntermediateColorTarget + && intermediateTexturesAreSampledAsTextures && Screen.msaaSamples > 1; + // We need to fix an issue where the MSAA samples are never set back to the Quality setting. + // The MSAA samples only seem to be set when the URP asset is changed. The optimization + // in this function seems fragile, because different renderers can be used, even + // in a single frame. If we change a renderer from rendering to the backbuffer (or on-tile), + // to a renderer that renders to the intermediate textures then they render without MSAA, + // without the user knowing. This is a functional/visual bug. + // https://jira.unity3d.com/browse/UUM-134600 + if (canOptimizeScreenMSAASamples) { Screen.SetMSAASamples(1); - } + } // iOS and macOS corner case bool screenAPIHasOneFrameDelay = (Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.IPhonePlayer); diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererFeature.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererFeature.cs index 4897d1dbdfb..e0f5d7b5f34 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererFeature.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ScriptableRendererFeature.cs @@ -1,5 +1,4 @@ using System; -using UnityEngine.Scripting.APIUpdating; namespace UnityEngine.Rendering.Universal { @@ -123,5 +122,7 @@ public void Dispose() protected virtual void Dispose(bool disposing) { } + + internal ScriptableRenderer.RenderingFeatures supportedRenderingFeatures { get; set; } = new ScriptableRenderer.RenderingFeatures(); } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index ee093bd8e1d..64f556b6709 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -237,16 +237,11 @@ internal static bool UseDynamicBranchFogKeyword() internal UniversalRenderPipelineRuntimeTextures runtimeTextures { get; private set; } - internal static RenderTextureUVOriginStrategy renderTextureUVOriginStrategy { private get; set; } - /// /// The default Render Pipeline Global Settings. /// public override RenderPipelineGlobalSettings defaultSettings => m_GlobalSettings; - // flag to keep track of depth buffer requirements by any of the overlay cameras in the stack - internal static bool stackedOverlayCamerasRequireDepthForPostProcessing = false; - internal static RenderGraph s_RenderGraph; internal static RTHandleResourcePool s_RTHandlePool; @@ -495,7 +490,7 @@ private void DisposeAdditionalCameraData() public CameraRenderingScope(ScriptableRenderContext context, Camera camera) { - using (new ProfilingScope(beginCameraRenderingSampler)) + using (new ProfilingScope(beginCameraRenderingSampler, camera)) { m_Context = context; m_Camera = camera; @@ -506,7 +501,7 @@ public CameraRenderingScope(ScriptableRenderContext context, Camera camera) public void Dispose() { - using (new ProfilingScope(endCameraRenderingSampler)) + using (new ProfilingScope(endCameraRenderingSampler, m_Camera)) { EndCameraRendering(m_Context, m_Camera); } @@ -669,8 +664,10 @@ protected override void ProcessRenderRequests(ScriptableRenderConte int mipLevel = standardRequest != null ? standardRequest.mipLevel : singleRequest.mipLevel; int slice = standardRequest != null ? standardRequest.slice : singleRequest.slice; int face = standardRequest != null ? (int)standardRequest.face : (int)singleRequest.face; + bool isPreview = standardRequest != null ? standardRequest.isPreview : false; //store data that will be changed + var originalCameraType = camera.cameraType; var originalTarget = camera.targetTexture; //set data @@ -695,6 +692,8 @@ protected override void ProcessRenderRequests(ScriptableRenderConte temporaryRT = RenderTexture.GetTemporary(RTDesc); } + if (isPreview) + camera.cameraType = CameraType.Preview; camera.targetTexture = temporaryRT ? temporaryRT : destination; if (standardRequest != null) @@ -766,6 +765,7 @@ protected override void ProcessRenderRequests(ScriptableRenderConte } //restore data + camera.cameraType = originalCameraType; camera.targetTexture = originalTarget; Graphics.SetRenderTarget(originalTarget); RenderTexture.ReleaseTemporary(temporaryRT); @@ -792,9 +792,17 @@ public static void RenderSingleCamera(ScriptableRenderContext context, Camera ca internal static void RenderSingleCameraInternal(ScriptableRenderContext context, Camera camera, bool isLastBaseCamera = true) { UniversalAdditionalCameraData additionalCameraData = null; + #if URP_SCREEN_SPACE_REFLECTION + camera.gameObject.TryGetComponent(out additionalCameraData); + + // We need this to support screen space reflections in the scene view, as it requires color history, + // which in turn requires a UniversalAdditionalCameraData component to be present on the scene view camera. + if (camera.cameraType == CameraType.SceneView && additionalCameraData == null) + additionalCameraData = camera.gameObject.AddComponent(); + #else if (IsGameCamera(camera)) camera.gameObject.TryGetComponent(out additionalCameraData); - + #endif RenderSingleCameraInternal(context, camera, ref additionalCameraData, isLastBaseCamera); } @@ -890,9 +898,9 @@ static void RenderSingleCamera(ScriptableRenderContext context, UniversalCameraD CommandBuffer cmdScope = cameraData.xr.enabled ? null : cmd; var cameraMetadata = CameraMetadataCache.GetCached(camera); - using (new ProfilingScope(cmdScope, cameraMetadata.sampler)) // Enqueues a "BeginSample" command into the CommandBuffer cmd + using (new ProfilingScope(cmdScope, cameraMetadata.sampler, camera)) // Enqueues a "BeginSample" command into the CommandBuffer cmd { - using (new ProfilingScope(Profiling.Pipeline.Renderer.setupCullingParameters)) + using (new ProfilingScope(Profiling.Pipeline.Renderer.setupCullingParameters, camera)) { var legacyCameraData = new CameraData(frameData); @@ -970,7 +978,7 @@ static void RenderSingleCamera(ScriptableRenderContext context, UniversalCameraD UniversalShadowData shadowData; CullContextData cullData; - using (new ProfilingScope(Profiling.Pipeline.initializeRenderingData)) + using (new ProfilingScope(Profiling.Pipeline.initializeRenderingData, camera)) { CreateUniversalResourceData(frameData); lightData = CreateLightData(frameData, asset, data.cullResults.visibleLights, renderingMode); @@ -987,20 +995,18 @@ static void RenderSingleCamera(ScriptableRenderContext context, UniversalCameraD if (asset?.useAdaptivePerformance == true) ApplyAdaptivePerformance(frameData); #endif - UniversalRenderPipeline.renderTextureUVOriginStrategy = RenderTextureUVOriginStrategy.BottomLeft; CreateShadowAtlasAndCullShadowCasters(lightData, shadowData, cameraData, ref data.cullResults, ref context); renderer.AddRenderPasses(ref legacyRenderingData); - RenderTextureUVOriginStrategy uvOriginStrategy = UniversalRenderPipeline.renderTextureUVOriginStrategy; - RecordAndExecuteRenderGraph(s_RenderGraph, context, renderer, cmd, cameraData.camera, uvOriginStrategy); - renderer.FinishRenderGraphRendering(cmd); + RecordAndExecuteRenderGraph(s_RenderGraph, context, renderer, cmd, cameraData.camera); + renderer.FinishRenderGraphRendering(cmd); } // When ProfilingSample goes out of scope, an "EndSample" command is enqueued into CommandBuffer cmd context.ExecuteCommandBuffer(cmd); // Sends to ScriptableRenderContext all the commands enqueued since cmd.Clear, i.e the "EndSample" command CommandBufferPool.Release(cmd); - using (new ProfilingScope(Profiling.Pipeline.Context.submit)) + using (new ProfilingScope(Profiling.Pipeline.Context.submit, cameraData.camera)) { context.Submit(); // Actually execute the commands that we previously sent to the ScriptableRenderContext context } @@ -1031,7 +1037,7 @@ private static void CreateShadowAtlasAndCullShadowCasters(UniversalLightData lig /// True if this is the last base camera. static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera, bool isLastBaseCamera) { - using var profScope = new ProfilingScope(ProfilingSampler.Get(URPProfileId.RenderCameraStack)); + using var profScope = new ProfilingScope(ProfilingSampler.Get(URPProfileId.RenderCameraStack), baseCamera); baseCamera.TryGetComponent(out var baseCameraAdditionalData); @@ -1058,8 +1064,6 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera var baseCameraRendererType = renderer.GetType(); bool shouldUpdateCameraStack = false; - stackedOverlayCamerasRequireDepthForPostProcessing = false; - for (int i = 0; i < stackedOverlayCameras.Count; ++i) { Camera overlayCamera = stackedOverlayCameras[i]; @@ -1098,8 +1102,6 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera continue; } - stackedOverlayCamerasRequireDepthForPostProcessing |= CheckPostProcessForDepth(); - stackAnyPostProcessingEnabled |= data.renderPostProcessing; lastActiveOverlayCameraIndex = i; } @@ -1111,8 +1113,9 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera } bool isStackedRendering = lastActiveOverlayCameraIndex != -1; - if (isStackedRendering && renderer is UniversalRenderer {onTileValidation: true}) - throw new ArgumentException("The active URP Renderer has 'On Tile Validation' on. This currently does not allow Camera Stacking usage. Check your scene and remove all overlay Cameras."); + + // The camera data is set based on the supported features. + renderer.UpdateSupportedRenderingFeatures(); // Prepare XR rendering var xrActive = false; @@ -1177,8 +1180,6 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera if (asset?.useAdaptivePerformance == true) ApplyAdaptivePerformance(baseCameraData); #endif - // update the base camera flag so that the scene depth is stored if needed by overlay cameras later in the frame - baseCameraData.postProcessingRequiresDepthTexture |= stackedOverlayCamerasRequireDepthForPostProcessing; // Check whether the camera stack final output is HDR // This is equivalent of UniversalCameraData.isHDROutputActive but without necessiting the base camera to be the last camera in the stack. @@ -1189,12 +1190,11 @@ static void RenderCameraStack(ScriptableRenderContext context, Camera baseCamera hdrDisplayOutputActive = xrPass.isHDRDisplayOutputActive; #endif finalOutputHDR = - asset.supportsHDR && hdrDisplayOutputActive // Check whether any HDR display is active and the render pipeline asset allows HDR rendering && baseCamera.targetTexture == null && (baseCamera.cameraType == CameraType.Game || baseCamera.cameraType == CameraType.VR) // Check whether the stack outputs to a screen - && baseCameraData.allowHDROutput; // Check whether the base camera allows HDR output + && baseCameraData.isHdrEnabled; // Check whether the base camera has HDR enabled (this includes a check if the renderer supports it) // Update stack-related parameters baseCameraData.stackAnyPostProcessingEnabled = stackAnyPostProcessingEnabled; @@ -1408,6 +1408,11 @@ static bool CheckPostProcessForDepth() if (stack.GetComponent().IsActive()) return true; + if (LensFlareCommonSRP.IsOcclusionRTCompatible() + && !LensFlareCommonSRP.Instance.IsEmpty() + && UniversalRenderPipeline.asset.supportDataDrivenLensFlare) + return true; + return false; } @@ -1462,6 +1467,8 @@ static UniversalCameraData CreateCameraData(ContextContainer frameData, Camera c var renderer = GetRenderer(camera, additionalCameraData); UniversalCameraData cameraData = frameData.Create(); + cameraData.renderer = renderer; + InitializeStackedCameraData(camera, additionalCameraData, cameraData); cameraData.camera = camera; @@ -1497,10 +1504,7 @@ static UniversalCameraData CreateCameraData(ContextContainer frameData, Camera c // Multiple cameras could render into the same XR display and they should share the same MSAA level. // However it should still respect the sample count of the target texture camera is rendering to. if (cameraData.xrRendering && rendererSupportsMSAA && camera.targetTexture == null) - msaaSamples = (int)XRSystem.GetDisplayMSAASamples(); - - if (renderer is UniversalRenderer { onTileValidation: true } && UniversalRenderer.PlatformRequiresExplicitMsaaResolve()) - msaaSamples = 1; + msaaSamples = (int)XRSystem.GetDisplayMSAASamples(); #if ENABLE_MULTI_WINDOWING && PLATFORM_SUPPORTS_PER_WINDOW_TRANSPARENCY && !UNITY_EDITOR bool needsAlphaChannel = GameWindowManager.IsGameWindowTransparent(cameraData.camera.targetDisplay); @@ -1573,11 +1577,16 @@ static void InitializeStackedCameraData(Camera baseCamera, UniversalAdditionalCa cameraData.allowHDROutput = true; } + var supportedRenderingFeatures = cameraData.renderer.supportedRenderingFeatures; + /////////////////////////////////////////////////////////////////// // Settings that control output of the camera / /////////////////////////////////////////////////////////////////// - cameraData.isHdrEnabled = baseCamera.allowHDR && settings.supportsHDR; + if (!supportedRenderingFeatures.antiAliasing) + cameraData.antialiasing = AntialiasingMode.None; + + cameraData.isHdrEnabled = baseCamera.allowHDR && settings.supportsHDR && supportedRenderingFeatures.supportsHDR; cameraData.allowHDROutput &= settings.supportsHDR; Rect cameraRect = baseCamera.rect; @@ -1594,8 +1603,8 @@ static void InitializeStackedCameraData(Camera baseCamera, UniversalAdditionalCa // Discard variations lesser than kRenderScaleThreshold. // Scale is only enabled for gameview. const float kRenderScaleThreshold = 0.05f; - bool disableRenderScale = ((Mathf.Abs(1.0f - settings.renderScale) < kRenderScaleThreshold) || isScenePreviewOrReflectionCamera); - cameraData.renderScale = disableRenderScale ? 1.0f : settings.renderScale; + bool disableRenderScale = (Mathf.Abs(1.0f - settings.renderScale) < kRenderScaleThreshold) || isScenePreviewOrReflectionCamera || !supportedRenderingFeatures.upscaling; + cameraData.renderScale = disableRenderScale? 1.0f : settings.renderScale; #if ENABLE_UPSCALER_FRAMEWORK // ImageUpscalingFilter is deprecated, we now track by upscaler name @@ -1608,8 +1617,10 @@ static void InitializeStackedCameraData(Camera baseCamera, UniversalAdditionalCa bool upscalerSupportsSharpening = activeUpscaler != null && activeUpscaler.supportsSharpening; #else // Convert the upscaling filter selection from the pipeline asset into an image upscaling filter - cameraData.upscalingFilter = ResolveUpscalingFilterSelection(new Vector2(cameraData.pixelWidth, cameraData.pixelHeight), cameraData.renderScale, settings.upscalingFilter); - + cameraData.upscalingFilter = supportedRenderingFeatures.upscaling? + ResolveUpscalingFilterSelection(new Vector2(cameraData.pixelWidth, cameraData.pixelHeight), cameraData.renderScale, settings.upscalingFilter) + : ImageUpscalingFilter.Point; + bool upscalerSupportsTemporalAntiAliasing = cameraData.upscalingFilter == ImageUpscalingFilter.STP; bool upscalerSupportsSharpening = cameraData.upscalingFilter == ImageUpscalingFilter.FSR; #endif @@ -1675,7 +1686,7 @@ static void InitializeAdditionalCameraData(Camera camera, UniversalAdditionalCam using var profScope = new ProfilingScope(Profiling.Pipeline.initializeAdditionalCameraData); var renderer = GetRenderer(camera, additionalCameraData); - var settings = asset; + var settings = asset; bool anyShadowsEnabled = settings.supportsMainLightShadows || settings.supportsAdditionalLightShadows; cameraData.maxShadowDistance = Mathf.Min(settings.shadowDistance, camera.farClipPlane); @@ -1716,6 +1727,14 @@ static void InitializeAdditionalCameraData(Camera camera, UniversalAdditionalCam cameraData.screenSizeOverride = cameraData.pixelRect.size; cameraData.screenCoordScaleBias = Vector2.one; } + + var supportedRenderingFeatures = renderer.supportedRenderingFeatures; + + if (!supportedRenderingFeatures.cameraOpaqueTexture) + cameraData.requiresOpaqueTexture = false; + + if (!supportedRenderingFeatures.cameraDepthTexture) + cameraData.requiresDepthTexture = false; cameraData.renderer = renderer; cameraData.postProcessingRequiresDepthTexture = CheckPostProcessForDepth(cameraData); @@ -1995,7 +2014,7 @@ static UniversalPostProcessingData CreatePostProcessingData(ContextContainer fra UniversalPostProcessingData postProcessingData = frameData.Create(); UniversalCameraData cameraData = frameData.Get(); - postProcessingData.isEnabled = cameraData.stackAnyPostProcessingEnabled; + postProcessingData.isEnabled = cameraData.postProcessEnabled; postProcessingData.gradingMode = settings.supportsHDR ? settings.colorGradingMode diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index 46975110ee8..f0bfad5c146 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -914,6 +914,7 @@ internal static class ShaderGlobalKeywords public static GlobalKeyword ReflectionProbeBlending; public static GlobalKeyword ReflectionProbeAtlas; public static GlobalKeyword ReflectionProbeRotation; + public static GlobalKeyword ScreenSpaceReflection; public static GlobalKeyword SoftShadows; public static GlobalKeyword SoftShadowsLow; public static GlobalKeyword SoftShadowsMedium; @@ -937,6 +938,7 @@ internal static class ShaderGlobalKeywords public static GlobalKeyword DecalNormalBlendHigh; public static GlobalKeyword DecalLayers; public static GlobalKeyword WriteRenderingLayers; + public static GlobalKeyword WriteSmoothness; public static GlobalKeyword ScreenSpaceOcclusion; public static GlobalKeyword ScreenSpaceIrradiance; public static GlobalKeyword _SPOT; @@ -989,7 +991,7 @@ internal static class ShaderGlobalKeywords public static GlobalKeyword META_QUEST_LIGHTUNROLL; public static GlobalKeyword META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP; #endif - + public static GlobalKeyword APPLICATION_SPACE_WARP_MOTION_TRANSPARENT; // TODO: Move following keywords to Local keywords? // https://docs.unity3d.com/ScriptReference/Rendering.LocalKeyword.html //public static GlobalKeyword TonemapACES; @@ -1033,6 +1035,7 @@ public static void InitializeShaderGlobalKeywords() ShaderGlobalKeywords.ReflectionProbeBlending = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeBlending); ShaderGlobalKeywords.ReflectionProbeAtlas = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeAtlas); ShaderGlobalKeywords.ReflectionProbeRotation = GlobalKeyword.Create(ShaderKeywordStrings.ReflectionProbeRotation); + ShaderGlobalKeywords.ScreenSpaceReflection = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceReflection); ShaderGlobalKeywords.SoftShadows = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadows); ShaderGlobalKeywords.SoftShadowsLow = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsLow); ShaderGlobalKeywords.SoftShadowsMedium = GlobalKeyword.Create(ShaderKeywordStrings.SoftShadowsMedium); @@ -1056,6 +1059,7 @@ public static void InitializeShaderGlobalKeywords() ShaderGlobalKeywords.DecalNormalBlendHigh = GlobalKeyword.Create(ShaderKeywordStrings.DecalNormalBlendHigh); ShaderGlobalKeywords.DecalLayers = GlobalKeyword.Create(ShaderKeywordStrings.DecalLayers); ShaderGlobalKeywords.WriteRenderingLayers = GlobalKeyword.Create(ShaderKeywordStrings.WriteRenderingLayers); + ShaderGlobalKeywords.WriteSmoothness = GlobalKeyword.Create(ShaderKeywordStrings.WriteSmoothness); ShaderGlobalKeywords.ScreenSpaceOcclusion = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceOcclusion); ShaderGlobalKeywords.ScreenSpaceIrradiance = GlobalKeyword.Create(ShaderKeywordStrings.ScreenSpaceIrradiance); ShaderGlobalKeywords._SPOT = GlobalKeyword.Create(ShaderKeywordStrings._SPOT); @@ -1108,7 +1112,7 @@ public static void InitializeShaderGlobalKeywords() ShaderGlobalKeywords.META_QUEST_LIGHTUNROLL = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_LIGHTUNROLL); ShaderGlobalKeywords.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP = GlobalKeyword.Create(ShaderKeywordStrings.META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP); #endif - + ShaderGlobalKeywords.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT = GlobalKeyword.Create(ShaderKeywordStrings.APPLICATION_SPACE_WARP_MOTION_TRANSPARENT); } } @@ -1153,6 +1157,9 @@ public static class ShaderKeywordStrings /// Keyword used for ReflectionProbe rotation. public const string ReflectionProbeRotation = "REFLECTION_PROBE_ROTATION"; + /// Keyword used for Screen Space Reflection (SSR). + public const string ScreenSpaceReflection = "_SCREEN_SPACE_REFLECTION"; + /// Keyword used for soft shadows. public const string SoftShadows = "_SHADOWS_SOFT"; @@ -1228,6 +1235,9 @@ public static class ShaderKeywordStrings /// Keyword used for writing Rendering Layers. public const string WriteRenderingLayers = "_WRITE_RENDERING_LAYERS"; + /// Keyword used for writing roughness to alpha channel of normals texture. + public const string WriteSmoothness = "_WRITE_SMOOTHNESS"; + /// Keyword used for low quality Subpixel Morphological Anti-aliasing (SMAA). public const string SmaaLow = "_SMAA_PRESET_LOW"; @@ -1452,6 +1462,9 @@ public static class ShaderKeywordStrings internal const string META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP = "META_QUEST_NO_SPOTLIGHTS_LIGHT_LOOP"; #endif + /// Keyword used for transparency spacewarp-related code + internal const string APPLICATION_SPACE_WARP_MOTION_TRANSPARENT = "APPLICATION_SPACE_WARP_MOTION_TRANSPARENT"; + /// Keyword used for Multi Sampling Anti-Aliasing (MSAA) with 2 per pixel sample count. public const string Msaa2 = "_MSAA_2"; @@ -1943,6 +1956,7 @@ internal enum URPProfileId MainLightShadow, ResolveShadows, SSAO, + SSR, // PostProcessPass StopNaNs, diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineRenderGraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineRenderGraph.cs index f75e2329177..9b0b625e3c6 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineRenderGraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineRenderGraph.cs @@ -5,8 +5,12 @@ namespace UnityEngine.Rendering.Universal { public sealed partial class UniversalRenderPipeline { - static void RecordAndExecuteRenderGraph(RenderGraph renderGraph, ScriptableRenderContext context, ScriptableRenderer renderer, CommandBuffer cmd, Camera camera, RenderTextureUVOriginStrategy uvOriginStrategy) + static void RecordAndExecuteRenderGraph(RenderGraph renderGraph, ScriptableRenderContext context, ScriptableRenderer renderer, CommandBuffer cmd, Camera camera) { + var universalRenderer = renderer as UniversalRenderer; + var renderTextureUVOriginStrategy = (universalRenderer != null && universalRenderer.useTileOnlyMode) ? + RenderTextureUVOriginStrategy.PropagateAttachmentOrientation : RenderTextureUVOriginStrategy.BottomLeft; + RenderGraphParameters rgParams = new RenderGraphParameters { executionId = camera.GetEntityId(), @@ -14,7 +18,7 @@ static void RecordAndExecuteRenderGraph(RenderGraph renderGraph, ScriptableRende commandBuffer = cmd, scriptableRenderContext = context, currentFrameIndex = Time.frameCount, - renderTextureUVOriginStrategy = uvOriginStrategy, + renderTextureUVOriginStrategy = renderTextureUVOriginStrategy, }; try diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index 3d1cf7ef69a..6b4991dfaf7 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -62,17 +62,12 @@ public sealed partial class UniversalRenderer : ScriptableRenderer /// public override int SupportedCameraStackingTypes() { - switch (m_RenderingMode) - { - case RenderingMode.Forward: - case RenderingMode.ForwardPlus: - return 1 << (int)CameraRenderType.Base | 1 << (int)CameraRenderType.Overlay; - case RenderingMode.Deferred: - case RenderingMode.DeferredPlus: - return 1 << (int)CameraRenderType.Base; - default: - return 0; - } + int supported = 1 << (int)CameraRenderType.Base; + + if(supportedRenderingFeatures.overlayCamera) + supported |= 1 << (int)CameraRenderType.Overlay; + + return supported; } /// @@ -85,7 +80,7 @@ protected internal override bool SupportsMotionVectors() /// protected internal override bool SupportsCameraOpaque() { - return true; + return supportedRenderingFeatures.cameraOpaqueTexture; } /// @@ -166,6 +161,7 @@ internal RenderingMode renderingModeActual { DrawScreenSpaceUIPass m_DrawOverlayUIPass; CopyColorPass m_HistoryRawColorCopyPass; + CopyColorPass m_HistoryBeforeTransparentsColorCopyPass; CopyDepthPass m_HistoryRawDepthCopyPass; StencilCrossFadeRenderPass m_StencilCrossFadeRenderPass; @@ -193,18 +189,29 @@ internal RenderingMode renderingModeActual { Material m_ClusterDeferredMaterial = null; Material m_CameraMotionVecMaterial = null; - internal bool isPostProcessActive { get => m_PostProcess != null; } + // Is the internal post processing of the renderer enabled. + // This does not include post processing in extensions. + // If post processing is enabled on the camera, and on the renderer, then + // the internal post processing passes will be added. + // Validation can still turn this off so it's not a direct view on the + // serialized renderer data. + internal bool postProcessEnabled { get; set; } internal DeferredLights deferredLights { get => m_DeferredLights; } internal LayerMask prepassLayerMask { get; set; } internal LayerMask opaqueLayerMask { get; set; } internal LayerMask transparentLayerMask { get; set; } internal bool shadowTransparentReceive { get; set; } - internal bool onTileValidation { get; set; } + + // A Renderer cannot be switched from On-Tile to not On-Tile. + // We make assumptions in the constructor to create the passes. + internal bool useTileOnlyMode { get; } internal GraphicsFormat cameraDepthTextureFormat { get => (m_CameraDepthTextureFormat != DepthFormat.Default) ? (GraphicsFormat)m_CameraDepthTextureFormat : CoreUtils.GetDefaultDepthStencilFormat(); } internal GraphicsFormat cameraDepthAttachmentFormat { get => (m_CameraDepthAttachmentFormat != DepthFormat.Default) ? (GraphicsFormat)m_CameraDepthAttachmentFormat : CoreUtils.GetDefaultDepthStencilFormat(); } + ValidationHandler m_ValidationHandler; + /// /// Constructor for the Universal Renderer. /// @@ -218,7 +225,7 @@ public UniversalRenderer(UniversalRendererData data) : base(data) if (GraphicsSettings.TryGetRenderPipelineSettings(out var xrResources)) { Experimental.Rendering.XRSystem.Initialize(XRPassUniversal.Create, xrResources.xrOcclusionMeshPS, xrResources.xrMirrorViewPS); - m_XRDepthMotionPass = new XRDepthMotionPass(RenderPassEvent.BeforeRenderingPrePasses, xrResources.xrMotionVector); + m_XRDepthMotionPass = new XRDepthMotionPass(RenderPassEvent.BeforeRenderingPrePasses, xrResources.xrMotionVector, data.transparentLayerMask); } #endif if (GraphicsSettings.TryGetRenderPipelineSettings( @@ -257,7 +264,15 @@ public UniversalRenderer(UniversalRendererData data) : base(data) transparentLayerMask = data.transparentLayerMask; shadowTransparentReceive = data.shadowTransparentReceive; - onTileValidation = data.onTileValidation; + useTileOnlyMode = data.tileOnlyMode; + + // The On-Tile Renderer does not support WebGL. + if (useTileOnlyMode && IsWebGL()) + { + useTileOnlyMode = false; + } + + m_ValidationHandler = new ValidationHandler(useTileOnlyMode); var asset = UniversalRenderPipeline.asset; if (asset != null && asset.supportsLightCookies) @@ -291,6 +306,33 @@ public UniversalRenderer(UniversalRendererData data) : base(data) this.m_CopyDepthMode = data.copyDepthMode; this.m_CameraDepthAttachmentFormat = data.depthAttachmentFormat; this.m_CameraDepthTextureFormat = data.depthTextureFormat; + this.postProcessEnabled = data.postProcessData != null; + this.name = data.name; + + UpdateSupportedRenderingFeatures(); + + // We log warnings to nudge users towards fixing the settings. Although we automatically fix these, its bad for the user to keep + // incompatible settings. The reason is that this automatic fixing has downsides for the users: if they toggle the Tile-Only + // setting, they get a different mix of settings with different visual results. Also the URP asset can have incompabitle settings. + // However, because these can be shared between different renderers, we can't log warnings. We also have warnings in the + // Inspector UI but these can easily be missed by the user. + if (useTileOnlyMode) + { + if (postProcessEnabled) + { + Debug.LogWarning($"The built-in Post Processing on the URP Renderer '{data.name}' is not compatible with the enabled Tile-Only Mode setting. Disable the post processing on the renderer asset."); + + // We don't change the camera setting. Extensions like our own On-Tile Post Processing + // use this as well. We just make sure we disable the internal post processing on the + // renderer because this is not on-tile compatible currently. + postProcessEnabled = false; + } + + if (renderingModeRequested == RenderingMode.Deferred || renderingModeRequested == RenderingMode.DeferredPlus) + { + Debug.LogWarning($"Rendering path Deferred on the URP Renderer '{data.name}' is not compatible with the enabled Tile-Only Mode setting. Change this to Forward(+) on the renderer asset."); + } + } // Note: Since all custom render passes inject first and we have stable sort, // we inject the builtin passes in the before events. @@ -304,7 +346,7 @@ public UniversalRenderer(UniversalRendererData data) : base(data) #endif m_DepthPrepass = new DepthOnlyPass(RenderPassEvent.BeforeRenderingPrePasses, RenderQueueRange.opaque, prepassLayerMask); m_DepthNormalPrepass = new DepthNormalOnlyPass(RenderPassEvent.BeforeRenderingPrePasses, RenderQueueRange.opaque, prepassLayerMask); - if (renderingModeRequested == RenderingMode.Deferred || renderingModeRequested == RenderingMode.DeferredPlus) + if (supportedRenderingFeatures.deferredLighting) { var deferredInitParams = new DeferredLights.InitParams(); deferredInitParams.stencilDeferredMaterial = m_StencilDeferredMaterial; @@ -364,14 +406,15 @@ public UniversalRenderer(UniversalRendererData data) : base(data) // History generation passes for "raw color/depth". These execute only if explicitly requested by users. // VFX system particles uses these. See RawColorHistory.cs. m_HistoryRawColorCopyPass = new CopyColorPass(RenderPassEvent.BeforeRenderingPostProcessing, m_SamplingMaterial, m_BlitMaterial, customPassName: "Copy Color Raw History"); + m_HistoryBeforeTransparentsColorCopyPass = new CopyColorPass(RenderPassEvent.BeforeRenderingTransparents, m_SamplingMaterial, m_BlitMaterial, customPassName: "Copy Color History Before Transparents"); m_HistoryRawDepthCopyPass = new CopyDepthPass(RenderPassEvent.BeforeRenderingPostProcessing, copyDephPS, false, customPassName: "Copy Depth Raw History"); m_DrawOffscreenUIPass = new DrawScreenSpaceUIPass(RenderPassEvent.BeforeRenderingPostProcessing); m_DrawOverlayUIPass = new DrawScreenSpaceUIPass(RenderPassEvent.AfterRendering + k_AfterFinalBlitPassQueueOffset); // after m_FinalBlitPass - - //No postProcessData means that post processes are disabled - if (data.postProcessData != null) + + if (postProcessEnabled) { + Debug.Assert(data.postProcessData != null); m_PostProcess = new PostProcess(data.postProcessData); m_ColorGradingLutPassRenderGraph = new ColorGradingLutPass(RenderPassEvent.BeforeRenderingPrePasses, data.postProcessData); } @@ -386,21 +429,60 @@ public UniversalRenderer(UniversalRendererData data) : base(data) m_ProbeVolumeDebugPass = new ProbeVolumeDebugPass(RenderPassEvent.BeforeRenderingTransparents, debugShaders.probeVolumeSamplingDebugComputeShader); #endif - supportedRenderingFeatures = new RenderingFeatures(); - - if (renderingModeRequested is RenderingMode.Deferred or RenderingMode.DeferredPlus) - { - // Deferred rendering does not support MSAA. - // if On-Tile Validation is enabled, Deferred(+) will fallback to Forward(+). Thus we must not fix msaa value in this case. - if (!onTileValidation) - supportedRenderingFeatures.msaa = false; - } - LensFlareCommonSRP.mergeNeeded = 0; LensFlareCommonSRP.maxLensFlareWithOcclusionTemporalSample = 1; LensFlareCommonSRP.Initialize(); } + internal override void UpdateSupportedRenderingFeatures() + { + if (useTileOnlyMode) + { + supportedRenderingFeatures.supportsHDR = false; // We need a blit pass to support hdr. + supportedRenderingFeatures.postProcessing = false; // Internal pp does not support on-tile. + supportedRenderingFeatures.cameraOpaqueTexture = false; + supportedRenderingFeatures.cameraDepthTexture = false; + supportedRenderingFeatures.upscaling = PlatformAutoDetect.isXRMobile; + supportedRenderingFeatures.antiAliasing = false; + supportedRenderingFeatures.gpuOcclusionCulling = false; + supportedRenderingFeatures.deferredLighting = false; + supportedRenderingFeatures.overlayCamera = false; + + // If a device requires explicit msaa resolve, that means that the backbuffer + // can't have msaa. In regular rendering, we can render to msaa intermediate + // textures and blit the resolved textures. However, in on-tile mode, this + // would break the render pass so we need to ensure the intermediate textures + // have the same msaa count as the backbuffer (ie 1). + supportedRenderingFeatures.msaa = !UniversalRenderer.PlatformRequiresExplicitMsaaResolve() && SystemInfo.supportsMultisampledBackBuffer && !supportedRenderingFeatures.deferredLighting; + } + else + { + supportedRenderingFeatures.supportsHDR = true; + supportedRenderingFeatures.postProcessing = postProcessEnabled; + supportedRenderingFeatures.cameraOpaqueTexture = true; + supportedRenderingFeatures.cameraDepthTexture = true; + supportedRenderingFeatures.upscaling = true; + supportedRenderingFeatures.antiAliasing = true; + supportedRenderingFeatures.gpuOcclusionCulling = true; + supportedRenderingFeatures.deferredLighting = renderingModeRequested is RenderingMode.Deferred or RenderingMode.DeferredPlus; + supportedRenderingFeatures.overlayCamera = !supportedRenderingFeatures.deferredLighting; + supportedRenderingFeatures.msaa = !supportedRenderingFeatures.deferredLighting; + } + + foreach (var feature in rendererFeatures) + { + if (feature.isActive) + { + // For example, OnTilePostProcessing adds post processing and hdr support. + supportedRenderingFeatures.supportsHDR |= feature.supportedRenderingFeatures.supportsHDR; + supportedRenderingFeatures.postProcessing |= feature.supportedRenderingFeatures.postProcessing; + } + } + + // Setting the engine wide feature flags here as well. We can likely phase these out. + SupportedRenderingFeatures.active.supportsHDR = supportedRenderingFeatures.supportsHDR; + } + /// protected override void Dispose(bool disposing) { @@ -637,11 +719,7 @@ static RenderPassInputSummary GetRenderPassInputs(List act } void AddRequirementsOfInternalFeatures(ref RenderPassInputSummary inputSummary, UniversalCameraData cameraData, bool postProcessingEnabled, bool renderingLayerProvidesByDepthNormalPass, MotionVectorRenderPass motionVectorPass, CopyDepthMode copyDepthMode) - { - // TAA in postprocess requires it to function. - if (cameraData.IsTemporalAAEnabled() ) - inputSummary.requiresMotionVectors = true; - + { if(cameraData.requiresDepthTexture) { inputSummary.requiresDepthTexture = true; @@ -674,6 +752,10 @@ void AddRequirementsOfInternalFeatures(ref RenderPassInputSummary inputSummary, inputSummary.requiresDepthTextureEarliestEvent = (RenderPassEvent)Mathf.Min( (int)RenderPassEvent.BeforeRenderingPostProcessing, (int)inputSummary.requiresDepthTextureEarliestEvent); } + // TAA in postprocess requires it to function. + if (cameraData.IsTemporalAAEnabled()) + inputSummary.requiresMotionVectors = true; + } // Motion vectors imply depth diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererData.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererData.cs index 8a13ae00419..26430b7dd94 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererData.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererData.cs @@ -154,7 +154,7 @@ static void CreateUniversalRendererData() bool m_AccurateGbufferNormals = false; [SerializeField] IntermediateTextureMode m_IntermediateTextureMode = IntermediateTextureMode.Always; - [SerializeField] bool m_OnTileValidation = false; + [SerializeField] bool m_TileOnlyMode = false; /// protected override ScriptableRenderer Create() @@ -348,19 +348,20 @@ public IntermediateTextureMode intermediateTextureMode } /// - /// On-Tile validation validates features to prevent going off tile. - /// This is mainly useful for tile based architectures. + /// Tile-Only Mode restricts render passes to avoid memory load/store of main camera targets, keeping them in on‑chip tile memory. + /// It activates additional RenderGaph validation. Some features may be disabled or fall back. See docs for details. + /// This is a potential GPU performance optimization on Tile-Based GPU architectures. /// - public bool onTileValidation + public bool tileOnlyMode { - get => m_OnTileValidation; + get => m_TileOnlyMode; set { - if (m_OnTileValidation == value) + if (m_TileOnlyMode == value) return; SetDirty(); - m_OnTileValidation = value; + m_TileOnlyMode = value; } } diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs index 27f4c38a7dc..ea8c082e1bd 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/UniversalRendererRenderGraph.cs @@ -288,6 +288,8 @@ internal static void GetTextureDesc(in RenderTextureDescriptor desc, out Texture rgDesc.useDynamicScale = desc.useDynamicScale; rgDesc.useDynamicScaleExplicit = desc.useDynamicScaleExplicit; rgDesc.vrUsage = desc.vrUsage; + rgDesc.useMipMap = desc.useMipMap; + rgDesc.autoGenerateMips = desc.autoGenerateMips; } internal static TextureHandle CreateRenderGraphTexture(RenderGraph renderGraph, in TextureDesc desc, string name, bool clear, Color clearColor, @@ -538,7 +540,7 @@ private void RenderRawColorDepthHistory(RenderGraph renderGraph, UniversalCamera var colorHistory = history.GetHistoryForWrite(); if (colorHistory != null) { - colorHistory.Update(ref cameraData.cameraTargetDescriptor, xrMultipassEnabled); + colorHistory.Update(cameraData, ref cameraData.cameraTargetDescriptor, xrMultipassEnabled); if (colorHistory.GetCurrentTexture(multipassId) != null) { var colorHistoryTarget = renderGraph.ImportTexture(colorHistory.GetCurrentTexture(multipassId)); @@ -582,66 +584,44 @@ private void RenderRawColorDepthHistory(RenderGraph renderGraph, UniversalCamera } } - /// - /// Called before recording the render graph. Can be used to initialize resources. - /// - public override void OnBeginRenderGraphFrame() - { - UniversalResourceData resourceData = frameData.Get(); - resourceData.InitFrame(); - } - - static void ApplyConstraints(bool onTileValidation, UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalPostProcessingData postProcessingData, List activeRenderPassQueue, ref RenderingMode renderingMode, ref DepthPrimingMode depthPrimingMode) + // Copy internal color buffer before transparents into the history. + private void RenderBeforeTransparentsColorHistory(RenderGraph renderGraph, UniversalCameraData cameraData, UniversalResourceData resourceData) { - if (!onTileValidation) - return; - - cameraData.requiresOpaqueTexture = false; - cameraData.requiresDepthTexture = false; - - cameraData.postProcessEnabled = false; - cameraData.stackAnyPostProcessingEnabled = false; - postProcessingData.isEnabled = false; - - cameraData.useGPUOcclusionCulling = false; - cameraData.isHdrEnabled = false; - - if (!PlatformAutoDetect.isXRMobile) + if (cameraData != null && cameraData.historyManager != null && resourceData != null) { - cameraData.renderScale = 1.0f; - cameraData.imageScalingMode = ImageScalingMode.None; - } - - if (renderingData.renderingMode == RenderingMode.DeferredPlus) - renderingData.renderingMode = RenderingMode.ForwardPlus; - - if (renderingMode == RenderingMode.DeferredPlus) - renderingMode = RenderingMode.ForwardPlus; - - if (renderingData.renderingMode == RenderingMode.Deferred) - renderingData.renderingMode = RenderingMode.Forward; - - if (renderingMode == RenderingMode.Deferred) - renderingMode = RenderingMode.Forward; + UniversalCameraHistory history = cameraData.historyManager; - if (cameraData.baseCamera != null && cameraData.baseCamera != cameraData.camera) - throw new ArgumentException("The active URP Renderer has 'On Tile Validation' on. This currently does not allow Camera Stacking usage. Check your scene and remove all overlay Cameras."); + bool xrMultipassEnabled = false; + int multipassId = 0; +#if ENABLE_VR && ENABLE_XR_MODULE + xrMultipassEnabled = cameraData.xr.enabled && !cameraData.xr.singlePassEnabled; + multipassId = cameraData.xr.multipassId; +#endif - if (activeRenderPassQueue.Count > 0) - throw new ArgumentException("The active URP Renderer has 'On Tile Validation' on. This currently does not allow any ScriptableRenderFeature enabled, and it does not allow enqueuing any ScriptableRenderPass. Check your Renderer asset and disable all Renderer Features. Also, ensure that no C# script enqueus any passes on the renderer."); + if (history.IsAccessRequested() && resourceData.cameraColor.IsValid()) + { + var colorHistory = history.GetHistoryForWrite(); + if (colorHistory != null) + { + colorHistory.Update(cameraData, ref cameraData.cameraTargetDescriptor, xrMultipassEnabled); + if (colorHistory.GetCurrentTexture(multipassId) != null) + { + var colorHistoryTarget = renderGraph.ImportTexture(colorHistory.GetCurrentTexture(multipassId)); + m_HistoryBeforeTransparentsColorCopyPass.RenderToExistingTexture(renderGraph, frameData, colorHistoryTarget, resourceData.cameraColor, Downsampling.None); + } + } + } + } } - //Catches mistakes by Unity devs with regards to clearing the settings - [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] - static void ValidateCorrectnessOfConstraints(bool onTileValidation, in RenderPassInputSummary renderPassInputs, bool requireIntermediateTextures) + /// + /// Called before recording the render graph. Can be used to initialize resources. + /// + public override void OnBeginRenderGraphFrame() { - if (!onTileValidation) - return; - - if (renderPassInputs is { requiresColorTexture: false, requiresDepthTexture: false, requiresMotionVectors: false, requiresNormalsTexture: false} && !requireIntermediateTextures) - return; - - throw new ArgumentException("On Tile Validation is on but certain features still added requirements that would validate this."); + UniversalResourceData resourceData = frameData.Get(); + resourceData.InitFrame(); + m_ValidationHandler.OnBeginRenderGraphFrame(); } internal override void OnRecordRenderGraph(RenderGraph renderGraph, ScriptableRenderContext context) @@ -652,8 +632,6 @@ internal override void OnRecordRenderGraph(RenderGraph renderGraph, ScriptableRe UniversalLightData lightData = frameData.Get(); UniversalPostProcessingData postProcessingData = frameData.Get(); - ApplyConstraints(onTileValidation, renderingData, cameraData, postProcessingData,activeRenderPassQueue, ref m_RenderingMode, ref m_DepthPrimingMode); - MotionVectorRenderPass.SetRenderGraphMotionVectorGlobalMatrices(renderGraph, cameraData); SetupRenderGraphLights(renderGraph, renderingData, cameraData, lightData); @@ -661,7 +639,7 @@ internal override void OnRecordRenderGraph(RenderGraph renderGraph, ScriptableRe SetupRenderingLayers(cameraData.cameraTargetDescriptor.msaaSamples); bool isCameraTargetOffscreenDepth = cameraData.camera.targetTexture != null && cameraData.camera.targetTexture.format == RenderTextureFormat.Depth; - bool applyPostProcessing = cameraData.postProcessEnabled && m_PostProcess != null; + bool applyPostProcessing = cameraData.postProcessEnabled && this.postProcessEnabled; //First get the input requirements for the the ScriptableRenderPasses. These are all user passes plus potentially some that URP adds. RenderPassInputSummary renderPassInputs = GetRenderPassInputs(activeRenderPassQueue); @@ -684,10 +662,11 @@ internal override void OnRecordRenderGraph(RenderGraph renderGraph, ScriptableRe if (cameraData.renderType == CameraRenderType.Base) s_RequiresIntermediateAttachments = RequiresIntermediateAttachments(cameraData, in renderPassInputs, requireCopyFromDepth, applyPostProcessing); - ValidateCorrectnessOfConstraints(onTileValidation, renderPassInputs, s_RequiresIntermediateAttachments); - CreateRenderGraphCameraRenderTargets(renderGraph, isCameraTargetOffscreenDepth, s_RequiresIntermediateAttachments, depthTextureIsDepthFormat); + m_ValidationHandler.active = cameraData.cameraType == CameraType.Game; + m_ValidationHandler.OnBeforeRendering(renderGraph, resourceData); + if (DebugHandler != null) DebugHandler.Setup(renderGraph, cameraData.isPreviewCamera); @@ -743,6 +722,9 @@ public override bool supportsGPUOcclusion { get { + if (!supportedRenderingFeatures.gpuOcclusionCulling) + return false; + // UUM-82677: GRD GPU Occlusion Culling on Vulkan breaks rendering on some mobile GPUs // // We currently disable gpu occlusion culling when running on Qualcomm GPUs due to suspected driver issues. @@ -821,7 +803,7 @@ private void OnBeforeRendering(RenderGraph renderGraph) RecordCustomRenderGraphPasses(renderGraph, RenderPassEvent.AfterRenderingShadows); - bool requiredColorGradingLutPass = cameraData.postProcessEnabled && m_PostProcess != null; + bool requiredColorGradingLutPass = cameraData.postProcessEnabled && this.postProcessEnabled; if (requiredColorGradingLutPass) { m_ColorGradingLutPassRenderGraph.RecordRenderGraph(renderGraph, frameData); @@ -1154,6 +1136,8 @@ private void OnMainRendering(RenderGraph renderGraph, ScriptableRenderContext co // Subtractive mixed lighting requires shadowMask output, which is actually used to store unity_ProbesOcclusion values. m_DeferredLights.CreateGbufferTextures(renderGraph, resourceData, isDepthNormalPrepass); + m_ValidationHandler.OnBeforeGBuffers(renderGraph, resourceData); + RecordCustomRenderGraphPasses(renderGraph, RenderPassEvent.BeforeRenderingGbuffer); bool needsOccluderUpdate = occluderPass == OccluderPass.GBuffer; @@ -1297,6 +1281,8 @@ private void OnMainRendering(RenderGraph renderGraph, ScriptableRenderContext co } #endif + RenderBeforeTransparentsColorHistory(renderGraph, cameraData, resourceData); + #if ENABLE_ADAPTIVE_PERFORMANCE if (needTransparencyPass) #endif @@ -1368,7 +1354,7 @@ private void OnAfterRendering(RenderGraph renderGraph, bool applyPostProcessing) RecordCustomRenderGraphPasses(renderGraph, RenderPassEvent.BeforeRenderingPostProcessing); // There's at least a camera in the camera stack that applies post-processing - bool anyPostProcessing = postProcessingData.isEnabled && m_PostProcess != null; + bool anyPostProcessing = postProcessingData.isEnabled && this.postProcessEnabled; #if ENABLE_UPSCALER_FRAMEWORK bool fsr1Enabled = cameraData.resolvedUpscalerHash == UniversalRenderPipeline.k_UpscalerHash_FSR1; @@ -1469,6 +1455,8 @@ private void OnAfterRendering(RenderGraph renderGraph, bool applyPostProcessing) //Checking resourceData.isActiveTargetBackBuffer is a robust way to check if this has happened, by our own code or by the user. if (!resourceData.isActiveTargetBackBuffer && cameraData.resolveFinalTarget) { + Debug.Assert(!useTileOnlyMode, "Adding the final blit pass when Tile-Only Mode is on. This is not valid and will throw an exception. Likely, an On-Tile Feature has requested the intermediate textures but did not correctly copy the data to the backbuffer."); + debugHandler?.UpdateShaderGlobalPropertiesForFinalValidationPass(renderGraph, cameraData, !resolveToDebugScreen); //Will swap the active camera targets to backbuffer (resourceData.SwitchActiveTexturesToBackbuffer) @@ -1476,14 +1464,40 @@ private void OnAfterRendering(RenderGraph renderGraph, bool applyPostProcessing) } RecordCustomRenderGraphPasses(renderGraph, RenderPassEvent.AfterRendering); - + // We can explicitely render the overlay UI from URP when HDR output is not enabled. // SupportedRenderingFeatures.active.rendersUIOverlay should also be set to true. bool shouldRenderUI = cameraData.rendersOverlayUI && cameraData.isLastBaseCamera; bool outputToHDR = cameraData.isHDROutputActive; if (shouldRenderUI && !outputToHDR) { - m_DrawOverlayUIPass.RenderOverlay(renderGraph, frameData, resourceData.activeColorTexture, resourceData.activeDepthTexture); + var color = resourceData.activeColorTexture; + var cameraDepth = resourceData.cameraDepth; + + TextureHandle depth; + + if (cameraDepth.IsValid() && SystemInfo.supportsBackbufferInMultipleRenderTargets) + { + var backbufferInfo = renderGraph.GetRenderTargetInfo(resourceData.backBufferDepth); + var cameraDepthDesc = renderGraph.GetTextureDesc(in cameraDepth); + + bool matchingDimensions = backbufferInfo.msaaSamples == (int) cameraDepthDesc.msaaSamples + && backbufferInfo.width == cameraDepthDesc.width && backbufferInfo.height == cameraDepthDesc.height + && backbufferInfo.volumeDepth == cameraDepthDesc.slices; + + // Using the cameraDepth avoids switching the depth target, that would break the native render pass. + depth = (matchingDimensions) ? cameraDepth : resourceData.activeDepthTexture; + } + else + { + depth = resourceData.activeDepthTexture; + } + + m_DrawOverlayUIPass.RenderOverlayUIToolkitAndUGUI(renderGraph, frameData, in color, in depth); + + // IMGUI uses an Unsafe pass and is therefore not supported by the on-tile renderer. + if(!(useTileOnlyMode && cameraData.cameraType == CameraType.Game)) + m_DrawOverlayUIPass.RenderOverlayIMGUI(renderGraph, frameData, in color, in depth); } #if ENABLE_VR && ENABLE_XR_MODULE @@ -1625,13 +1639,16 @@ void ImportBackBuffers(RenderGraph renderGraph, UniversalCameraData cameraData, // We cannot use directly !cameraData.rendersOverlayUI but this is similar logic bool isNativeUIOverlayRenderingAfterURP = !SupportedRenderingFeatures.active.rendersUIOverlay && cameraData.resolveToScreen; bool isNativeRenderingAfterURP = UnityEngine.Rendering.Watermark.IsVisible() || isNativeUIOverlayRenderingAfterURP; - // If MSAA > 1, no extra native rendering after SRP and we target the BB directly (!m_RequiresIntermediateAttachments) - // then we can discard MSAA buffers and only resolve, otherwise we must store and resolve - bool noStoreOnlyResolveBBColor = !s_RequiresIntermediateAttachments && !isNativeRenderingAfterURP && (cameraData.cameraTargetDescriptor.msaaSamples > 1); - //Backbuffer orientation is used for either the actual backbuffer (not a texture), or in XR for the eye texture. - bool useActualBackbufferOrienation = !cameraData.isSceneViewCamera && !cameraData.isPreviewCamera && cameraData.targetTexture == null; - TextureUVOrigin backbufferTextureUVOrigin = useActualBackbufferOrienation ? (SystemInfo.graphicsUVStartsAtTop ? TextureUVOrigin.TopLeft : TextureUVOrigin.BottomLeft) : TextureUVOrigin.BottomLeft; + // If MSAA > 1, no extra native rendering after SRP and we target the BB directly + // then we can discard MSAA buffers and only resolve, otherwise we must store and resolve. + // To target the BB directly, either we don't render to the intermediate textures, or we render with the on-tile renderer. + // The on-tile renderer guarantees a single native render pass for the draw passes to the backbuffer, even though + // it potentially uses the intermediate textures as temporary attachments inside of the NRP. + bool intermediateTexturesAreSampledAsTextures = s_RequiresIntermediateAttachments && !useTileOnlyMode; + bool noStoreOnlyResolveBBColor = !intermediateTexturesAreSampledAsTextures && !isNativeRenderingAfterURP && (cameraData.cameraTargetDescriptor.msaaSamples > 1); + + TextureUVOrigin backbufferTextureUVOrigin = RenderingUtils.GetBackBufferUVOrientation(cameraData); ImportResourceParams importBackbufferColorParams = new ImportResourceParams(); importBackbufferColorParams.clearOnFirstUse = clearBackbufferOnFirstUse; @@ -1682,7 +1699,18 @@ void ImportBackBuffers(RenderGraph renderGraph, UniversalCameraData cameraData, { // Backbuffer is the final render target, we obtain its number of MSAA samples through Screen API // in some cases we disable multisampling for optimization purpose - int numSamples = AdjustAndGetScreenMSAASamples(renderGraph, s_RequiresIntermediateAttachments); + //int numSamples = AdjustAndGetScreenMSAASamples(renderGraph, intermediateTexturesAreSampledAsTextures); + + // We need to fix an issue where the MSAA samples are never set back to the Quality setting. + // The MSAA samples only seem to be set when the URP asset is changed. The optimization + // in this function seems fragile, because different renderers can be used, even + // in a single frame. If we change a renderer from rendering to the backbuffer (or on-tile), + // to a renderer that renders to the intermediate textures then they render without MSAA, + // without the user knowing. This is a functional/visual bug. + // https://jira.unity3d.com/browse/UUM-134600 + // This optimization is temporarely disabled until we fix this functional issue. + int numSamples = (!SystemInfo.supportsMultisampledBackBuffer) ? 1 : Mathf.Max(Screen.msaaSamples, 1); + //BuiltinRenderTextureType.CameraTarget so this is either system render target or camera.targetTexture if non null //NOTE: Careful what you use here as many of the properties bake-in the camera rect so for example @@ -1749,6 +1777,7 @@ void CreateIntermediateCameraColorAttachment(RenderGraph renderGraph, UniversalC desc.autoGenerateMips = false; desc.filterMode = FilterMode.Bilinear; desc.wrapMode = TextureWrapMode.Clamp; + desc.bindTextureMS = useTileOnlyMode && desc.msaaSamples != MSAASamples.None; //Needed for GLES fallback // When there's a single camera setup, there's no need to do the double buffer technique with attachment A/B, in order to save memory allocation // and simplify the workflow by using a RenderGraph texture directly. @@ -1876,7 +1905,7 @@ void CreateCameraNormalsTexture(RenderGraph renderGraph, TextureDesc descriptor) DepthNormalOnlyPass.k_CameraNormalsTextureName : DeferredLights.k_GBufferNames[m_DeferredLights.GBufferNormalSmoothnessIndex]; descriptor.format = !usesDeferredLighting ? DepthNormalOnlyPass.GetGraphicsFormat() : m_DeferredLights.GetGBufferFormat(m_DeferredLights.GBufferNormalSmoothnessIndex); - resourceData.cameraNormalsTexture = CreateRenderGraphTexture(renderGraph, descriptor, normalsName, true, Color.black); + resourceData.cameraNormalsTexture = CreateRenderGraphTexture(renderGraph, descriptor, normalsName, true, Color.clear); } void CreateRenderingLayersTexture(RenderGraph renderGraph, TextureDesc descriptor) diff --git a/Packages/com.unity.render-pipelines.universal/Runtime/ValidationHandler.cs b/Packages/com.unity.render-pipelines.universal/Runtime/ValidationHandler.cs index 780b57ffb16..fecc716d4c6 100644 --- a/Packages/com.unity.render-pipelines.universal/Runtime/ValidationHandler.cs +++ b/Packages/com.unity.render-pipelines.universal/Runtime/ValidationHandler.cs @@ -6,29 +6,37 @@ namespace UnityEngine.Rendering.Universal { internal class ValidationHandler { + string k_ErrorMesssageHowToResolve = "The On-Tile Validation layer is activated with the setting 'Tile-Only Mode' on the URP Renderer. " + + "When activated, it is not allowed to sample (RenderGraph.UseTexture) the cameraColor or cameraDepth (intermediate) textures or the GBuffers or any copies of those." + + "You need to disable any of the following that could cause the issue: a URP setting that would break the native render pass, a ScriptableRenderPass that is enqueued " + + "from script, or a ScriptableRenderFeature that is installed on your URP Renderer.\n"; + OnTileValidationLayer m_OnTileValidationLayer; + public bool active { get; set; } - [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] - public void OnBeginRenderGraphFrame(bool onTileValidation) + public ValidationHandler(bool onTileValidation) { if (onTileValidation) - { - if (m_OnTileValidationLayer == null) - m_OnTileValidationLayer = new OnTileValidationLayer(); - } - else - { - m_OnTileValidationLayer = null; + { + m_OnTileValidationLayer = new OnTileValidationLayer(); + m_OnTileValidationLayer.errorMessageHowToResolve = k_ErrorMesssageHowToResolve; } } + [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] + public void OnBeginRenderGraphFrame() + { + + } + [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] public void OnBeforeRendering(RenderGraph renderGraph, UniversalResourceData resourceData) { // Will be null and therefor remove the validation layer when onTileValidation is off - InternalRenderGraphValidation.SetAdditionalValidationLayer(renderGraph, m_OnTileValidationLayer); + InternalRenderGraphValidation.SetAdditionalValidationLayer(renderGraph, + active? m_OnTileValidationLayer : null); - if (m_OnTileValidationLayer != null) + if (m_OnTileValidationLayer != null && active) { m_OnTileValidationLayer.renderGraph = renderGraph; @@ -41,7 +49,7 @@ public void OnBeforeRendering(RenderGraph renderGraph, UniversalResourceData res [Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")] public void OnBeforeGBuffers(RenderGraph renderGraph, UniversalResourceData resourceData) { - if (m_OnTileValidationLayer != null) + if (m_OnTileValidationLayer != null && active) { foreach (TextureHandle handle in resourceData.gBuffer) { diff --git a/Packages/com.unity.render-pipelines.universal/Samples~/URPPackageSamples/RendererFeatures/DepthBlit/DepthBlitCopyDepthPass.cs b/Packages/com.unity.render-pipelines.universal/Samples~/URPPackageSamples/RendererFeatures/DepthBlit/DepthBlitCopyDepthPass.cs index 40c98cedd19..ba71f6de3fe 100644 --- a/Packages/com.unity.render-pipelines.universal/Samples~/URPPackageSamples/RendererFeatures/DepthBlit/DepthBlitCopyDepthPass.cs +++ b/Packages/com.unity.render-pipelines.universal/Samples~/URPPackageSamples/RendererFeatures/DepthBlit/DepthBlitCopyDepthPass.cs @@ -88,8 +88,9 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer builder.SetRenderFunc((PassData data, RasterGraphContext context) => { // Enable an MSAA shader keyword based on the source texture MSAA sample count + // when depth must be resolved manually in the copy shader RTHandle sourceTex = data.source; - int cameraSamples = sourceTex.rt.antiAliasing; + int cameraSamples = sourceTex.rt.bindTextureMS ? sourceTex.rt.antiAliasing : 1; context.cmd.SetKeyword(data.keyword_DepthMsaa2, cameraSamples == 2); context.cmd.SetKeyword(data.keyword_DepthMsaa4, cameraSamples == 4); context.cmd.SetKeyword(data.keyword_DepthMsaa8, cameraSamples == 8); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl new file mode 100644 index 00000000000..dc1636b1272 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl @@ -0,0 +1,670 @@ +#ifndef UNIVERSAL_SSR_INCLUDED +#define UNIVERSAL_SSR_INCLUDED + +// Includes +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl" +#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" +#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + +// Textures & Samplers +TEXTURE2D_X(_CameraColorTexture); +SAMPLER(sampler_CameraColorTexture); + +TEXTURE2D_X(_SmoothnessTexture); +SAMPLER(sampler_SmoothnessTexture); + +TEXTURE2D_X(_MotionVectorColorTexture); +SAMPLER(sampler_MotionVectorColorTexture); + +SAMPLER(sampler_BlitTexture); + +// Params +float4x4 _CameraInverseViewProjections[2]; +float4x4 _CameraProjections[2]; +float4x4 _CameraInverseProjections[2]; +float4x4 _CameraViews[2]; + +float4 _SourceSize; + +TYPED_TEXTURE2D_X(float, _DepthPyramid); +float4 _DepthPyramidMipLevelOffsets[15]; +int _SsrDepthPyramidMaxMip; + +// SSR Settings +float4 _MaxRayLength; +int _MaxRaySteps; +uint _Downsample; +int _HiZTrace; +int _HitRefinementSteps; +float4 _ThicknessScaleAndBias; +float4 _MinimumSmoothnessAndFadeStart; +float4 _ScreenEdgeFadeAndViewConeDot; +int _ReflectSky; + +float GetMaxRayLength() +{ + return _MaxRayLength.x; +} + +float GetRayLengthFadeStart() +{ + return _MaxRayLength.y; +} + +float GetThicknessScale() +{ + return _ThicknessScaleAndBias.x; +} + +float GetThicknessBias() +{ + return _ThicknessScaleAndBias.y; +} + +float GetThicknessScaleFine() +{ + return _ThicknessScaleAndBias.z; +} + +float GetThicknessBiasFine() +{ + return _ThicknessScaleAndBias.w; +} + +float GetViewConeDot() +{ + return _ScreenEdgeFadeAndViewConeDot.z; +} + +float2 GetScreenEdgeFade() +{ + return _ScreenEdgeFadeAndViewConeDot.xy; +} + +float GetMinimumSmoothness() +{ + return _MinimumSmoothnessAndFadeStart.x; +} + +#if defined(USING_STEREO_MATRICES) +#define unity_eyeIndex unity_StereoEyeIndex +#else +#define unity_eyeIndex 0 +#endif + +// Constants +#define SSR_TRACE_EPS 0.000488281f + +// ------------------------------------------------------------------ +// Screen Space Marching +// ------------------------------------------------------------------ +bool TraceScreenSpaceRay( + float2 startPosSS, + float startZ, + float2 endPosSS, + float endZ, + float4 screenSizeWithInverse, + out float3 rayHitPosNDC, + out int iterCount) +{ + // Calculate the step to take each iteration, and the total step count + float rayScreenDeltaX = endPosSS.x - startPosSS.x; + float rayScreenDeltaY = endPosSS.y - startPosSS.y; + float rayScreenDeltaZ = endZ - startZ; + float useDeltaX = abs(rayScreenDeltaX) >= abs(rayScreenDeltaY) ? 1.0 : 0.0; + float rayScreenDelta = min(lerp(abs(rayScreenDeltaY), abs(rayScreenDeltaX), useDeltaX), _MaxRaySteps); + float3 rayStep = float3(rayScreenDeltaX, rayScreenDeltaY, rayScreenDeltaZ) / max(rayScreenDelta, 0.001); + + // March against depth buffer with coarse steps + float3 rayPosSS = float3(startPosSS, startZ); + float rayHitT = 0; + rayHitPosNDC = 0; + float prevT = 0; + bool hitCoarse = false; + + for (iterCount = 0; iterCount < rayScreenDelta; iterCount++) + { + rayPosSS += rayStep; + + // We went offscreen, so stop + if (rayPosSS.x < 0 || rayPosSS.x > screenSizeWithInverse.z || rayPosSS.y < 0 || rayPosSS.y > screenSizeWithInverse.w) + return false; + + // How far along the ray are we in [0; 1]? + rayHitT = lerp((rayPosSS.y - startPosSS.y) / rayScreenDeltaY, (rayPosSS.x - startPosSS.x) / rayScreenDeltaX, useDeltaX); + + // Get current depth of scene at the ray position. + float rawSceneDepth = LoadSceneDepth(rayPosSS.xy * _Downsample); + + // Check if we've hit something + bool aboveBase = !COMPARE_DEVICE_DEPTH_CLOSER(rayPosSS.z, rawSceneDepth); + bool belowFloor = COMPARE_DEVICE_DEPTH_CLOSER(rayPosSS.z, rawSceneDepth * GetThicknessScale() + GetThicknessBias()); + if (aboveBase && belowFloor) + { + hitCoarse = true; + break; + } + prevT = rayHitT; + } + rayHitPosNDC = float3(rayPosSS.xy * screenSizeWithInverse.xy, rayPosSS.z); + + #ifdef _REFINE_DEPTH + if (hitCoarse) + { + // Refine depth by testing intersections at points between the last 2 coarse positions, + // using a smaller thickness value. + float t0 = prevT; + float t1 = 2.0 * rayHitT - t0; + + int step = 0; + bool hitFine = false; + for (; step < _HitRefinementSteps; step++) + { + float t = t0 + (t1 - t0) * 0.5; + + float2 candidateHitPosSS = lerp(startPosSS, endPosSS, t); + candidateHitPosSS = round(candidateHitPosSS - 0.5) + 0.5; // round to nearest texel center + float rayDepth = lerp(startZ, endZ, t); + float rawSceneDepth = LoadSceneDepth(candidateHitPosSS * _Downsample); + + bool aboveBase = !COMPARE_DEVICE_DEPTH_CLOSER(rayDepth, rawSceneDepth); + bool belowFloor = COMPARE_DEVICE_DEPTH_CLOSER(rayDepth, rawSceneDepth * GetThicknessScale() + GetThicknessBias()); + if (aboveBase && belowFloor) + { + hitFine = COMPARE_DEVICE_DEPTH_CLOSER(rayDepth, rawSceneDepth * GetThicknessScaleFine() + GetThicknessBiasFine()); + + rayHitPosNDC = float3(candidateHitPosSS * screenSizeWithInverse.xy, rayDepth); + t1 = t; + } + else + { + t0 = t; + } + } + iterCount += step; + + if (!hitFine) + return false; + } + #endif + + return hitCoarse || _ReflectSky; +} + +bool TraceScreenSpaceRayHiZ( + float2 startPosSS, + float startZ, + float2 endPosSS, + float endZ, + float2 screenSize, + out float3 rayHitPosNDC, + out int iterCount) +{ + // We start tracing from the center of the current pixel, and do so up to the far plane. + float3 rayOrigin = float3(startPosSS, startZ); + + float3 rayDir = float3(endPosSS, endZ) - rayOrigin; + float3 rcpRayDir = rcp(rayDir); + int2 rayStep = int2(rcpRayDir.x >= 0 ? 1 : 0, + rcpRayDir.y >= 0 ? 1 : 0); + float3 raySign = float3(rcpRayDir.x >= 0 ? 1 : -1, + rcpRayDir.y >= 0 ? 1 : -1, + rcpRayDir.z >= 0 ? 1 : -1); + bool rayTowardsEye = rcpRayDir.z >= 0; + + // Extend and clip the end point to the frustum. + float tMax; + { + // Shrink the frustum by half a texel for efficiency reasons. + const float halfTexel = 0.5; + + float3 bounds; + bounds.x = (rcpRayDir.x >= 0) ? screenSize.x - halfTexel : halfTexel; + bounds.y = (rcpRayDir.y >= 0) ? screenSize.y - halfTexel : halfTexel; + // If we do not want to intersect the skybox, it is more efficient to not trace too far. + float maxDepth = (_ReflectSky != 0) ? -0.00000024 : 0.00000024; // 2^-22 + bounds.z = (rcpRayDir.z >= 0) ? 1 : maxDepth; + + float3 dist = bounds * rcpRayDir - (rayOrigin * rcpRayDir); + tMax = Min3(dist.x, dist.y, dist.z); + } + + // Clamp the MIP level to give the compiler more information to optimize. + const int maxMipLevel = min(_SsrDepthPyramidMaxMip, 14); + + // Start ray marching from the next texel to avoid self-intersections. + float t; + { + // 'rayOrigin' is the exact texel center. + float2 dist = abs(0.5 * rcpRayDir.xy); + t = min(dist.x, dist.y); + } + + float3 rayPos; + + int mipLevel = 0; + iterCount = 0; + bool hit = false; + bool miss = false; + bool belowMip0 = false; // This value is set prior to entering the cell + + while (!(hit || miss) && (t <= tMax) && (iterCount < _MaxRaySteps)) + { + rayPos = rayOrigin + t * rayDir; + + // Ray position often ends up on the edge. To determine (and look up) the right cell, + // we need to bias the position by a small epsilon in the direction of the ray. + float2 sgnEdgeDist = round(rayPos.xy) - rayPos.xy; + float2 satEdgeDist = clamp(raySign.xy * sgnEdgeDist + SSR_TRACE_EPS, 0, SSR_TRACE_EPS); + rayPos.xy += raySign.xy * satEdgeDist; + + int2 mipCoord = (int2)rayPos.xy >> mipLevel; + int2 mipOffset = int2(_DepthPyramidMipLevelOffsets[mipLevel].xy); + // Bounds define 4 faces of a cube: + // 2 walls in front of the ray, and a floor and a base below it. + float4 bounds; + + bounds.xy = (mipCoord + rayStep) << mipLevel; + bounds.z = LOAD_TEXTURE2D_X_LOD(_DepthPyramid, int2(mipOffset + mipCoord), 0).r; + + // We define the depth of the base as the depth value as: + // b = DeviceDepth((1 + thickness) * LinearDepth(d)) + // b = ((f - n) * d + n * (1 - (1 + thickness))) / ((f - n) * (1 + thickness)) + // b = ((f - n) * d - n * thickness) / ((f - n) * (1 + thickness)) + // b = d / (1 + thickness) - n / (f - n) * (thickness / (1 + thickness)) + // b = d * k_s + k_b + bounds.w = bounds.z * GetThicknessScale() + GetThicknessBias(); + + float4 dist = bounds * rcpRayDir.xyzz - (rayOrigin.xyzz * rcpRayDir.xyzz); + float distWall = min(dist.x, dist.y); + float distFloor = dist.z; + float distBase = dist.w; + + // Note: 'rayPos' given by 't' can correspond to one of several depth values: + // - above or exactly on the floor + // - inside the floor (between the floor and the base) + // - below the base + bool belowFloor = !COMPARE_DEVICE_DEPTH_CLOSER(rayPos.z, bounds.z); + bool aboveBase = COMPARE_DEVICE_DEPTH_CLOSEREQUAL(rayPos.z, bounds.w); + bool insideFloor = belowFloor && aboveBase; + bool hitFloor = (t <= distFloor) && (distFloor <= distWall); + + // Game rules: + // * if the closest intersection is with the wall of the cell, switch to the coarser MIP, and advance the ray. + // * if the closest intersection is with the heightmap below, switch to the finer MIP, and advance the ray. + // * if the closest intersection is with the heightmap above, switch to the finer MIP, and do NOT advance the ray. + // Victory conditions: + // * See below. Do NOT reorder the statements! + + miss = belowMip0 && insideFloor; + hit = (mipLevel == 0) && (hitFloor || insideFloor); + belowMip0 = (mipLevel == 0) && belowFloor; + + // 'distFloor' can be smaller than the current distance 't'. + // We can also safely ignore 'distBase'. + // If we hit the floor, it's always safe to jump there. + // If we are at (mipLevel != 0) and we are below the floor, we should not move. + t = hitFloor ? distFloor : (((mipLevel != 0) && belowFloor) ? t : distWall); + rayPos.z = bounds.z; // Retain the depth of the potential intersection + + // Warning: both rays towards the eye, and tracing behind objects has linear + // rather than logarithmic complexity! This is due to the fact that we only store + // the maximum value of depth, and not the min-max. + mipLevel += (hitFloor || belowFloor || rayTowardsEye) ? -1 : 1; + mipLevel = clamp(mipLevel, 0, maxMipLevel); + + // mipLevel = 0; + + iterCount++; + } + + // Treat intersections with the sky as misses. + miss = miss || ((_ReflectSky == 0) && (rayPos.z == 0)); + hit = hit && !miss; + + rayHitPosNDC = float3(floor(rayPos.xy) / screenSize + (0.5 / screenSize), rayPos.z); + + return hit; +} + +float2 SampleMotionVector(float2 uv) +{ + return SAMPLE_TEXTURE2D_X(_MotionVectorColorTexture, sampler_MotionVectorColorTexture, uv).xy; +} + +float SampleSmoothness(float2 uv) +{ + return SAMPLE_TEXTURE2D_X(_SmoothnessTexture, sampler_SmoothnessTexture, uv).a; +} + +float4 ComputeSSR(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 positionNDC = input.texcoord; + float2 positionSS = input.positionCS.xy; + float deviceDepth = LoadSceneDepth(uint2(positionSS) * _Downsample).r; + + // If the smoothness is below our minimum, don't do any raymarching + float perceptualSmoothness = SampleSmoothness(positionNDC); + UNITY_BRANCH if (perceptualSmoothness <= GetMinimumSmoothness()) + { + #if UNITY_REVERSED_Z + float alpha = deviceDepth != 0; + #else + float alpha = deviceDepth != 1; + #endif + // Output the framebuffer color -> + // avoids bleeding black/uninitialized texels into reflections when blurring. + // If the pixel is showing skybox, output 0 alpha -> + // avoids bleeding the skybox color into reflections when blurring, which would cause haloing. + // If the pixel is showing an object, output 1 alpha -> + // avoids bleeding 0 alpha into reflections when blurring, which would cause peter-panning. + return float4(SAMPLE_TEXTURE2D_X_LOD(_CameraColorTexture, sampler_CameraColorTexture, positionNDC, 0).rgb, alpha); + } + + // Calculate ray origin and direction in view space and screen space + float3 normalWS = SampleSceneNormals(positionNDC); + float3 positionWS = ComputeWorldSpacePosition(positionNDC, deviceDepth, _CameraInverseViewProjections[unity_eyeIndex]); + float3 positionToCamWS = GetWorldSpaceNormalizeViewDir(positionWS); + float3 positionVS = mul(_CameraViews[unity_eyeIndex], float4(positionWS, 1)).xyz; + float3 rayDirWS = reflect(-positionToCamWS, normalWS); + float3 rayDirVS = SafeNormalize(mul(_CameraViews[unity_eyeIndex], float4(rayDirWS, 0)).xyz); + + // Calculate ray end position in view space and screen space + float rayLength = 1; + + #ifndef _HIZ_TRACE + // Clamp ray length such that the end point is in front of the camera. + // Not needed for Hi-Z path as there is no end point, only a direction. + rayLength = rayDirVS.z > 0 ? min(GetMaxRayLength(), -positionVS.z / rayDirVS.z * 0.999) : GetMaxRayLength(); + #endif + + float3 endPosVS = positionVS + rayDirVS * rayLength; + float3 startPosNDC = float3(positionNDC, deviceDepth); + float3 endPosNDC = ComputeNormalizedDeviceCoordinatesWithZ(endPosVS, _CameraProjections[unity_eyeIndex]); + + #ifndef _HIZ_TRACE + // Clamp ray length such that the end point is within the view frustum. + // Not needed for Hi-Z path as there is no end point, only a direction. + float3 rayDeltaNDC = endPosNDC - startPosNDC; + float rayLengthNDC = length(rayDeltaNDC); + float3 rayDirNDC = rayDeltaNDC * rcp(rayLengthNDC); + float3 maxDistanceNDC = rayDirNDC >= 0 ? (1 - startPosNDC) / rayDirNDC : -startPosNDC / rayDirNDC; + endPosNDC = startPosNDC + rayDirNDC * min(rayLengthNDC, min(maxDistanceNDC.x, min(maxDistanceNDC.y, maxDistanceNDC.z))); + #endif + + float4 screenSizeWithInverse = _BlitTexture_TexelSize; + float2 endPosSS = endPosNDC.xy * screenSizeWithInverse.zw; + + float3 rayHitPosNDC; + int iterCount; + bool hit; + #ifdef _HIZ_TRACE + hit = TraceScreenSpaceRayHiZ(positionSS, deviceDepth, endPosSS.xy, endPosNDC.z, screenSizeWithInverse.zw, rayHitPosNDC, iterCount); + #else + hit = TraceScreenSpaceRay(positionSS, deviceDepth, endPosSS.xy, endPosNDC.z, screenSizeWithInverse, rayHitPosNDC, iterCount); + #endif + + UNITY_BRANCH if (hit) + { + #ifdef _USE_MOTION_VECTORS + rayHitPosNDC.xy -= SampleMotionVector(rayHitPosNDC.xy); + #endif + + float3 hitColor = SAMPLE_TEXTURE2D_X_LOD(_CameraColorTexture, sampler_CameraColorTexture, rayHitPosNDC.xy, 0).rgb; + + // Fade rays pointing toward camera. + float viewDotRay = dot(SafeNormalize(positionVS), rayDirVS); + float viewConeDot = GetViewConeDot(); + const float normalFadeFactor = 0.1; + float fade = smoothstep(viewConeDot, viewConeDot + normalFadeFactor, viewDotRay); + + // Fade rays hitting near the max distance, if we aren't reflecting the sky. + #ifndef _HIZ_TRACE + if (!_ReflectSky) + { + float4 rayHitPosCS = ComputeClipSpacePosition(rayHitPosNDC.xy, rayHitPosNDC.z); + float4 rayHitPosVS = mul(_CameraInverseProjections[unity_eyeIndex], rayHitPosCS); + rayHitPosVS.xyz /= rayHitPosVS.w; + fade *= smoothstep(GetMaxRayLength(), GetRayLengthFadeStart(), distance(positionVS, rayHitPosVS.xyz)); + } + #endif + + // Fade rays reaching near the edge of the screen, to avoid a harsh discontinuity. + float2 edgeDist = smoothstep(0, GetScreenEdgeFade().x, rayHitPosNDC.xy) * smoothstep(1, GetScreenEdgeFade().y, rayHitPosNDC.xy); + fade *= edgeDist.x * edgeDist.y; + + return float4(hitColor, fade); + } + + // Even if we hit nothing, we output the framebuffer color (but with 0 weight). + // This provides the blur/upscale kernel with data needed to avoid blurring black into + // the reflections, which leads to ugly borders. + return float4(SAMPLE_TEXTURE2D_X_LOD(_CameraColorTexture, sampler_CameraColorTexture, positionNDC, 0).rgb, 0); +} + +// ------------------------------------------------------------------ +// Compositing for AfterOpaque mode +// ------------------------------------------------------------------ +float4 CompositeSSRAfterOpaque(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord); + + float perceptualSmoothness = SAMPLE_TEXTURE2D_X(_SmoothnessTexture, sampler_SmoothnessTexture, uv).a; + + // Map roughness to mip level to get blur. + float perceptualRoughness = PerceptualSmoothnessToPerceptualRoughness(perceptualSmoothness); + float mipLevel = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + float4 reflColor = SAMPLE_TEXTURE2D_X_LOD(_BlitTexture, sampler_TrilinearClamp, uv, mipLevel); + + // Fade out reflections with smoothness. + // Not physically correct, but we can't do much better without more data. + reflColor.a *= perceptualSmoothness; + + return reflColor; +} + +// ------------------------------------------------------------------ +// Bilateral Blur +// ------------------------------------------------------------------ +#define SAMPLE_BASEMAP(uv) float4(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, UnityStereoTransformScreenSpaceTex(uv))); + +float CompareNormal(float3 d1, float3 d2) +{ + return smoothstep(0.8, 1.0, dot(d1, d2)); +} + +// Geometry-aware separable bilateral filter +float4 BilateralBlur(const float2 uv, const float2 delta) : SV_Target +{ + float4 p0 = SAMPLE_BASEMAP(uv); + float4 p1a = SAMPLE_BASEMAP(uv - delta * 1.3846153846); + float4 p1b = SAMPLE_BASEMAP(uv + delta * 1.3846153846); + float4 p2a = SAMPLE_BASEMAP(uv - delta * 3.2307692308); + float4 p2b = SAMPLE_BASEMAP(uv + delta * 3.2307692308); + + float3 n0 = SampleSceneNormals(uv); + float3 n1a = SampleSceneNormals(uv - delta * 1.3846153846); + float3 n1b = SampleSceneNormals(uv + delta * 1.3846153846); + float3 n2a = SampleSceneNormals(uv - delta * 3.2307692308); + float3 n2b = SampleSceneNormals(uv + delta * 3.2307692308); + + float w0 = float(0.2270270270); + float w1a = CompareNormal(n0, n1a) * float(0.3162162162); + float w1b = CompareNormal(n0, n1b) * float(0.3162162162); + float w2a = CompareNormal(n0, n2a) * float(0.0702702703); + float w2b = CompareNormal(n0, n2b) * float(0.0702702703); + + float4 s = 0.0; + s += p0 * w0; + s += p1a * w1a; + s += p1b * w1b; + s += p2a * w2a; + s += p2b * w2b; + s *= rcp(w0 + w1a + w1b + w2a + w2b); + + return s; +} + +// Geometry-aware bilateral filter (single pass/small kernel) +float4 BilateralBlurSinglePass(const float2 uv, const float2 delta) +{ + float4 p0 = SAMPLE_BASEMAP(uv ); + float4 p1 = SAMPLE_BASEMAP(uv + float2(-delta.x, -delta.y)); + float4 p2 = SAMPLE_BASEMAP(uv + float2( delta.x, -delta.y)); + float4 p3 = SAMPLE_BASEMAP(uv + float2(-delta.x, delta.y)); + float4 p4 = SAMPLE_BASEMAP(uv + float2( delta.x, delta.y)); + + float3 n0 = SampleSceneNormals(uv); + float3 n1a = SampleSceneNormals(uv - delta * 1.3846153846); + float3 n1b = SampleSceneNormals(uv + delta * 1.3846153846); + float3 n2a = SampleSceneNormals(uv - delta * 3.2307692308); + float3 n2b = SampleSceneNormals(uv + delta * 3.2307692308); + + float w0 = 1.0; + float w1 = CompareNormal(n0, n1a); + float w2 = CompareNormal(n0, n1b); + float w3 = CompareNormal(n0, n2a); + float w4 = CompareNormal(n0, n2b); + + float4 s = 0.0; + s += p0 * w0; + s += p1 * w1; + s += p2 * w2; + s += p3 * w3; + s += p4 * w4; + + return s *= rcp(w0 + w1 + w2 + w3 + w4); +} + +float4 HorizontalBilateralBlur(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + const float2 uv = input.texcoord; + const float2 delta = float2(_SourceSize.z * _Downsample, 0.0); + return BilateralBlur(uv, delta); +} + +float4 VerticalBilateralBlur(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + const float2 uv = input.texcoord; + const float2 delta = float2(0.0, _SourceSize.w * _Downsample); + return BilateralBlur(uv, delta); +} + +float4 FinalBilateralBlur(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + const float2 uv = input.texcoord; + const float2 delta = _SourceSize.zw * _Downsample; + return BilateralBlurSinglePass(uv, delta ); +} + +// ------------------------------------------------------------------ +// Gaussian Blur +// ------------------------------------------------------------------ +float4 GaussianBlur(float2 uv, float2 pixelOffset) +{ + float4 colOut = 0; + + // Kernel width 7 x 7 + const int stepCount = 2; + + const half gWeights[stepCount] ={ + 0.44908, + 0.05092 + }; + const half gOffsets[stepCount] ={ + 0.53805, + 2.06278 + }; + + UNITY_UNROLL + for( int i = 0; i < stepCount; i++ ) + { + float2 texCoordOffset = gOffsets[i] * pixelOffset; + float4 p1 = SAMPLE_BASEMAP(uv + texCoordOffset); + float4 p2 = SAMPLE_BASEMAP(uv - texCoordOffset); + float4 col = p1 + p2; + colOut += gWeights[i] * col; + } + + return colOut; +} + +float4 HorizontalGaussianBlur(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = input.texcoord; + float2 delta = float2(_SourceSize.z * _Downsample, 0.0); + return GaussianBlur(uv, delta); +} + +float4 VerticalGaussianBlur(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = input.texcoord; + float2 delta = float2(0.0, _SourceSize.w * _Downsample); + return GaussianBlur(uv, delta); +} + +// ------------------------------------------------------------------ +// Kawase Blur +// ------------------------------------------------------------------ +float4 KawaseBlurFilter(float2 texCoord, float2 pixelSize) +{ + float2 texCoordSample; + float2 halfPixelSize = pixelSize * 0.5; + float2 dUV = halfPixelSize.xy; + + float4 cOut; + + // Sample top left pixel + texCoordSample.x = texCoord.x - dUV.x; + texCoordSample.y = texCoord.y + dUV.y; + cOut = SAMPLE_BASEMAP(texCoordSample); + + // Sample top right pixel + texCoordSample.x = texCoord.x + dUV.x; + texCoordSample.y = texCoord.y + dUV.y; + cOut += SAMPLE_BASEMAP(texCoordSample); + + // Sample bottom right pixel + texCoordSample.x = texCoord.x + dUV.x; + texCoordSample.y = texCoord.y - dUV.y; + cOut += SAMPLE_BASEMAP(texCoordSample); + + // Sample bottom left pixel + texCoordSample.x = texCoord.x - dUV.x; + texCoordSample.y = texCoord.y - dUV.y; + cOut += SAMPLE_BASEMAP(texCoordSample); + + // Average + cOut *= 0.25; + + return cOut; +} + +float4 KawaseBlur(Varyings input) : SV_Target +{ + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + + float2 uv = input.texcoord; + float2 texelSize = _SourceSize.zw * _Downsample; + return KawaseBlurFilter(uv, texelSize); +} + +#endif //UNIVERSAL_SSR_INCLUDED diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl.meta new file mode 100644 index 00000000000..2c7bfdbb8c5 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3ea3b96bfb18c244d807bea74fe8a9d5 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl index ce94f789b1d..695f6f00a47 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl @@ -9,15 +9,11 @@ float4 _CameraDepthTexture_TexelSize; // 2023.3 Deprecated. This is for backwards compatibility. Remove in the future. #define sampler_CameraDepthTexture sampler_PointClamp -float SampleSceneDepth(float2 uv, SAMPLER(samplerParam)) -{ - uv = ClampAndScaleUVForBilinear(UnityStereoTransformScreenSpaceTex(uv), _CameraDepthTexture_TexelSize.xy); - return SAMPLE_TEXTURE2D_X(_CameraDepthTexture, samplerParam, uv).r; -} - float SampleSceneDepth(float2 uv) { - return SampleSceneDepth(uv, sampler_PointClamp); + uv = ClampAndScaleUVForBilinear(UnityStereoTransformScreenSpaceTex(uv), _CameraDepthTexture_TexelSize.xy); + uint2 pixelCoord = uint2(uv * _CameraDepthTexture_TexelSize.zw); + return LOAD_TEXTURE2D_X(_CameraDepthTexture, pixelCoord).r; } float LoadSceneDepth(uint2 pixelCoords) diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl index dddcf60e29c..ddfa4d612b3 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl @@ -4,6 +4,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RealtimeLights.hlsl" +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl" #define AMBIENT_PROBE_BUFFER 0 #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/AmbientProbe.hlsl" @@ -207,7 +208,11 @@ half3 SampleLightmap(float2 staticLightmapUV, half3 normalWS) } #if defined(_SCREEN_SPACE_IRRADIANCE) -#define SAMPLE_GI(irradianceTex, pos) SampleScreenSpaceGI(pos) + #if !defined(_SURFACE_TYPE_TRANSPARENT) + #define SAMPLE_GI(irradianceTex, pos, normal) SampleScreenSpaceGI(pos) + #else + #define SAMPLE_GI(irradianceTex, pos, normal) EvaluateAmbientProbe(normal) + #endif #elif defined(LIGHTMAP_ON) && defined(DYNAMICLIGHTMAP_ON) #define SAMPLE_GI(staticLmName, dynamicLmName, shName, normalWSName) SampleLightmap(staticLmName, dynamicLmName, normalWSName) #elif defined(DYNAMICLIGHTMAP_ON) @@ -215,11 +220,11 @@ half3 SampleLightmap(float2 staticLightmapUV, half3 normalWS) #elif defined(LIGHTMAP_ON) #define SAMPLE_GI(staticLmName, shName, normalWSName) SampleLightmap(staticLmName, 0, normalWSName) #elif defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2) -#ifdef USE_APV_PROBE_OCCLUSION - #define SAMPLE_GI(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) SampleProbeVolumePixel(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) -#else - #define SAMPLE_GI(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) SampleProbeVolumePixel(shName, absolutePositionWS, normalWS, viewDir, positionSS) -#endif + #ifdef USE_APV_PROBE_OCCLUSION + #define SAMPLE_GI(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) SampleProbeVolumePixel(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) + #else + #define SAMPLE_GI(shName, absolutePositionWS, normalWS, viewDir, positionSS, vertexProbeOcclusion, probeOcclusion) SampleProbeVolumePixel(shName, absolutePositionWS, normalWS, viewDir, positionSS) + #endif #else #define SAMPLE_GI(staticLmName, shName, normalWSName) SampleSHPixel(shName, normalWSName) #endif @@ -372,7 +377,7 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi if (weightProbe0 > 0.01f) { half3 reflectVector0 = reflectVector; - if (_REFLECTION_PROBE_BOX_PROJECTION) + if (_REFLECTION_PROBE_BOX_PROJECTION) { #if defined(REFLECTION_PROBE_ROTATION) reflectVector0 = BoxProjectedCubemapDirection(unity_SpecCube0_Rotation, reflectVector, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); @@ -417,37 +422,52 @@ half3 CalculateIrradianceFromReflectionProbes(half3 reflectVector, float3 positi half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV) { - half3 irradiance; - -#if !defined(_ENVIRONMENTREFLECTIONS_OFF) - if (_REFLECTION_PROBE_BLENDING) - { - irradiance = CalculateIrradianceFromReflectionProbes(reflectVector, positionWS, perceptualRoughness, normalizedScreenSpaceUV); - } - else + half3 irradiance = 0; + #if defined(_SCREENSPACEREFLECTIONS_OFF) + half4 ssrColor = 0; + #else + half4 ssrColor = GetScreenSpaceReflection(normalizedScreenSpaceUV, perceptualRoughness); + #endif + + // We skip sampling reflection probes if they would be overwritten by SSR anyways. + // This optimization causes a miscompilation when using FXC, and the rendering path + // is single pass stereo instancing, so disable it in that path. + #if !defined(STEREO_INSTANCING_ON) || defined(UNITY_COMPILER_DXC) + if (ssrColor.a < 1.0) + #endif { - if (_REFLECTION_PROBE_BOX_PROJECTION) + #if !defined(_ENVIRONMENTREFLECTIONS_OFF) + if (_REFLECTION_PROBE_BLENDING) { - #if defined(REFLECTION_PROBE_ROTATION) - float3 probeCenterPosWS0 = unity_SpecCube0_BoxMin.xyz + (unity_SpecCube0_BoxMax.xyz - unity_SpecCube0_BoxMin.xyz) / 2; - float3 rotPosWS0 = RotateVectorByQuat(unity_SpecCube0_Rotation, positionWS - probeCenterPosWS0) + probeCenterPosWS0; - half3 rotReflectVector0 = RotateVectorByQuat(unity_SpecCube0_Rotation, reflectVector); - float4 inverseRotation0 = -unity_SpecCube0_Rotation; - inverseRotation0.w = -inverseRotation0.w; - reflectVector = BoxProjectedCubemapDirection(rotReflectVector0, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - reflectVector = RotateVectorByQuat(inverseRotation0, reflectVector); - #else - reflectVector = BoxProjectedCubemapDirection(reflectVector, positionWS, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); - #endif + irradiance = CalculateIrradianceFromReflectionProbes(reflectVector, positionWS, perceptualRoughness, normalizedScreenSpaceUV); } - half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness); - half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip)); - - irradiance = DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR); + else + { + if (_REFLECTION_PROBE_BOX_PROJECTION) + { + #if defined(REFLECTION_PROBE_ROTATION) + float3 probeCenterPosWS0 = unity_SpecCube0_BoxMin.xyz + (unity_SpecCube0_BoxMax.xyz - unity_SpecCube0_BoxMin.xyz) / 2; + float3 rotPosWS0 = RotateVectorByQuat(unity_SpecCube0_Rotation, positionWS - probeCenterPosWS0) + probeCenterPosWS0; + half3 rotReflectVector0 = RotateVectorByQuat(unity_SpecCube0_Rotation, reflectVector); + float4 inverseRotation0 = -unity_SpecCube0_Rotation; + inverseRotation0.w = -inverseRotation0.w; + reflectVector = BoxProjectedCubemapDirection(rotReflectVector0, rotPosWS0, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); + reflectVector = RotateVectorByQuat(inverseRotation0, reflectVector); + #else + reflectVector = BoxProjectedCubemapDirection(reflectVector, positionWS, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax); + #endif + } + half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + half4 encodedIrradiance = half4(SAMPLE_TEXTURECUBE_LOD(unity_SpecCube0, samplerunity_SpecCube0, reflectVector, mip)); + + irradiance = DecodeHDREnvironment(encodedIrradiance, unity_SpecCube0_HDR); + } + #else // _ENVIRONMENTREFLECTIONS_OFF + irradiance = _GlossyEnvironmentColor.rgb; + #endif // !_ENVIRONMENTREFLECTIONS_OFF } -#else // _ENVIRONMENTREFLECTIONS_OFF - irradiance = _GlossyEnvironmentColor.rgb; -#endif // !_ENVIRONMENTREFLECTIONS_OFF + + irradiance = lerp(irradiance.rgb, ssrColor.rgb, ssrColor.a); return irradiance * occlusion; } diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl index fe30ce9367e..6c79c35a090 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl @@ -125,6 +125,12 @@ uint _MainLightLayerMask; // w: directLightStrength half4 _AmbientOcclusionParam; +// x: SSR Enabled/Disabled (Needed for situations when OFF keyword is stripped out but feature disabled in runtime) +// y: Minimum smoothness, used as a mask for SSR. +// z: Smoothness fade start. +// w is currently unused +half4 _ScreenSpaceReflectionParam; + half4 _AdditionalLightsCount; uint _RenderingLayerMaxInt; diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/NormalReconstruction.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/NormalReconstruction.hlsl index d59972c6dfb..697649b0ab4 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/NormalReconstruction.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/NormalReconstruction.hlsl @@ -13,7 +13,7 @@ float4x4 _NormalReconstructionMatrix[2]; float GetRawDepth(float2 uv) { - return SampleSceneDepth(uv.xy, sampler_PointClamp).r; + return SampleSceneDepth(uv.xy).r; } // inspired by keijiro's depth inverse projection diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl index 42c4bd935c5..2963ba74749 100644 --- a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl @@ -31,7 +31,7 @@ struct Attributes { float4 position : POSITION; -#if _ALPHATEST_ON +#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT float2 uv : TEXCOORD0; #endif float3 positionOld : TEXCOORD4; @@ -46,7 +46,7 @@ struct Varyings float4 positionCS : SV_POSITION; float4 positionCSNoJitter : POSITION_CS_NO_JITTER; float4 previousPositionCSNoJitter : PREV_POSITION_CS_NO_JITTER; -#if _ALPHATEST_ON +#if _ALPHATEST_ON || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT float2 uv : TEXCOORD0; #endif UNITY_VERTEX_INPUT_INSTANCE_ID @@ -65,7 +65,7 @@ Varyings vert(Attributes input) const VertexPositionInputs vertexInput = GetVertexPositionInputs(input.position.xyz); - #if defined(_ALPHATEST_ON) + #if defined(_ALPHATEST_ON) || APPLICATION_SPACE_WARP_MOTION_TRANSPARENT output.uv = TRANSFORM_TEX(input.uv, _BaseMap); #endif @@ -106,6 +106,9 @@ float4 frag(Varyings input) : SV_Target #endif #if defined(APPLICATION_SPACE_WARP_MOTION) + #if APPLICATION_SPACE_WARP_MOTION_TRANSPARENT + clip((SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a * _BaseColor.a) - 0.001); + #endif return float4(CalcAswNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 1); #else return float4(CalcNdcMotionVectorFromCsPositions(input.positionCSNoJitter, input.previousPositionCSNoJitter), 0, 0); diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl new file mode 100644 index 00000000000..13f6953346f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl @@ -0,0 +1,37 @@ +#ifndef SAMPLE_SCREEN_SPACE_REFLECTION_INCLUDED +#define SAMPLE_SCREEN_SPACE_REFLECTION_INCLUDED + +#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + +// SSR reflection color +TEXTURE2D_X(_ScreenSpaceReflectionTexture); + +half4 SampleScreenSpaceReflection(float2 normalizedScreenSpaceUV, float perceptualRoughness) +{ + float2 uv = UnityStereoTransformScreenSpaceTex(normalizedScreenSpaceUV); + + // Map roughness to mip level to get blur. + float mipLevel = PerceptualRoughnessToMipmapLevel(perceptualRoughness); + float4 reflColor = SAMPLE_TEXTURE2D_X_LOD(_ScreenSpaceReflectionTexture, sampler_TrilinearClamp, uv, mipLevel); + + // Fade out reflections for pixels that have smoothness below our minimum. + float perceptualSmoothness = PerceptualRoughnessToPerceptualSmoothness(perceptualRoughness); + float fadeStart = _ScreenSpaceReflectionParam.y; + float fadeEnd = _ScreenSpaceReflectionParam.z; + float fade = smoothstep(fadeStart, fadeEnd, perceptualSmoothness); + reflColor.a *= fade; + + return reflColor; +} + +half4 GetScreenSpaceReflection(float2 normalizedScreenSpaceUV, float perceptualRoughness) +{ +#if _SCREEN_SPACE_REFLECTION_KEYWORD_DECLARED + if (_SCREEN_SPACE_REFLECTION) + return SampleScreenSpaceReflection(normalizedScreenSpaceUV, perceptualRoughness) * _ScreenSpaceReflectionParam.x; + else +#endif + return 0; +} + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl.meta b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl.meta new file mode 100644 index 00000000000..e0c1454979f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/ShaderLibrary/SampleScreenSpaceReflection.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 229e2e6b5e442024a819f1a5bc578442 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl index 3b888875bd5..06b21292140 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/2D/Include/Core2D.hlsl @@ -100,7 +100,7 @@ float3 UnitySkinSprite( in float3 inputData, in uint4 blendIndices, in float4 bl void SetUpSpriteInstanceProperties() { -#ifdef UNITY_INSTANCING_ENABLED +#if defined(UNITY_INSTANCING_ENABLED) && !defined(HAVE_VFX_MODIFICATION) unity_SpriteProps.xy = unity_SpriteFlip; #endif } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader index 8bdf123f0db..89312d9872a 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLit.shader @@ -395,6 +395,7 @@ Shader "Universal Render Pipeline/Baked Lit" HLSLPROGRAM #pragma shader_feature_local _ALPHATEST_ON #pragma multi_compile _ LOD_FADE_CROSSFADE + #pragma multi_compile _ APPLICATION_SPACE_WARP_MOTION_TRANSPARENT #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #define APPLICATION_SPACE_WARP_MOTION 1 diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl index 3e40f5c0132..5e3452c7934 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitForwardPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_BAKEDLIT_FORWARD_PASS_INCLUDED #define UNIVERSAL_BAKEDLIT_FORWARD_PASS_INCLUDED +#include "BakedLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #if defined(LOD_FADE_CROSSFADE) #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" @@ -174,7 +175,7 @@ void BakedLitForwardPassFragment( half4 finalColor = UniversalFragmentBakedLit(inputData, color, alpha, normalTS); - finalColor.a = OutputAlpha(finalColor.a, _Surface); + finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent()); outColor = finalColor; #ifdef _WRITE_RENDERING_LAYERS @@ -182,4 +183,4 @@ void BakedLitForwardPassFragment( #endif } -#endif \ No newline at end of file +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl index 735e3d27493..984d549d9f0 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/BakedLitInput.hlsl @@ -3,6 +3,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; @@ -11,7 +12,6 @@ CBUFFER_START(UnityPerMaterial) half _Cutoff; half _Glossiness; half _Metallic; - half _Surface; UNITY_TEXTURE_STREAMING_DEBUG_VARS; CBUFFER_END @@ -22,14 +22,12 @@ UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(float , _Cutoff) UNITY_DOTS_INSTANCED_PROP(float , _Glossiness) UNITY_DOTS_INSTANCED_PROP(float , _Metallic) - UNITY_DOTS_INSTANCED_PROP(float , _Surface) UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata) static float4 unity_DOTS_Sampled_BaseColor; static float unity_DOTS_Sampled_Cutoff; static float unity_DOTS_Sampled_Glossiness; static float unity_DOTS_Sampled_Metallic; -static float unity_DOTS_Sampled_Surface; void SetupDOTSBakedLitMaterialPropertyCaches() { @@ -37,7 +35,6 @@ void SetupDOTSBakedLitMaterialPropertyCaches() unity_DOTS_Sampled_Cutoff = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Cutoff); unity_DOTS_Sampled_Glossiness = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Glossiness); unity_DOTS_Sampled_Metallic = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Metallic); - unity_DOTS_Sampled_Surface = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Surface); } #undef UNITY_SETUP_DOTS_MATERIAL_PROPERTY_CACHES @@ -47,7 +44,6 @@ void SetupDOTSBakedLitMaterialPropertyCaches() #define _Cutoff unity_DOTS_Sampled_Cutoff #define _Glossiness unity_DOTS_Sampled_Glossiness #define _Metallic unity_DOTS_Sampled_Metallic -#define _Surface unity_DOTS_Sampled_Surface #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader index 4803b9211d0..755a89af0e3 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ComplexLit.shader @@ -24,6 +24,7 @@ Shader "Universal Render Pipeline/Complex Lit" [ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 + [ToggleOff] _ScreenSpaceReflections("Screen Space Reflections", Float) = 1.0 _BumpScale("Scale", Float) = 1.0 _BumpMap("Normal Map", 2D) = "bump" {} @@ -131,6 +132,7 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma shader_feature_local_fragment _ _CLEARCOAT _CLEARCOATMAP #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF + #pragma shader_feature_local_fragment _SCREENSPACEREFLECTIONS_OFF #pragma shader_feature_local_fragment _SPECULAR_SETUP // ------------------------------------- @@ -151,6 +153,7 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION @@ -281,6 +284,7 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF + #pragma shader_feature_local_fragment _SCREENSPACEREFLECTIONS_OFF #pragma shader_feature_local_fragment _SPECULAR_SETUP #pragma shader_feature_local _RECEIVE_SHADOWS_OFF @@ -291,6 +295,7 @@ Shader "Universal Render Pipeline/Complex Lit" //#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED @@ -398,11 +403,14 @@ Shader "Universal Render Pipeline/Complex Lit" #pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED #pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP + #pragma shader_feature_local_fragment _SCREENSPACEREFLECTIONS_OFF // ------------------------------------- // Universal Pipeline keywords #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT // forward-only variant #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" + #pragma multi_compile _ _WRITE_SMOOTHNESS // ------------------------------------- // Unity defined keywords @@ -528,6 +536,7 @@ Shader "Universal Render Pipeline/Complex Lit" HLSLPROGRAM #pragma shader_feature_local _ALPHATEST_ON #pragma multi_compile _ LOD_FADE_CROSSFADE + #pragma multi_compile _ APPLICATION_SPACE_WARP_MOTION_TRANSPARENT #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #define APPLICATION_SPACE_WARP_MOTION 1 diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader index 71fdd29999d..1bc71daced6 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Lit.shader @@ -21,6 +21,7 @@ Shader "Universal Render Pipeline/Lit" [ToggleOff] _SpecularHighlights("Specular Highlights", Float) = 1.0 [ToggleOff] _EnvironmentReflections("Environment Reflections", Float) = 1.0 + [ToggleOff] _ScreenSpaceReflections("Screen Space Reflections", Float) = 1.0 _BumpScale("Scale", Float) = 1.0 _BumpMap("Normal Map", 2D) = "bump" {} @@ -131,6 +132,7 @@ Shader "Universal Render Pipeline/Lit" #pragma shader_feature_local_fragment _OCCLUSIONMAP #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF + #pragma shader_feature_local_fragment _SCREENSPACEREFLECTIONS_OFF #pragma shader_feature_local_fragment _SPECULAR_SETUP // ------------------------------------- @@ -145,6 +147,7 @@ Shader "Universal Render Pipeline/Lit" #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _SCREEN_SPACE_IRRADIANCE @@ -278,6 +281,7 @@ Shader "Universal Render Pipeline/Lit" #pragma shader_feature_local_fragment _SPECULARHIGHLIGHTS_OFF #pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF + #pragma shader_feature_local_fragment _SCREENSPACEREFLECTIONS_OFF #pragma shader_feature_local_fragment _SPECULAR_SETUP #pragma shader_feature_local _RECEIVE_SHADOWS_OFF @@ -288,6 +292,7 @@ Shader "Universal Render Pipeline/Lit" //#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED @@ -396,6 +401,8 @@ Shader "Universal Render Pipeline/Lit" #pragma shader_feature_local _ _DETAIL_MULX2 _DETAIL_SCALED #pragma shader_feature_local _ALPHATEST_ON #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A + #pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP + #pragma shader_feature_local_fragment _SCREENSPACEREFLECTIONS_OFF // ------------------------------------- // Unity defined keywords @@ -404,6 +411,8 @@ Shader "Universal Render Pipeline/Lit" // ------------------------------------- // Universal Pipeline keywords #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" + #pragma multi_compile _ _WRITE_SMOOTHNESS + #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT //-------------------------------------- // GPU Instancing @@ -527,6 +536,7 @@ Shader "Universal Render Pipeline/Lit" HLSLPROGRAM #pragma shader_feature_local _ALPHATEST_ON #pragma multi_compile _ LOD_FADE_CROSSFADE + #pragma multi_compile _ APPLICATION_SPACE_WARP_MOTION_TRANSPARENT #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #define APPLICATION_SPACE_WARP_MOTION 1 diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl index e2cbc01382d..fe1a88948dc 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitDepthNormalsPass.hlsl @@ -18,7 +18,7 @@ #define REQUIRES_WORLD_SPACE_TANGENT_INTERPOLATOR #endif -#if defined(_ALPHATEST_ON) || defined(_PARALLAXMAP) || defined(_NORMALMAP) || defined(_DETAIL) +#if defined(_ALPHATEST_ON) || defined(_PARALLAXMAP) || defined(_NORMALMAP) || defined(_DETAIL) || defined(_WRITE_SMOOTHNESS) #define REQUIRES_UV_INTERPOLATOR #endif @@ -99,8 +99,12 @@ void DepthNormalsFragment( UNITY_SETUP_INSTANCE_ID(input); UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); + #if defined(_ALPHATEST_ON) || defined(_WRITE_SMOOTHNESS) + float alpha = SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a; + #endif + #if defined(_ALPHATEST_ON) - Alpha(SampleAlbedoAlpha(input.uv, TEXTURE2D_ARGS(_BaseMap, sampler_BaseMap)).a, _BaseColor, _Cutoff); + Alpha(alpha, _BaseColor, _Cutoff); #endif #if defined(LOD_FADE_CROSSFADE) @@ -142,6 +146,10 @@ void DepthNormalsFragment( outNormalWS = half4(NormalizeNormalPerPixel(normalWS), 0.0); #endif + #if defined(_WRITE_SMOOTHNESS) && !defined(_SCREENSPACEREFLECTIONS_OFF) + outNormalWS.a = SampleMetallicSpecGloss(input.uv, alpha).a; + #endif + #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl index b6162a6ea6a..1764c2a7f21 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitForwardPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_FORWARD_LIT_PASS_INCLUDED #define UNIVERSAL_FORWARD_LIT_PASS_INCLUDED +#include "LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" @@ -145,7 +146,7 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); @@ -273,7 +274,7 @@ void LitPassFragment( half4 color = UniversalFragmentPBR(inputData, surfaceData); color.rgb = MixFog(color.rgb, inputData.fogCoord); - color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent(_Surface)); + color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); outColor = color; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl index 9d88a219c3d..707f7836437 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl @@ -113,7 +113,7 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl index f5032e24fe1..badb5448dca 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl @@ -7,6 +7,7 @@ #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ParallaxMapping.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DBuffer.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" #if defined(_DETAIL_MULX2) || defined(_DETAIL_SCALED) #define _DETAIL @@ -30,7 +31,6 @@ half _ClearCoatMask; half _ClearCoatSmoothness; half _DetailAlbedoMapScale; half _DetailNormalMapScale; -half _Surface; UNITY_TEXTURE_STREAMING_DEBUG_VARS; CBUFFER_END @@ -53,7 +53,6 @@ UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(float , _ClearCoatSmoothness) UNITY_DOTS_INSTANCED_PROP(float , _DetailAlbedoMapScale) UNITY_DOTS_INSTANCED_PROP(float , _DetailNormalMapScale) - UNITY_DOTS_INSTANCED_PROP(float , _Surface) UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata) // Here, we want to avoid overriding a property like e.g. _BaseColor with something like this: @@ -79,7 +78,6 @@ static float unity_DOTS_Sampled_ClearCoatMask; static float unity_DOTS_Sampled_ClearCoatSmoothness; static float unity_DOTS_Sampled_DetailAlbedoMapScale; static float unity_DOTS_Sampled_DetailNormalMapScale; -static float unity_DOTS_Sampled_Surface; void SetupDOTSLitMaterialPropertyCaches() { @@ -96,7 +94,6 @@ void SetupDOTSLitMaterialPropertyCaches() unity_DOTS_Sampled_ClearCoatSmoothness = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _ClearCoatSmoothness); unity_DOTS_Sampled_DetailAlbedoMapScale = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _DetailAlbedoMapScale); unity_DOTS_Sampled_DetailNormalMapScale = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _DetailNormalMapScale); - unity_DOTS_Sampled_Surface = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Surface); } #undef UNITY_SETUP_DOTS_MATERIAL_PROPERTY_CACHES @@ -115,7 +112,6 @@ void SetupDOTSLitMaterialPropertyCaches() #define _ClearCoatSmoothness unity_DOTS_Sampled_ClearCoatSmoothness #define _DetailAlbedoMapScale unity_DOTS_Sampled_DetailAlbedoMapScale #define _DetailNormalMapScale unity_DOTS_Sampled_DetailNormalMapScale -#define _Surface unity_DOTS_Sampled_Surface #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader index f728bc82a0e..36c36e442a8 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8.shader @@ -62,6 +62,7 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile _ LOD_FADE_CROSSFADE #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION @@ -253,10 +254,13 @@ Shader "Universal Render Pipeline/Nature/SpeedTree8" #pragma shader_feature_local_vertex _WINDQUALITY_NONE _WINDQUALITY_FAST _WINDQUALITY_BETTER _WINDQUALITY_BEST _WINDQUALITY_PALM #pragma shader_feature_local EFFECT_BUMP + #pragma shader_feature_local_fragment EFFECT_EXTRA_TEX #pragma multi_compile _ LOD_FADE_CROSSFADE #pragma multi_compile_instancing #pragma multi_compile_vertex LOD_FADE_PERCENTAGE + #pragma multi_compile _ _WRITE_SMOOTHNESS + #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma instancing_options assumeuniformscaling maxcount:50 diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl index 5b702d20636..954c6745128 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree8Passes.hlsl @@ -595,11 +595,21 @@ half4 SpeedTree8FragDepthNormal(SpeedTreeDepthNormalFragmentInput input) : SV_Ta normalTs = normalize(normalTs); #endif + half outputAlpha = 0.0; + #ifdef _WRITE_SMOOTHNESS + #ifdef EFFECT_EXTRA_TEX + half4 extra = tex2D(_ExtraTex, uv); + outputAlpha = extra.r; + #else + outputAlpha = _Glossiness; + #endif + #endif + #if defined(EFFECT_BUMP) float3 normalWS = TransformTangentToWorld(normalTs, half3x3(input.interpolated.tangentWS.xyz, input.interpolated.bitangentWS.xyz, input.interpolated.normalWS.xyz)); - return half4(NormalizeNormalPerPixel(normalWS), 0.0h); + return half4(NormalizeNormalPerPixel(normalWS), outputAlpha); #else - return half4(NormalizeNormalPerPixel(input.interpolated.normalWS), 0.0h); + return half4(NormalizeNormalPerPixel(input.interpolated.normalWS), outputAlpha); #endif } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader b/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader index f7c59521678..43816444345 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/ObjectMotionVectorFallback.shader @@ -31,6 +31,7 @@ Shader "Hidden/Universal Render Pipeline/ObjectMotionVectorFallback" HLSLPROGRAM #define APPLICATION_SPACE_WARP_MOTION 1 + #define APPLICATION_SPACE_WARP_MOTION_TRANSPARENT 0 #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" ENDHLSL } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl index 0c2c6241a9a..768ac42254d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl @@ -51,7 +51,7 @@ half4 DepthNormalsFragment(VaryingsDepthNormalsParticle input) : SV_TARGET UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input); // Inputs... - #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) + #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) || defined(_WRITE_SMOOTHNESS) float2 uv = input.texcoord; #if defined(_FLIPBOOKBLENDING_ON) @@ -84,14 +84,23 @@ half4 DepthNormalsFragment(VaryingsDepthNormalsParticle input) : SV_TARGET float3 normalWS = input.normalWS; #endif + half outputAlpha = 0; + #if defined(_WRITE_SMOOTHNESS) + #if defined(_METALLICSPECGLOSSMAP) + outputAlpha = BlendTexture(TEXTURE2D_ARGS(_MetallicGlossMap, sampler_MetallicGlossMap), uv, blendUv).a * _Smoothness; + #else + outputAlpha = _Smoothness; + #endif + #endif + // Output... #if defined(_GBUFFER_NORMALS_OCT) float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1] half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS); // values between [ 0, 1] - return half4(packedNormalWS, 0.0); + return half4(packedNormalWS, outputAlpha); #else - return half4(NormalizeNormalPerPixel(normalWS), 0.0); + return half4(NormalizeNormalPerPixel(normalWS), outputAlpha); #endif } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl index 92e9224a838..99d75a3f074 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl @@ -129,7 +129,7 @@ struct VaryingsDepthNormalsParticle half4 color : COLOR; #endif - #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) + #if defined(_ALPHATEST_ON) || defined(_NORMALMAP) || defined(_WRITE_SMOOTHNESS) float2 texcoord : TEXCOORD0; #if defined(_FLIPBOOKBLENDING_ON) diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader index e5d17589efd..2fd8fa7a4f7 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLit.shader @@ -140,6 +140,7 @@ Shader "Universal Render Pipeline/Particles/Lit" #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _LIGHT_COOKIES @@ -223,6 +224,7 @@ Shader "Universal Render Pipeline/Particles/Lit" //#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED @@ -313,6 +315,7 @@ Shader "Universal Render Pipeline/Particles/Lit" #pragma shader_feature_local _ _FLIPBOOKBLENDING_ON #pragma shader_feature_local _ _ALPHATEST_ON #pragma shader_feature_local_fragment _ _COLOROVERLAY_ON _COLORCOLOR_ON _COLORADDSUBDIFF_ON + #pragma shader_feature_local_fragment _METALLICSPECGLOSSMAP // ------------------------------------- // Unity defined keywords @@ -324,6 +327,11 @@ Shader "Universal Render Pipeline/Particles/Lit" // Includes #include_with_pragmas "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesDepthNormalsPass.hlsl" + + // ------------------------------------- + // Universal Pipeline keywords + #pragma multi_compile _ _WRITE_SMOOTHNESS + #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT ENDHLSL } // ------------------------------------------------------------------ diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl index 7245d5f826a..55e73a79198 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitForwardPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_PARTICLES_FORWARD_LIT_PASS_INCLUDED #define UNIVERSAL_PARTICLES_FORWARD_LIT_PASS_INCLUDED +#include "ParticlesLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" @@ -135,7 +136,7 @@ half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target half4 color = UniversalFragmentPBR(inputData, surfaceData); color.rgb = MixFog(color.rgb, inputData.fogCoord); - color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent(_Surface)); + color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); return color; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl index 30d54e1a1c3..60f4fd34e82 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesLitInput.hlsl @@ -3,6 +3,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -19,7 +20,6 @@ half _Smoothness; half _BumpScale; half _DistortionStrengthScaled; half _DistortionBlend; -half _Surface; CBUFFER_END #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl index 6de33666093..e3bc6da587e 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitForwardPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_PARTICLES_FORWARD_SIMPLE_LIT_PASS_INCLUDED #define UNIVERSAL_PARTICLES_FORWARD_SIMPLE_LIT_PASS_INCLUDED +#include "ParticlesSimpleLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" @@ -145,7 +146,7 @@ half4 ParticlesLitFragment(VaryingsParticle input) : SV_Target half4 color = UniversalFragmentBlinnPhong(inputData, diffuse, specularGloss, specularGloss.a, emission, alpha, normalTS); color.rgb = MixFog(color.rgb, inputData.fogCoord); - color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent(_Surface)); + color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); return color; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl index c1486ecb939..7316b695dd7 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLitInput.hlsl @@ -3,6 +3,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -18,7 +19,6 @@ CBUFFER_START(UnityPerMaterial) half _Smoothness; half _DistortionStrengthScaled; half _DistortionBlend; - half _Surface; CBUFFER_END #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl index ed99e7d5006..d04ca7534b5 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitForwardPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_PARTICLES_UNLIT_FORWARD_PASS_INCLUDED #define UNIVERSAL_PARTICLES_UNLIT_FORWARD_PASS_INCLUDED +#include "ParticlesUnlitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" @@ -158,7 +159,7 @@ half4 fragParticleUnlit(VaryingsParticle input) : SV_Target #endif finalColor.rgb = MixFog(finalColor.rgb, inputData.fogCoord); - finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent(_Surface)); + finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent()); return finalColor; } diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl index b1766f2d10d..b98cfe0701f 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesUnlitInput.hlsl @@ -3,6 +3,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesInput.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" // NOTE: Do not ifdef the properties here as SRP batcher can not handle different layouts. CBUFFER_START(UnityPerMaterial) @@ -16,7 +17,6 @@ CBUFFER_START(UnityPerMaterial) half _Cutoff; half _DistortionStrengthScaled; half _DistortionBlend; - half _Surface; CBUFFER_END #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Particles.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader index 449ee1e027e..0a76394a268 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLit.shader @@ -470,8 +470,10 @@ Shader "Universal Render Pipeline/Simple Lit" HLSLPROGRAM #pragma shader_feature_local _ALPHATEST_ON #pragma multi_compile _ LOD_FADE_CROSSFADE + #pragma multi_compile _ APPLICATION_SPACE_WARP_MOTION_TRANSPARENT #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY #define APPLICATION_SPACE_WARP_MOTION 1 + #include "Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" ENDHLSL diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl index 7a5f4dbc516..bbfb99e5bee 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitForwardPass.hlsl @@ -1,6 +1,7 @@ #ifndef UNIVERSAL_SIMPLE_LIT_PASS_INCLUDED #define UNIVERSAL_SIMPLE_LIT_PASS_INCLUDED +#include "SimpleLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #if defined(LOD_FADE_CROSSFADE) #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/LODCrossFade.hlsl" @@ -115,7 +116,7 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); @@ -219,7 +220,7 @@ void LitPassFragmentSimple( half4 color = UniversalFragmentBlinnPhong(inputData, surfaceData); color.rgb = MixFog(color.rgb, inputData.fogCoord); - color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent(_Surface)); + color.a = OutputAlpha(color.a, IsSurfaceTypeTransparent()); outColor = color; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl index f689b5dfc0b..bee516caf19 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitGBufferPass.hlsl @@ -111,7 +111,7 @@ void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData void InitializeBakedGIData(Varyings input, inout InputData inputData) { #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, input.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl index 56b869627fa..bd2d29658b1 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/SimpleLitInput.hlsl @@ -4,6 +4,7 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; @@ -12,7 +13,6 @@ CBUFFER_START(UnityPerMaterial) half4 _SpecColor; half4 _EmissionColor; half _Cutoff; - half _Surface; UNITY_TEXTURE_STREAMING_DEBUG_VARS; CBUFFER_END @@ -22,14 +22,12 @@ UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(float4, _SpecColor) UNITY_DOTS_INSTANCED_PROP(float4, _EmissionColor) UNITY_DOTS_INSTANCED_PROP(float , _Cutoff) - UNITY_DOTS_INSTANCED_PROP(float , _Surface) UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata) static float4 unity_DOTS_Sampled_BaseColor; static float4 unity_DOTS_Sampled_SpecColor; static float4 unity_DOTS_Sampled_EmissionColor; static float unity_DOTS_Sampled_Cutoff; -static float unity_DOTS_Sampled_Surface; void SetupDOTSSimpleLitMaterialPropertyCaches() { @@ -37,7 +35,6 @@ void SetupDOTSSimpleLitMaterialPropertyCaches() unity_DOTS_Sampled_SpecColor = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4 , _SpecColor); unity_DOTS_Sampled_EmissionColor = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4 , _EmissionColor); unity_DOTS_Sampled_Cutoff = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Cutoff); - unity_DOTS_Sampled_Surface = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Surface); } #undef UNITY_SETUP_DOTS_MATERIAL_PROPERTY_CACHES @@ -47,7 +44,6 @@ void SetupDOTSSimpleLitMaterialPropertyCaches() #define _SpecColor unity_DOTS_Sampled_SpecColor #define _EmissionColor unity_DOTS_Sampled_EmissionColor #define _Cutoff unity_DOTS_Sampled_Cutoff -#define _Surface unity_DOTS_Sampled_Surface #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl index 06e7fddb117..808623bdc5d 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainDetailLitPasses.hlsl @@ -56,7 +56,7 @@ void InitializeInputData(Varyings input, out InputData inputData) inputData.positionWS = input.PositionWS; #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy, input.NormalWS.xyz); #elif !defined(LIGHTMAP_ON) && (defined(PROBE_VOLUMES_L1) || defined(PROBE_VOLUMES_L2)) inputData.bakedGI = SAMPLE_GI(input.vertexSH, GetAbsolutePositionWS(inputData.positionWS), diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader index b914b8ccc35..63ef81f088b 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLit.shader @@ -79,6 +79,7 @@ Shader "Universal Render Pipeline/Terrain/Lit" #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _SCREEN_SPACE_IRRADIANCE @@ -167,6 +168,7 @@ Shader "Universal Render Pipeline/Terrain/Lit" //#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS //#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _DBUFFER_MRT1 _DBUFFER_MRT2 _DBUFFER_MRT3 #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED @@ -242,6 +244,8 @@ Shader "Universal Render Pipeline/Terrain/Lit" #pragma fragment DepthNormalOnlyFragment #pragma shader_feature_local _NORMALMAP + #pragma multi_compile _ _WRITE_SMOOTHNESS + #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/RenderingLayers.hlsl" #pragma multi_compile_instancing diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader index 80232b438d8..ed84d866e27 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitAdd.shader @@ -73,6 +73,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Add Pass)" #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _LIGHT_COOKIES diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader index 1cefc8c4e6d..cb0001a9afc 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitBase.shader @@ -51,6 +51,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS + #pragma multi_compile_fragment _ _SCREEN_SPACE_REFLECTION #pragma multi_compile_fragment _ _SHADOWS_SOFT _SHADOWS_SOFT_LOW _SHADOWS_SOFT_MEDIUM _SHADOWS_SOFT_HIGH #pragma multi_compile_fragment _ _SCREEN_SPACE_OCCLUSION #pragma multi_compile_fragment _ _LIGHT_COOKIES @@ -205,6 +206,7 @@ Shader "Hidden/Universal Render Pipeline/Terrain/Lit (Base Pass)" #pragma multi_compile_instancing #pragma instancing_options assumeuniformscaling nomatrices nolightprobe nolightmap #pragma shader_feature_local _NORMALMAP + #pragma multi_compile _ _WRITE_SMOOTHNESS #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl" diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl index aa297c36f63..653a7be2fa3 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitDepthNormalsPass.hlsl @@ -97,9 +97,31 @@ void DepthNormalOnlyFragment( half3 normalWS = IN.normal; #endif - normalWS = NormalizeNormalPerPixel(normalWS); + #if defined(_GBUFFER_NORMALS_OCT) + normalWS = normalize(normalWS); + float2 octNormalWS = PackNormalOctQuadEncode(normalWS); // values between [-1, +1], must use fp32 on some platforms + float2 remappedOctNormalWS = saturate(octNormalWS * 0.5 + 0.5); // values between [ 0, 1] + half3 packedNormalWS = PackFloat2To888(remappedOctNormalWS); // values between [ 0, 1] + outNormalWS = half4(packedNormalWS, 0.0); + #else + outNormalWS = half4(NormalizeNormalPerPixel(normalWS), 0.0); + #endif + + #if defined(_WRITE_SMOOTHNESS) + half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3); + half4 masks[4]; + ComputeMasks(masks, hasMask, IN.uvSplat01, IN.uvSplat23); - outNormalWS = half4(normalWS, 0.0); + half weight; + half4 mixedDiffuse; + half4 defaultSmoothness; + SplatmapMix(IN.uvMainAndLM, IN.uvSplat01, IN.uvSplat23, splatControl, weight, mixedDiffuse, defaultSmoothness, normalTS); + half4 maskSmoothness = half4(masks[0].a, masks[1].a, masks[2].a, masks[3].a); + defaultSmoothness = lerp(defaultSmoothness, maskSmoothness, hasMask); + half smoothness = dot(splatControl, defaultSmoothness); + + outNormalWS.a = smoothness; + #endif #ifdef _WRITE_RENDERING_LAYERS outRenderingLayers = EncodeMeshRenderingLayer(); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl index 259b26a3876..c02c6a44bed 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitInput.hlsl @@ -74,7 +74,7 @@ TEXTURE2D(_MetallicTex); SAMPLER(sampler_MetallicTex); #endif #ifdef UNITY_INSTANCING_ENABLED -TEXTURE2D(_TerrainHeightmapTexture); +TYPED_TEXTURE2D(float4, _TerrainHeightmapTexture); TEXTURE2D(_TerrainNormalmapTexture); SAMPLER(sampler_TerrainNormalmapTexture); #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl index 5f0bd4a1cb4..662bbe2cc93 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/TerrainLitPasses.hlsl @@ -124,7 +124,7 @@ void InitializeBakedGIData(Varyings IN, inout InputData inputData) #endif #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(IN.uvMainAndLM.zw, IN.dynamicLightmapUV, SH, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(IN.uvMainAndLM.zw); @@ -370,7 +370,7 @@ Varyings SplatmapVert(Attributes v) return o; } -void ComputeMasks(out half4 masks[4], half4 hasMask, Varyings IN) +void ComputeMasks(out half4 masks[4], half4 hasMask, float4 uvSplat01, float4 uvSplat23) { masks[0] = 0.5h; masks[1] = 0.5h; @@ -378,10 +378,10 @@ void ComputeMasks(out half4 masks[4], half4 hasMask, Varyings IN) masks[3] = 0.5h; #ifdef _MASKMAP - masks[0] = lerp(masks[0], SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, IN.uvSplat01.xy), hasMask.x); - masks[1] = lerp(masks[1], SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, IN.uvSplat01.zw), hasMask.y); - masks[2] = lerp(masks[2], SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, IN.uvSplat23.xy), hasMask.z); - masks[3] = lerp(masks[3], SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, IN.uvSplat23.zw), hasMask.w); + masks[0] = lerp(masks[0], SAMPLE_TEXTURE2D(_Mask0, sampler_Mask0, uvSplat01.xy), hasMask.x); + masks[1] = lerp(masks[1], SAMPLE_TEXTURE2D(_Mask1, sampler_Mask0, uvSplat01.zw), hasMask.y); + masks[2] = lerp(masks[2], SAMPLE_TEXTURE2D(_Mask2, sampler_Mask0, uvSplat23.xy), hasMask.z); + masks[3] = lerp(masks[3], SAMPLE_TEXTURE2D(_Mask3, sampler_Mask0, uvSplat23.zw), hasMask.w); #endif masks[0] *= _MaskMapRemapScale0.rgba; @@ -423,7 +423,7 @@ void SplatmapFragment( half4 hasMask = half4(_LayerHasMask0, _LayerHasMask1, _LayerHasMask2, _LayerHasMask3); half4 masks[4]; - ComputeMasks(masks, hasMask, IN); + ComputeMasks(masks, hasMask, IN.uvSplat01, IN.uvSplat23); float2 splatUV = (IN.uvMainAndLM.xy * (_Control_TexelSize.zw - 1.0f) + 0.5f) * _Control_TexelSize.xy; half4 splatControl = SAMPLE_TEXTURE2D(_Control, sampler_Control, splatUV); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl index faf772d6527..1256d7cb2b1 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Terrain/WavingGrassPasses.hlsl @@ -77,7 +77,7 @@ void InitializeInputData(GrassVertexOutput input, out InputData inputData) inputData.vertexLighting = input.fogFactorAndVertexLight.yzw; #if defined(_SCREEN_SPACE_IRRADIANCE) - inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy); + inputData.bakedGI = SAMPLE_GI(_ScreenSpaceIrradiance, inputData.positionCS.xy, inputData.normalWS); #elif defined(DYNAMICLIGHTMAP_ON) inputData.bakedGI = SAMPLE_GI(input.lightmapUV, NOT_USED, input.vertexSH, inputData.normalWS); inputData.shadowMask = SAMPLE_SHADOWMASK(input.lightmapUV); diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader index 22bc54765fc..387802f5754 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Unlit.shader @@ -292,7 +292,9 @@ Shader "Universal Render Pipeline/Unlit" #pragma shader_feature_local _ALPHATEST_ON #pragma multi_compile _ LOD_FADE_CROSSFADE #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY + #pragma multi_compile _ APPLICATION_SPACE_WARP_MOTION_TRANSPARENT #define APPLICATION_SPACE_WARP_MOTION 1 + #include "Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl" #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" ENDHLSL diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl index fa449987687..6101c6c5626 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitForwardPass.hlsl @@ -2,6 +2,7 @@ #ifndef URP_UNLIT_FORWARD_PASS_INCLUDED #define URP_UNLIT_FORWARD_PASS_INCLUDED +#include "UnlitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Unlit.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" #if defined(LOD_FADE_CROSSFADE) @@ -161,7 +162,7 @@ void UnlitPassFragment( fogFactor = input.fogCoord; #endif // #if defined(_FOG_FRAGMENT) finalColor.rgb = MixFog(finalColor.rgb, fogFactor); - finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent(_Surface)); + finalColor.a = OutputAlpha(finalColor.a, IsSurfaceTypeTransparent()); outColor = finalColor; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl index 04939d7b162..c5d67b53877 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/UnlitInput.hlsl @@ -3,13 +3,13 @@ #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/SurfaceInput.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DebugMipmapStreamingMacros.hlsl" +#include "Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl" CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; float4 _BaseMap_TexelSize; half4 _BaseColor; half _Cutoff; - half _Surface; UNITY_TEXTURE_STREAMING_DEBUG_VARS; CBUFFER_END @@ -17,18 +17,15 @@ CBUFFER_END UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(float4, _BaseColor) UNITY_DOTS_INSTANCED_PROP(float , _Cutoff) - UNITY_DOTS_INSTANCED_PROP(float , _Surface) UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata) static float4 unity_DOTS_Sampled_BaseColor; static float unity_DOTS_Sampled_Cutoff; -static float unity_DOTS_Sampled_Surface; void SetupDOTSUnlitMaterialPropertyCaches() { unity_DOTS_Sampled_BaseColor = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float4, _BaseColor); unity_DOTS_Sampled_Cutoff = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Cutoff); - unity_DOTS_Sampled_Surface = UNITY_ACCESS_DOTS_INSTANCED_PROP_WITH_DEFAULT(float , _Surface); } #undef UNITY_SETUP_DOTS_MATERIAL_PROPERTY_CACHES @@ -36,7 +33,6 @@ void SetupDOTSUnlitMaterialPropertyCaches() #define _BaseColor unity_DOTS_Sampled_BaseColor #define _Cutoff unity_DOTS_Sampled_Cutoff -#define _Surface unity_DOTS_Sampled_Surface #endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ComputeScreenSpaceReflection.shader b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ComputeScreenSpaceReflection.shader new file mode 100644 index 00000000000..3d42fa3ec3f --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ComputeScreenSpaceReflection.shader @@ -0,0 +1,137 @@ +Shader "Hidden/Universal Render Pipeline/ComputeScreenSpaceReflection" +{ + HLSLINCLUDE + #pragma editor_sync_compilation + #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" + #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl" + ENDHLSL + + SubShader + { + Tags + { + "RenderType" = "Opaque" + "RenderPipeline" = "UniversalPipeline" + } + Cull Off + ZWrite Off + ZTest Always + + // ------------------------------------------------------------------ + // Screen Space Reflection + // ------------------------------------------------------------------ + // Main SSR pass + Pass + { + Name "SSR_Main" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment ComputeSSR + #pragma multi_compile_local_fragment _ _HIZ_TRACE + #pragma multi_compile_local_fragment _ _REFINE_DEPTH + #pragma multi_compile_local_fragment _ _USE_MOTION_VECTORS + #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + // Pass to blit after opaque with alpha blending + Pass + { + Name "SSR_AfterOpaque" + + ZTest Off + Blend SrcAlpha OneMinusSrcAlpha + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment CompositeSSRAfterOpaque + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + // ------------------------------------------------------------------ + // Bilateral Blur + // ------------------------------------------------------------------ + Pass + { + Name "SSR_Bilateral_HorizontalBlur" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment HorizontalBilateralBlur + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + Pass + { + Name "SSR_Bilateral_VerticalBlur" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment VerticalBilateralBlur + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + Pass + { + Name "SSR_Bilateral_FinalBlur" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment FinalBilateralBlur + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + // ------------------------------------------------------------------ + // Gaussian Blur + // ------------------------------------------------------------------ + Pass + { + Name "SSR_Gaussian_HorizontalBlur" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment HorizontalGaussianBlur + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + Pass + { + Name "SSR_Gaussian_VerticalBlur" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment VerticalGaussianBlur + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + + // ------------------------------------------------------------------ + // Kawase Blur + // ------------------------------------------------------------------ + Pass + { + Name "SSR_KawaseBlur" + + HLSLPROGRAM + #pragma vertex Vert + #pragma fragment KawaseBlur + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ComputeScreenSpaceReflection.hlsl" + ENDHLSL + } + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ComputeScreenSpaceReflection.shader.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ComputeScreenSpaceReflection.shader.meta new file mode 100644 index 00000000000..c0427de388c --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/ComputeScreenSpaceReflection.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 7b3e6785f5f6b634794df3a85a2a35da +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/CopyDepthPass.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/CopyDepthPass.hlsl index 731ba1e892b..6698a7f5712 100644 --- a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/CopyDepthPass.hlsl +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/CopyDepthPass.hlsl @@ -44,7 +44,7 @@ float SampleDepth(float2 pixelCoords) { int2 coord = int2(pixelCoords); #if MSAA_SAMPLES == 1 - return LOAD(coord); + return LOAD(coord).r; #else float outDepth = DEPTH_DEFAULT_VALUE; diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl new file mode 100644 index 00000000000..beee86c14f2 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl @@ -0,0 +1,47 @@ +#ifndef UNIVERSAL_SURFACE_TYPE_TRANSPARENT_INCLUDED +#define UNIVERSAL_SURFACE_TYPE_TRANSPARENT_INCLUDED +// Utility functionality for Universal RP materials that has the _SURFACE_TYPE_TRANSPARENT shader feature. + +// The _Surface property has been removed, but we add this is a fallback. +#if defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) || defined(_SURFACE_TYPE_TRANSPARENT) +#if defined(_Surface) +#undef _Surface +#endif +// This property is deprecated. Use parameterless IsSurfaceTypeTransparent() instead. +#define _Surface _SURFACE_TYPE_TRANSPARENT +#elif defined(_Surface) // Some shaders hardcode the _Surface property +// Use IsSurfaceTypeTransparent() instead of checking this keyword directly. +#define _SURFACE_TYPE_TRANSPARENT (_Surface > 0) +#define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 +#else +// Use IsSurfaceTypeTransparent() instead of checking this keyword directly. +#define _SURFACE_TYPE_TRANSPARENT 0 +#define _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY 1 +// This property is deprecated. Use parameterless IsSurfaceTypeTransparent() instead. +static const half _Surface = 0; +#endif + +// Returns 'True' if the materials Surface Type is set to 'Transparent'. +inline bool IsSurfaceTypeTransparent() +{ + #if defined(_SURFACE_TYPE_TRANSPARENT_KEYWORD_DECLARED) || defined(_SURFACE_TYPE_TRANSPARENT) + return _SURFACE_TYPE_TRANSPARENT; + #else + return false; + #endif +} + +// Returns 'True' if the materials Surface Type is set to 'Opaque'. +inline bool IsSurfaceTypeOpaque() +{ + return !IsSurfaceTypeTransparent(); +} + +// Prevents leaking _SURFACE_TYPE_TRANSPARENT fallback definition. +// This makes sure #if defined(_SURFACE_TYPE_TRANSPARENT) doesn't suddenly return true for shaders that include this file. +#if defined(_SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY) +#undef _SURFACE_TYPE_TRANSPARENT_DEFINED_LOCALLY +#undef _SURFACE_TYPE_TRANSPARENT +#endif + +#endif diff --git a/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl.meta b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl.meta new file mode 100644 index 00000000000..0c65f0d30c0 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Shaders/Utils/SurfaceType.hlsl.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3d17dfbc1c864f5b993c279862bf9a0f +timeCreated: 1771332447 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs index 9301d8d5300..8f6df91e0f2 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderBuildPreprocessorTests.cs @@ -29,6 +29,7 @@ private class TestHelper internal bool containsSurfaceCache; #endif internal bool everyRendererHasSSAO; + internal bool everyRendererHasSSR; internal ShaderFeatures defaultURPAssetFeatures { @@ -108,7 +109,7 @@ internal ShaderFeatures GetSupportedShaderFeaturesFromAsset() #if SURFACE_CACHE return ShaderBuildPreprocessor.GetSupportedShaderFeaturesFromAsset(ref urpAsset, ref rendererShaderFeatures, ref ssaoRendererFeatures, stripUnusedVariants, out containsForwardRenderer, out containsSurfaceCache, out everyRendererHasSSAO); #else - return ShaderBuildPreprocessor.GetSupportedShaderFeaturesFromAsset(ref urpAsset, ref rendererShaderFeatures, ref ssaoRendererFeatures, stripUnusedVariants, out containsForwardRenderer, out everyRendererHasSSAO); + return ShaderBuildPreprocessor.GetSupportedShaderFeaturesFromAsset(ref urpAsset, ref rendererShaderFeatures, ref ssaoRendererFeatures, stripUnusedVariants, out containsForwardRenderer, out everyRendererHasSSAO, out everyRendererHasSSR); #endif } @@ -940,6 +941,32 @@ public void TestGetSupportedShaderFeaturesFromRendererFeatures_SurfaceCacheGI() } #endif +#if URP_SCREEN_SPACE_REFLECTION + [Test] + public void TestGetSupportedShaderFeaturesFromRendererFeatures_ScreenSpaceReflection() + { + ScreenSpaceReflectionRendererFeature ssrFeature = ScriptableObject.CreateInstance(); + m_TestHelper.rendererFeatures.Add(ssrFeature); + + // Enabled feature + m_TestHelper.rendererFeatures[0].SetActive(true); + + RendererRequirements rendererRequirements = m_TestHelper.defaultRendererRequirements; + ShaderFeatures actual = m_TestHelper.GetSupportedShaderFeaturesFromRendererFeatures(rendererRequirements); + ShaderFeatures expected = ShaderFeatures.ScreenSpaceReflection; + m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); + + // Disabled feature + m_TestHelper.rendererFeatures[0].SetActive(false); + rendererRequirements = m_TestHelper.defaultRendererRequirements; + actual = m_TestHelper.GetSupportedShaderFeaturesFromRendererFeatures(rendererRequirements); + expected = ShaderFeatures.None; + m_TestHelper.AssertShaderFeaturesAndReset(expected, actual); + + Object.DestroyImmediate(ssrFeature); + } +#endif + [Test] public void TestGetSupportedShaderFeaturesFromRendererFeatures_Decals() { diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderPrefilteringTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderPrefilteringTests.cs index 9aa6f172a32..be95d9c0959 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderPrefilteringTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderPrefilteringTests.cs @@ -15,6 +15,7 @@ class TestHelper { internal bool isAssetUsingforward = true; internal bool everyRendererHasSSAO = false; + internal bool everyRendererHasSSR = false; internal bool stripXRKeywords = true; internal bool stripHDRKeywords = true; internal bool stripDebugDisplay = true; @@ -34,9 +35,9 @@ public TestHelper() internal ShaderPrefilteringData CreatePrefilteringSettings(ShaderFeatures shaderFeatures) { #if SURFACE_CACHE - return ShaderBuildPreprocessor.CreatePrefilteringSettings(ref shaderFeatures, isAssetUsingforward, everyRendererHasSSAO, stripXRKeywords, stripHDRKeywords, stripDebugDisplay, stripScreenCoordOverride, stripBicubicLightmapSampling, stripReflectionProbeRotation, stripScreenSpaceIrradiance, stripUnusedVariants, ref ssaoRendererFeatures); + return ShaderBuildPreprocessor.CreatePrefilteringSettings(ref shaderFeatures, isAssetUsingforward, everyRendererHasSSAO, everyRendererHasSSR, stripXRKeywords, stripHDRKeywords, stripDebugDisplay, stripScreenCoordOverride, stripBicubicLightmapSampling, stripReflectionProbeRotation, stripScreenSpaceIrradiance, stripUnusedVariants, ref ssaoRendererFeatures); #else - return ShaderBuildPreprocessor.CreatePrefilteringSettings(ref shaderFeatures, isAssetUsingforward, everyRendererHasSSAO, stripXRKeywords, stripHDRKeywords, stripDebugDisplay, stripScreenCoordOverride, stripBicubicLightmapSampling, stripReflectionProbeRotation, stripUnusedVariants, ref ssaoRendererFeatures); + return ShaderBuildPreprocessor.CreatePrefilteringSettings(ref shaderFeatures, isAssetUsingforward, everyRendererHasSSAO, everyRendererHasSSR, stripXRKeywords, stripHDRKeywords, stripDebugDisplay, stripScreenCoordOverride, stripBicubicLightmapSampling, stripReflectionProbeRotation, stripUnusedVariants, ref ssaoRendererFeatures); #endif } @@ -49,6 +50,7 @@ internal void AssertPrefilteringData(ShaderPrefilteringData expected, ShaderPref Assert.AreEqual(expected.additionalLightsPrefilteringMode, actual.additionalLightsPrefilteringMode, "additionalLightsPrefilteringMode mismatch"); Assert.AreEqual(expected.additionalLightsShadowsPrefilteringMode, actual.additionalLightsShadowsPrefilteringMode, "additionalLightsShadowsPrefilteringMode mismatch"); Assert.AreEqual(expected.screenSpaceOcclusionPrefilteringMode, actual.screenSpaceOcclusionPrefilteringMode, "screenSpaceOcclusionPrefilteringMode mismatch"); + Assert.AreEqual(expected.screenSpaceReflectionPrefilteringMode, actual.screenSpaceReflectionPrefilteringMode, "screenSpaceReflectionPrefilteringMode mismatch"); Assert.AreEqual(expected.stripXRKeywords, actual.stripXRKeywords, "stripXRKeywords mismatch"); Assert.AreEqual(expected.stripHDRKeywords, actual.stripHDRKeywords, "stripHDRKeywords mismatch"); @@ -70,6 +72,8 @@ internal void AssertPrefilteringData(ShaderPrefilteringData expected, ShaderPref Assert.AreEqual(expected.stripSSAOSampleCountMedium, actual.stripSSAOSampleCountMedium, "stripNativeRenderPass mismatch"); Assert.AreEqual(expected.stripSSAOSampleCountHigh, actual.stripSSAOSampleCountHigh, "stripNativeRenderPass mismatch"); + Assert.AreEqual(expected.stripWriteSmoothness, actual.stripWriteSmoothness, "stripWriteSmoothness mismatch"); + Assert.AreEqual(expected, actual, "Some mismatch between the Prefiltering Data that is not covered in the previous tests."); } } @@ -490,5 +494,48 @@ public void TestCreatePrefilteringSettings_ScreenSpaceOcclusion() actual = helper.CreatePrefilteringSettings(ShaderFeatures.None); helper.AssertPrefilteringData(expected, actual); } + + [Test] + public void TestCreatePrefilteringSettings_ScreenSpaceReflection() + { + ShaderPrefilteringData actual; + ShaderPrefilteringData expected; + TestHelper helper = new(); + + // SSR disabled + expected = helper.defaultPrefilteringData; + expected.screenSpaceReflectionPrefilteringMode = PrefilteringMode.Remove; + expected.stripWriteSmoothness = true; + actual = helper.CreatePrefilteringSettings(ShaderFeatures.None); + helper.AssertPrefilteringData(expected, actual); + +#if URP_SCREEN_SPACE_REFLECTION + // SSR enabled + expected = helper.defaultPrefilteringData; + expected.screenSpaceReflectionPrefilteringMode = PrefilteringMode.Select; + expected.stripWriteSmoothness = false; + actual = helper.CreatePrefilteringSettings(ShaderFeatures.ScreenSpaceReflection); + helper.AssertPrefilteringData(expected, actual); + + // Every Renderer has SSR with & without strip unused variants + helper.everyRendererHasSSR = true; + helper.stripUnusedVariants = true; + expected = helper.defaultPrefilteringData; + expected.screenSpaceReflectionPrefilteringMode = PrefilteringMode.SelectOnly; + expected.stripWriteSmoothness = false; + actual = helper.CreatePrefilteringSettings(ShaderFeatures.ScreenSpaceReflection); + helper.AssertPrefilteringData(expected, actual); + + helper.stripUnusedVariants = false; + expected = helper.defaultPrefilteringData; + expected.screenSpaceReflectionPrefilteringMode = PrefilteringMode.Select; + expected.stripWriteSmoothness = false; + actual = helper.CreatePrefilteringSettings(ShaderFeatures.ScreenSpaceReflection); + helper.AssertPrefilteringData(expected, actual); + + helper.stripUnusedVariants = true; + helper.everyRendererHasSSR = false; +#endif + } } } diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs index 59b37a6f749..8bd50f4db91 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/ShaderScriptableStripperTests.cs @@ -785,6 +785,7 @@ public void TestStripUnusedFeatures(string shaderName) TestStripUnusedFeatures_ReflectionProbes(shader); TestStripUnusedFeatures_AdditionalLights(shader); TestStripUnusedFeatures_ScreenSpaceOcclusion(shader); + TestStripUnusedFeatures_ScreenSpaceReflection(shader); TestStripUnusedFeatures_DecalsDbuffer(shader); TestStripUnusedFeatures_DecalsNormalBlend(shader); TestStripUnusedFeatures_DecalLayers(shader); @@ -1645,6 +1646,53 @@ public void TestStripUnusedFeatures_ScreenSpaceOcclusion(Shader shader) helper.IsFalse(helper.stripper.StripUnusedFeatures_ScreenSpaceOcclusion(ref helper.data, ref helper.featureStripTool)); } + public void TestStripUnusedFeatures_ScreenSpaceReflection(Shader shader) + { + TestHelper helper; + + // None + helper = new TestHelper(shader, ShaderFeatures.None); + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + helper.IsFalse(helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + + helper = new TestHelper(shader, ShaderFeatures.None); + TestHelper.s_EnabledKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection}; + helper.AreEqual(shader != null, helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + + helper = new TestHelper(shader, ShaderFeatures.None); + TestHelper.s_EnabledKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.WriteSmoothness}; + helper.AreEqual(shader != null, helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + + helper = new TestHelper(shader, ShaderFeatures.None); + TestHelper.s_EnabledKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + helper.AreEqual(shader != null, helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + +#if URP_SCREEN_SPACE_REFLECTION + // ScreenSpaceReflection + helper = new TestHelper(shader, ShaderFeatures.ScreenSpaceReflection); + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + helper.AreEqual(shader != null, helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + + helper = new TestHelper(shader, ShaderFeatures.ScreenSpaceReflection); + TestHelper.s_EnabledKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection}; + helper.IsFalse(helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + + helper = new TestHelper(shader, ShaderFeatures.ScreenSpaceReflection); + TestHelper.s_EnabledKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.WriteSmoothness}; + helper.IsFalse(helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); + + helper = new TestHelper(shader, ShaderFeatures.ScreenSpaceReflection); + TestHelper.s_EnabledKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + TestHelper.s_PassKeywords = new List() {ShaderKeywordStrings.ScreenSpaceReflection, ShaderKeywordStrings.WriteSmoothness}; + helper.IsFalse(helper.stripper.StripUnusedFeatures_ScreenSpaceReflection(ref helper.data, ref helper.featureStripTool)); +#endif + } + public void TestStripUnusedFeatures_DecalsDbuffer(Shader shader) { TestHelper helper; diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/Converters/MaterialUpgrader/ParticleSurfaceMaterialUpgraderTest.cs b/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/Converters/MaterialUpgrader/ParticleSurfaceMaterialUpgraderTest.cs new file mode 100644 index 00000000000..87b35b47557 --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/Converters/MaterialUpgrader/ParticleSurfaceMaterialUpgraderTest.cs @@ -0,0 +1,780 @@ +using System; +using System.Collections; +using NUnit.Framework; +using UnityEditor; +using UnityEditor.Rendering; +using UnityEditor.Rendering.Universal; +using UnityEngine; +using UnityEngine.TestTools; +[Category("Graphics Tools")] + +class ParticleSurfaceMaterialUpgraderTest : MaterialUpgraderTestBase +{ + [OneTimeSetUp] + public override void OneTimeSetUp() + { + m_Upgrader = new ParticleUpgrader("Particles/Standard Surface"); + } + + public ParticleSurfaceMaterialUpgraderTest() : base("Particles/Standard Surface", "Universal Render Pipeline/Particles/Lit") + { + } + + [Test] + [TestCaseSource(nameof(MaterialUpgradeCases))] + public void UpgradeParticleStandardUnlitMaterial(MaterialUpgradeTestCase testCase) + { + base.UpgradeMaterial(testCase); + } + + private static IEnumerable MaterialUpgradeCases() + { + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueParticleStandardSurface_WhenUpgrading_Then_TheOpaqueURPParticleLitPreserve", + setup = material => + { + //set the material to opaque + material.SetFloat("_Mode", 0.0f); // Opaque + }, + verify = material => + { + //check the material is still opaque + Assert.AreEqual(0.0f, material.GetFloat("_Surface")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_CutoutParticleStandardSurface_WhenUpgrading_Then_TheCutoutURPParticleLitGoesOpaque", + setup = material => + { + //set the material to cutout mode + material.SetFloat("_Mode", 1.0f); // Cutout + }, + verify = material => + { + //check the material is opaque + Assert.AreEqual(0.0f, material.GetFloat("_Surface")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeParticleStandardSurface_WhenUpgrading_Then_TheFadeURPParticleLitGoesTransparent", + setup = material => + { + //set the material to fade mode + material.SetFloat("_Mode", 2.0f); // Fade + }, + verify = material => + { + //check the material is transparent + Assert.AreEqual(1.0f, material.GetFloat("_Surface")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_TransparentParticleStandardSurface_WhenUpgrading_Then_TheTransparentURPParticleLitPreserve", + setup = material => + { + //set the material to transparent mode + material.SetFloat("_Mode", 3.0f); // Transparent + }, + verify = material => + { + //check the material is still transparent + Assert.AreEqual(1.0f, material.GetFloat("_Surface")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_AdditiveParticleStandardSurface_WhenUpgrading_Then_TheAdditiveURPParticleLitGoesTransparent", + setup = material => + { + //set the material to additive mode + material.SetFloat("_Mode", 4.0f); // Additive + }, + verify = material => + { + //check the material is transparent + Assert.AreEqual(1.0f, material.GetFloat("_Surface")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_SubtractiveParticleStandardSurface_WhenUpgrading_Then_TheSubtractiveURPParticleLitSurfaceIsNotEmpty", + ignore = true, + setup = material => + { + //set the material to subtractive mode + material.SetFloat("_Mode", 5.0f); // Subtractive + }, + verify = material => + { + //check material surface type is not blank + float surfaceType = material.GetFloat("_Surface"); + Assert.IsTrue(surfaceType == 0.0f || surfaceType == 1.0f, "Surface type is blank."); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_ModulateParticleStandardSurface_WhenUpgrading_Then_TheModulateURPParticleLitSurfaceGoesTransparent", + setup = material => + { + //set the material to modulate mode + material.SetFloat("_Mode", 6.0f); // Modulate + }, + verify = material => + { + //check the material is transparent + Assert.AreEqual(1.0f, material.GetFloat("_Surface")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueFlipBookFrameBlendingStandardSurface_WhenUpgrading_Then_TheOpaqueFlipBookFrameBlendingURPParticleLitPreserve", + setup = material => + { + //set the material to opaque with flipbook frame blending + material.SetFloat("_Mode", 0.0f); // Opaque + material.SetFloat("_FlipbookMode", 1.0f); // Frame Blending + }, + verify = material => + { + //check the material flipbook mode is still frame blending + Assert.AreEqual(1.0f, material.GetFloat("_FlipbookBlending")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueTwoSidedStandardSurface_WhenUpgrading_Then_TheOpaqueTwoSidedURPParticleLitPreserve", + setup = material => + { + //set the material to opaque and two sided + material.SetFloat("_Mode", 0.0f); // Opaque + material.SetFloat("_Cull", 1.0f); // Two Sided + }, + verify = material => + { + //check the material is still two sided + Assert.AreEqual(1.0f, material.GetFloat("_Cull")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueMetallicValueStandardSurface_WhenUpgrading_Then_TheOpaqueURPParticleLitPreserveMetallicValue", + setup = material => + { + //set the material to opaque with metallic value + material.SetFloat("_Mode", 0.0f); // Opaque + material.SetFloat("_Metallic", 0.7f); // Metallic Value + }, + verify = material => + { + //check the material metallic value is preserved + Assert.AreEqual(0.7f, material.GetFloat("_Metallic")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueSmoothnessValueStandardSurface_WhenUpgrading_Then_TheOpaqueURPParticleLitPreserveSmoothnessValue", + setup = material => + { + //set the material to opaque with smoothness value + material.SetFloat("_Mode", 0.0f); // Opaque + material.SetFloat("_Glossiness", 0.3f); // Smoothness Value + }, + verify = material => + { + //check the material smoothness value is preserved + Assert.AreEqual(0.3f, material.GetFloat("_Smoothness")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueEmissionCheckboxEnabledStandardSurface_WhenUpgrading_Then_TheOpaqueURPParticleLitPreserveEmissionCheckbox", + setup = material => + { + //set the material to opaque with emission enabled + material.SetFloat("_Mode", 0.0f); // Opaque + material.SetFloat("_EmissionEnabled", 1.0f); + material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive; + }, + verify = material => + { + //check the material emission checkbox is preserved + Assert.IsTrue(material.IsKeywordEnabled("_EMISSION")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_OpaqueAlbedoColorRedStandardSurface_WhenUpgrading_Then_TheOpaqueURPParticleLitPreserveAlbedoColorRed", + setup = material => + { + //set the material to opaque with albedo color red + material.SetFloat("_Mode", 0.0f); // Opaque + material.SetColor("_Color", Color.red); + }, + verify = material => + { + //check the material albedo color is preserved as red + Assert.AreEqual(Color.red, material.GetColor("_BaseColor")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_CutoutAlphaCutoffValueStandardSurface_WhenUpgrading_Then_TheCutoutAlphaCutoffValueURPParticleLitPreserve", + setup = material => + { + //set the material to cutout with alpha cutoff value + material.SetFloat("_Mode", 1.0f); // Cutout + material.SetFloat("_Cutoff", 0.2f); // Alpha Cutoff Value + }, + verify = material => + { + //check the material alpha cutoff value is preserved + Assert.AreEqual(0.2f, material.GetFloat("_Cutoff")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_CutoutStandardSurface_WhenUpgrading_Then_TheCutoutAlphaClippingCheckboxURPParticleLitEnabled", + setup = material => + { + //set the material to cutout mode + material.SetFloat("_Mode", 1.0f); // Cutout + }, + verify = material => + { + //check the material alpha Clipping checkbox is enabled + Assert.AreEqual(1f, material.GetFloat("_AlphaClip")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeFlipBookFrameBlendingStandardSurface_WhenUpgrading_Then_TheFadeFlipBookFrameBlendingURPParticleLitPreserve", + setup = material => + { + //set the material to fade with flipbook frame blending + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_FlipbookMode", 1.0f); // Frame Blending + }, + verify = material => + { + //check the material flipbook mode is still frame blending + Assert.AreEqual(1.0f, material.GetFloat("_FlipbookBlending")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeTwoSidedStandardSurface_WhenUpgrading_Then_TheFadeTwoSidedURPParticleLitPreserve", + setup = material => + { + //set the material to fade and two sided + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_Cull", 1.0f); // Two Sided + }, + verify = material => + { + //check the material is still two sided + Assert.AreEqual(1.0f, material.GetFloat("_Cull")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeSoftParticlesStandardSurface_WhenUpgrading_Then_TheFadeSoftParticlesURPParticleLitPreserve", + setup = material => + { + //set the material to fade with soft particles + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_SoftParticlesEnabled", 1.0f); // Soft Particles + }, + verify = material => + { + //check the material soft particles is preserved + Assert.AreEqual(1.0f, material.GetFloat("_SoftParticlesEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeSoftParticleNearValueStandardSurface_WhenUpgrading_Then_TheFadeSoftParticleNearValueURPParticleLitPreserve", + setup = material => + { + //set the material to fade with soft particles and set near value + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_SoftParticlesEnabled", 1.0f); // Soft Particles + material.SetFloat("_SoftParticlesNearFadeDistance", 0.1f); // Soft Particle Near + }, + verify = material => + { + //check the material soft particle near value is preserved + Assert.AreEqual(0.1f, material.GetFloat("_SoftParticlesNearFadeDistance")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeSoftParticleFarValueStandardSurface_WhenUpgrading_Then_TheFadeSoftParticleFarValueURPParticleLitPreserve", + setup = material => + { + //set the material to fade with soft particles and set far value + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_SoftParticlesEnabled", 1.0f); // Soft Particles + material.SetFloat("_SoftParticlesFarFadeDistance", 0.7f); // Soft Particle Far + }, + verify = material => + { + //check the material soft particle far value is preserved + Assert.AreEqual(0.7f, material.GetFloat("_SoftParticlesFarFadeDistance")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeCameraFadingStandardSurface_WhenUpgrading_Then_TheFadeCameraFadingURPParticleLitPreserve", + setup = material => + { + //set the material to fade with camera fading + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_CameraFadingEnabled", 1.0f); // Camera Fading + }, + verify = material => + { + //check the material camera fading is preserved + Assert.AreEqual(1.0f, material.GetFloat("_CameraFadingEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeCameraDistortionStandardSurface_WhenUpgrading_Then_TheFadeCameraDistortionURPParticleLitPreserve", + setup = material => + { + //set the material to fade with camera distortion + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + }, + verify = material => + { + //check the material camera distortion is preserved + Assert.AreEqual(1.0f, material.GetFloat("_DistortionEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeDistortionStrengthValueStandardSurface_WhenUpgrading_Then_TheFadeDistortionStrengthValueURPParticleLitPreserve", + setup = material => + { + //set the material to fade with camera distortion and set distortion strength value + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + material.SetFloat("_DistortionStrength", 2f); // Distortion Strength + }, + verify = material => + { + //check the material distortion strength value is preserved + Assert.AreEqual(2f, material.GetFloat("_DistortionStrength")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_FadeDistortionBlendValueStandardSurface_WhenUpgrading_Then_TheFadeDistortionBlendValueURPParticleLitPreserve", + setup = material => + { + //set the material to fade with camera distortion and set distortion blend value + material.SetFloat("_Mode", 2.0f); // Fade + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + material.SetFloat("_DistortionBlend", 0.1f); // Distortion Blend + }, + verify = material => + { + //check the material distortion blend value is preserved + Assert.AreEqual(0.1f, material.GetFloat("_DistortionBlend")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_TransparentFlipBookFrameBlendingStandardSurface_WhenUpgrading_Then_TheTransparentFlipBookFrameBlendingURPParticleLitPreserve", + setup = material => + { + //set the material to transparent with flipbook frame blending + material.SetFloat("_Mode", 3.0f); // Transparent + material.SetFloat("_FlipbookMode", 1.0f); // Frame Blending + }, + verify = material => + { + //check the material flipbook mode is still frame blending + Assert.AreEqual(1.0f, material.GetFloat("_FlipbookBlending")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_TransparentTwoSidedStandardSurface_WhenUpgrading_Then_TheTransparentTwoSidedURPParticleLitPreserve", + setup = material => + { + //set the material to transparent and two sided + material.SetFloat("_Mode", 3.0f); // Transparent + material.SetFloat("_Cull", 1.0f); // Two Sided + }, + verify = material => + { + //check the material is still two sided + Assert.AreEqual(1.0f, material.GetFloat("_Cull")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_TransparentCameraFadingStandardSurface_WhenUpgrading_Then_TheTransparentCameraFadingURPParticleLitPreserve", + setup = material => + { + //set the material to transparent with camera fading + material.SetFloat("_Mode", 3.0f); // Transparent + material.SetFloat("_CameraFadingEnabled", 1.0f); // Camera Fading + }, + verify = material => + { + //check the material camera fading is preserved + Assert.AreEqual(1.0f, material.GetFloat("_CameraFadingEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_TransparentCameraDistortionStandardSurface_WhenUpgrading_Then_TheTransparentCameraDistortionURPParticleLitPreserve", + setup = material => + { + //set the material to transparent with camera distortion + material.SetFloat("_Mode", 3.0f); // Transparent + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + }, + verify = material => + { + //check the material camera distortion is preserved + Assert.AreEqual(1.0f, material.GetFloat("_DistortionEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_TransparentEmissionEnabledStandardSurface_WhenUpgrading_Then_TheTransparentEmissionEnabledURPParticleLitPreserve", + setup = material => + { + //set the material to transparent with emission enabled + material.SetFloat("_Mode", 3.0f); // Transparent + material.SetFloat("_EmissionEnabled", 1.0f); + material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive; + }, + verify = material => + { + //check the material emission enabled is preserved + Assert.IsTrue(material.IsKeywordEnabled("_EMISSION")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_AdditiveFlipBookFrameBlendingStandardSurface_WhenUpgrading_Then_TheAdditiveFlipBookFrameBlendingURPParticleLitPreserve", + setup = material => + { + //set the material to additive with flipbook frame blending + material.SetFloat("_Mode", 4.0f); // Additive + material.SetFloat("_FlipbookMode", 1.0f); // Frame Blending + }, + verify = material => + { + //check the material flipbook mode is still frame blending + Assert.AreEqual(1.0f, material.GetFloat("_FlipbookBlending")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_AdditiveTwoSidedStandardSurface_WhenUpgrading_Then_TheAdditiveTwoSidedURPParticleLitPreserve", + setup = material => + { + //set the material to additive and two sided + material.SetFloat("_Mode", 4.0f); // Additive + material.SetFloat("_Cull", 1.0f); // Two Sided + }, + verify = material => + { + //check the material is still two sided + Assert.AreEqual(1.0f, material.GetFloat("_Cull")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_AdditiveSoftParticlesStandardSurface_WhenUpgrading_Then_TheAdditiveSoftParticlesURPParticleLitPreserve", + setup = material => + { + //set the material to additive with soft particles + material.SetFloat("_Mode", 4.0f); // Additive + material.SetFloat("_SoftParticlesEnabled", 1.0f); // Soft Particles + }, + verify = material => + { + //check the material soft particles is preserved + Assert.AreEqual(1.0f, material.GetFloat("_SoftParticlesEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_AdditiveCameraFadingStandardSurface_WhenUpgrading_Then_TheAdditiveCameraFadingURPParticleLitPreserve", + setup = material => + { + //set the material to additive with camera fading + material.SetFloat("_Mode", 4.0f); // Additive + material.SetFloat("_CameraFadingEnabled", 1.0f); // Camera Fading + }, + verify = material => + { + //check the material camera fading is preserved + Assert.AreEqual(1.0f, material.GetFloat("_CameraFadingEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_AdditiveDistortionEnabledStandardSurface_WhenUpgrading_Then_TheAdditiveDistortionEnabledURPParticleLitPreserve", + setup = material => + { + //set the material to additive with camera distortion + material.SetFloat("_Mode", 4.0f); // Additive + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + }, + verify = material => + { + //check the material camera distortion is preserved + Assert.AreEqual(1.0f, material.GetFloat("_DistortionEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_SubtractiveFlipBookFrameBlendingStandardSurface_WhenUpgrading_Then_TheSubtractiveFlipBookFrameBlendingURPParticleLitPreserve", + setup = material => + { + //set the material to subtractive with flipbook frame blending + material.SetFloat("_Mode", 5.0f); // Subtractive + material.SetFloat("_FlipbookMode", 1.0f); // Frame Blending + }, + verify = material => + { + //check the material flipbook mode is still frame blending + Assert.AreEqual(1.0f, material.GetFloat("_FlipbookBlending")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_SubtractiveTwoSidedStandardSurface_WhenUpgrading_Then_TheSubtractiveTwoSidedURPParticleLitPreserve", + setup = material => + { + //set the material to subtractive and two sided + material.SetFloat("_Mode", 5.0f); // Subtractive + material.SetFloat("_Cull", 1.0f); // Two Sided + }, + verify = material => + { + //check the material is still two sided + Assert.AreEqual(1.0f, material.GetFloat("_Cull")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_SubtractiveSoftParticlesStandardSurface_WhenUpgrading_Then_TheSubtractiveSoftParticlesURPParticleLitPreserve", + setup = material => + { + //set the material to subtractive with soft particles + material.SetFloat("_Mode", 5.0f); // Subtractive + material.SetFloat("_SoftParticlesEnabled", 1.0f); // Soft Particles + }, + verify = material => + { + //check the material soft particles is preserved + Assert.AreEqual(1.0f, material.GetFloat("_SoftParticlesEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_SubtractiveCameraFadingStandardSurface_WhenUpgrading_Then_TheSubtractiveCameraFadingURPParticleLitPreserve", + setup = material => + { + //set the material to subtractive with camera fading + material.SetFloat("_Mode", 5.0f); // Subtractive + material.SetFloat("_CameraFadingEnabled", 1.0f); // Camera Fading + }, + verify = material => + { + //check the material camera fading is preserved + Assert.AreEqual(1.0f, material.GetFloat("_CameraFadingEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_SubtractiveDistortionEnabledStandardSurface_WhenUpgrading_Then_TheSubtractiveDistortionEnabledURPParticleLitPreserve", + setup = material => + { + //set the material to subtractive with camera distortion + material.SetFloat("_Mode", 5.0f); // Subtractive + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + }, + verify = material => + { + //check the material camera distortion is preserved + Assert.AreEqual(1.0f, material.GetFloat("_DistortionEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_ModulateFlipBookFrameBlendingStandardSurface_WhenUpgrading_Then_TheModulateFlipBookFrameBlendingURPParticleLitPreserve", + setup = material => + { + //set the material to modulate with flipbook frame blending + material.SetFloat("_Mode", 6.0f); // Modulate + material.SetFloat("_FlipbookMode", 1.0f); // Frame Blending + }, + verify = material => + { + //check the material flipbook mode is still frame blending + Assert.AreEqual(1.0f, material.GetFloat("_FlipbookBlending")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_ModulateTwoSidedStandardSurface_WhenUpgrading_Then_TheModulateTwoSidedURPParticleLitPreserve", + setup = material => + { + //set the material to modulate and two sided + material.SetFloat("_Mode", 6.0f); // Modulate + material.SetFloat("_Cull", 1.0f); // Two Sided + }, + verify = material => + { + //check the material is still two sided + Assert.AreEqual(1.0f, material.GetFloat("_Cull")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_ModulateSoftParticlesStandardSurface_WhenUpgrading_Then_TheModulateSoftParticlesURPParticleLitPreserve", + setup = material => + { + //set the material to modulate with soft particles + material.SetFloat("_Mode", 6.0f); // Modulate + material.SetFloat("_SoftParticlesEnabled", 1.0f); // Soft Particles + }, + verify = material => + { + //check the material soft particles is preserved + Assert.AreEqual(1.0f, material.GetFloat("_SoftParticlesEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_ModulateCameraFadingStandardSurface_WhenUpgrading_Then_TheModulateCameraFadingURPParticleLitPreserve", + setup = material => + { + //set the material to modulate with camera fading + material.SetFloat("_Mode", 6.0f); // Modulate + material.SetFloat("_CameraFadingEnabled", 1.0f); // Camera Fading + }, + verify = material => + { + //check the material camera fading is preserved + Assert.AreEqual(1.0f, material.GetFloat("_CameraFadingEnabled")); + } + }; + + yield return new MaterialUpgradeTestCase + { + name = + "Given_ModulateDistortionEnabledStandardSurface_WhenUpgrading_Then_TheModulateDistortionEnabledURPParticleLitPreserve", + setup = material => + { + //set the material to modulate with camera distortion + material.SetFloat("_Mode", 6.0f); // Modulate + material.SetFloat("_DistortionEnabled", 1.0f); // Camera Distortion + }, + verify = material => + { + //check the material camera distortion is preserved + Assert.AreEqual(1.0f, material.GetFloat("_DistortionEnabled")); + } + }; + } +} diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/Converters/MaterialUpgrader/ParticleSurfaceMaterialUpgraderTest.cs.meta b/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/Converters/MaterialUpgrader/ParticleSurfaceMaterialUpgraderTest.cs.meta new file mode 100644 index 00000000000..f91feaeac3e --- /dev/null +++ b/Packages/com.unity.render-pipelines.universal/Tests/Editor/Tools/Converters/MaterialUpgrader/ParticleSurfaceMaterialUpgraderTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7a8f40bae4efe4be082ea48246a3e6a2 \ No newline at end of file diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/RenderGraphConstraintsTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/RenderGraphConstraintsTests.cs index dbffc717eb8..9060d114094 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/RenderGraphConstraintsTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/RenderGraphConstraintsTests.cs @@ -160,7 +160,7 @@ public class OnTileValidationConfiguration public bool occlusionCulling { get; set; } = false; public float renderScale { get; set; } = 1.0f; public bool postProcessingEnabled { get; set; } = false; - public bool onTileValidation { get; set; } = false; + public bool tileOnlyMode { get; set; } = false; public List rendererFeatures { get; set; } = new(); @@ -187,7 +187,7 @@ bool TryApplyToAssetAndRenderer(UniversalRenderPipelineAsset asset, UniversalRen } // Apply renderer settings - rendererData.onTileValidation = onTileValidation; + rendererData.tileOnlyMode = tileOnlyMode; if (renderingMode != RenderingMode.Forward && !s_RenderingModes.Contains(renderingMode)) return false; @@ -235,6 +235,7 @@ public void ApplyToAssetAndRenderer(UniversalRenderPipelineAsset asset, Universa .SetName("Post Processing on Universal Renderer.").Returns(null), }; + [UnityPlatform(exclude = new RuntimePlatform[] { RuntimePlatform.WebGLPlayer })] [UnityTest] [TestCaseSource(nameof(s_OnTileValidationCases))] public IEnumerator URPSettingsShouldNotCauseNonMemorylessTargets(OnTileValidationConfiguration config) @@ -244,7 +245,7 @@ public IEnumerator URPSettingsShouldNotCauseNonMemorylessTargets(OnTileValidatio config.ApplyToAssetAndRenderer(m_UniversalRenderPipelineAsset, m_UniversalRendererData); // Act - m_UniversalRendererData.onTileValidation = true; + m_UniversalRendererData.tileOnlyMode = true; yield return null; @@ -252,26 +253,9 @@ public IEnumerator URPSettingsShouldNotCauseNonMemorylessTargets(OnTileValidatio LogAssert.ignoreFailingMessages = false; } + [UnityPlatform(exclude = new RuntimePlatform[] { RuntimePlatform.WebGLPlayer})] [UnityTest] - public IEnumerator AnyScriptableRendererFeatureProduceAnException() - { - // Arrange - var config = new OnTileValidationConfiguration(); - config.rendererFeatures.Add(ScriptableObject.CreateInstance()); - config.ApplyToAssetAndRenderer(m_UniversalRenderPipelineAsset, m_UniversalRendererData); - - yield return null; - - // Act - LogAssert.Expect(LogType.Error, new Regex("Render Graph Execution error")); - LogAssert.Expect(LogType.Exception, new Regex("ArgumentException")); - - m_UniversalRendererData.onTileValidation = true; - yield return null; - } - - [UnityTest] - public IEnumerator CameraStackingProduceAnException() + public IEnumerator CameraStackingProduceWarning() { // Arrange var gameObject = new GameObject(); @@ -287,15 +271,13 @@ public IEnumerator CameraStackingProduceAnException() yield return null; // Act - LogAssert.Expect(LogType.Exception, new Regex("ArgumentException")); + LogAssert.Expect(LogType.Warning, new Regex("does not support Overlay cameras")); + LogAssert.Expect(LogType.Warning, new Regex("camera overlay no longer exists")); - m_UniversalRendererData.onTileValidation = true; + m_UniversalRendererData.tileOnlyMode = true; yield return null; - m_UniversalRendererData.onTileValidation = false; - ((UniversalRenderer)additionalCameraData.scriptableRenderer).onTileValidation = true; - - LogAssert.Expect(LogType.Exception, new Regex("ArgumentException")); + m_UniversalRendererData.tileOnlyMode = false; yield return null; diff --git a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/ShadowCaster2DTests.cs b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/ShadowCaster2DTests.cs index c43269eeb8e..da84421001e 100644 --- a/Packages/com.unity.render-pipelines.universal/Tests/Runtime/ShadowCaster2DTests.cs +++ b/Packages/com.unity.render-pipelines.universal/Tests/Runtime/ShadowCaster2DTests.cs @@ -29,7 +29,7 @@ public void AddShadowCaster2DWithSpriteSkin() // ShadowCaster2D.shadowShape2DProvider is always null on Standalone. #if UNITY_EDITOR - Assert.That(shadowCaster2D.shadowShape2DProvider, Is.TypeOf(typeof(ShadowCaster2DProvider_SpriteSkin))); + Assert.That(shadowCaster2D.shadowShape2DProvider, Is.TypeOf(typeof(ShadowShape2DProvider_SpriteSkin))); #else Assert.That(shadowCaster2D.shadowShape2DProvider, Is.Null); #endif @@ -46,7 +46,7 @@ public void AddShadowCaster2DWithSpriteSkinWhenInactive() m_Obj.SetActive(true); // ShadowCaster2D.shadowShape2DProvider is always null on Standalone. #if UNITY_EDITOR - Assert.That(shadowCaster2D.shadowShape2DProvider, Is.TypeOf(typeof(ShadowCaster2DProvider_SpriteSkin))); + Assert.That(shadowCaster2D.shadowShape2DProvider, Is.TypeOf(typeof(ShadowShape2DProvider_SpriteSkin))); #else Assert.That(shadowCaster2D.shadowShape2DProvider, Is.Null); #endif diff --git a/Packages/com.unity.shadergraph/Documentation~/Branch-On-Input-Connection-Node.md b/Packages/com.unity.shadergraph/Documentation~/Branch-On-Input-Connection-Node.md index a4091e64296..90e1c4a2d16 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Branch-On-Input-Connection-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Branch-On-Input-Connection-Node.md @@ -6,10 +6,6 @@ For more information, refer to [Set default inputs for a Sub Graph](Sub-Graph-De The node generates branching HLSL source code, but during compilation Unity optimizes the branch out of your shader. -## Compatibility - -The Branch On Input Connection [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] - You can only use a Branch on Input Connection node in a [Sub Graph](Sub-graphs.md). ## Inputs diff --git a/Packages/com.unity.shadergraph/Documentation~/Calculate-Level-Of-Detail-Texture-2D-Node.md b/Packages/com.unity.shadergraph/Documentation~/Calculate-Level-Of-Detail-Texture-2D-Node.md index 313e7481c60..b9f844708d1 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Calculate-Level-Of-Detail-Texture-2D-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Calculate-Level-Of-Detail-Texture-2D-Node.md @@ -19,9 +19,7 @@ For example, a Texture might only have 3 mips: a 64×64 mip, a 32×32 mip, and a The Calculate Level of Detail Texture 2D node is under the **Input** > **Texture** category in the Create Node menu. -## Compatibility - -The Calculate Level of Detail Texture 2D [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] +## Limitations The Calculate Level of Detail Texture 2D [!include[nodes-fragment-only](./snippets/nodes-fragment-only.md)] diff --git a/Packages/com.unity.shadergraph/Documentation~/Custom-Function-Node.md b/Packages/com.unity.shadergraph/Documentation~/Custom-Function-Node.md index 909746678c6..38580a49ede 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Custom-Function-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Custom-Function-Node.md @@ -165,6 +165,8 @@ However, be aware of the following: * The Shader Graph node and main previews can't access Unity's Render Pipeline libraries in the Editor. This generates compile errors in the Editor even though the shader works correctly in your project. To prevent this issue, you have to isolate the code with an `#ifdef SHADERGRAPH_PREVIEW` condition and also define default values for the variables in the Shader Graph preview context. * The code in libraries might change over time from one Unity version to another. You need to make sure to regularly test and update your custom functions in your projects. +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + Here is an example with URP library function calls and the above-mentioned conditional protections set up: ``` diff --git a/Packages/com.unity.shadergraph/Documentation~/Custom-Interpolators.md b/Packages/com.unity.shadergraph/Documentation~/Custom-Interpolators.md index 507a3921bfb..7712e282b53 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Custom-Interpolators.md +++ b/Packages/com.unity.shadergraph/Documentation~/Custom-Interpolators.md @@ -9,6 +9,8 @@ There are two target audiences for custom interpolators: **Note:** If you use the Built-In Render Pipeline, refer to [Input vertex data into a shader](https://docs.unity3d.com/Manual/SL-VertexProgramInputs.html) instead. +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + ## Supported data types Custom interpolators support float, vector 2, vector 3, and vector 4 types. diff --git a/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md b/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md index 4cb0a75b264..673a8da0249 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Dropdown-Node.md @@ -31,10 +31,6 @@ To add a Subgraph Dropdown node to a Subgraph: ![An image of the Graph window, that displays a Dropdown node in the Graph Editor. The Dropdown property is selected in the Blackboard and the Graph Inspector shows the available options for configuring the Dropdown property.](images/sg-subgraph-dropdown-node.png) -## Compatibility - -The Subgraph Dropdown [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] - ## Ports > [!NOTE] diff --git a/Packages/com.unity.shadergraph/Documentation~/Gather-Texture-2D-Node.md b/Packages/com.unity.shadergraph/Documentation~/Gather-Texture-2D-Node.md index 1861ccd516e..f77bf8dca0b 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Gather-Texture-2D-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Gather-Texture-2D-Node.md @@ -19,9 +19,7 @@ The pixels that the Gather Texture 2D samples are always from the top mip level The Gather Texture 2D node is under the **Input** > **Texture** category in the Create Node menu. -## Compatibility - -The Gather Texture 2D [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] +## Limitations The Gather Texture 2D [!include[nodes-fragment-only](./snippets/nodes-fragment-only.md)] diff --git a/Packages/com.unity.shadergraph/Documentation~/Graph-Settings-Tab.md b/Packages/com.unity.shadergraph/Documentation~/Graph-Settings-Tab.md index 86443d00ade..dd6e7f15457 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Graph-Settings-Tab.md +++ b/Packages/com.unity.shadergraph/Documentation~/Graph-Settings-Tab.md @@ -23,6 +23,8 @@ Shader Graph supports the following target types: * **Universal**: Shaders for the [Universal Render Pipeline (URP)](xref:um-universal-render-pipeline), available only if your project uses URP. * **HDRP**: Shaders for the [High Definition Render Pipeline (HDRP)](xref:high-definition-render-pipeline), available only if your project uses HDRP. +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + ### Target properties Each graph target added in the list of **Active Targets** has its own set of properties. diff --git a/Packages/com.unity.shadergraph/Documentation~/Graph-Target.md b/Packages/com.unity.shadergraph/Documentation~/Graph-Target.md index d843d493b6f..5fa2cf26467 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Graph-Target.md +++ b/Packages/com.unity.shadergraph/Documentation~/Graph-Target.md @@ -10,6 +10,8 @@ Typically, each Target you select generates a valid subshader from the graph. Fo Shader Graph supports three targets: the [Universal Render Pipeline](https://docs.unity3d.com/Manual/urp/urp-introduction.html), the [High Definition Render Pipeline](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@latest/index.html?subfolder=/manual/), and the [Built-In Render Pipeline](https://docs.unity3d.com/Documentation/Manual/built-in-render-pipeline.html). +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + Not all blocks are compatible with all targets. If a block in your graph becomes inactive when you choose a target, that block is not compatible with that target. The visual results of a graph are not the same in all render pipelines. This is because of the technical differences between URP, Built-In, and HDRP. diff --git a/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Array-Node.md b/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Array-Node.md index 7551dc32f7e..252e045e532 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Array-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Array-Node.md @@ -12,9 +12,7 @@ For more information about Texture 2D Arrays, see [Texture Arrays](https://docs. The Sample Texture 2D Array node is under the **Input** > **Texture** category in the Create Node menu. -## Compatibility - -The Sample Texture 3D [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] +## Limitations [!include[nodes-sample-fragment-lod](./snippets/sample-nodes/nodes-sample-fragment-lod.md)] diff --git a/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Node.md b/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Node.md index f07eee8dea4..cf1225c6931 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-2D-Node.md @@ -12,9 +12,7 @@ A Sample Texture 2D node can also sample a normal map. For more information, ref The Sample Texture 2D node is under the **Input** > **Texture** category in the Create Node menu. -## Compatibility - -The Sample Texture 2D [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] +## Limitations [!include[nodes-sample-fragment-lod](./snippets/sample-nodes/nodes-sample-fragment-lod.md)] diff --git a/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-3D-Node.md b/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-3D-Node.md index ef4fc4c031f..b54d4f2a934 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-3D-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Sample-Texture-3D-Node.md @@ -12,9 +12,7 @@ For more information about Texture 3D assets, refer to [3D textures](https://doc The Sample Texture 2D node is under the **Input** > **Texture** category in the Create Node menu. -## Compatibility - -The Sample Texture 3D [!include[nodes-compatibility-all](./snippets/nodes-compatibility-all.md)] +## Limitations [!include[nodes-sample-fragment-lod](./snippets/sample-nodes/nodes-sample-fragment-lod.md)] diff --git a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md index 22acfdf41d5..3d55aace82f 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md +++ b/Packages/com.unity.shadergraph/Documentation~/Shader-Graph-Sample-Feature-Examples.md @@ -241,6 +241,8 @@ This section illustrates two ways to branch your shader. #### Branch On Render Pipeline Shader Graph allows you to create shaders that can be used in multiple render pipelines- Built-In, URP, and HDRP. This can be done by opening the shader in Shader Graph and adding the targets for all of the pipelines you want the shader to support in the Active Targets section under Graph Settings in the Graph Inspector window. +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + When supporting multiple render pipelines, it’s occasionally necessary to do different things in the graph depending on which pipeline is being used. In order to do that, you need to branch the shader based on the active render pipeline. There isn’t an official node in Shader Graph for performing that branching operation, but it is possible to create a subgraph that contains a Custom Function node that does the branch. In this example, we use that Branch On RP to create a different outcome depending which render pipeline is active. In our simple example, we just make the cube a different color - green for URP, blue for HDRP, and yellow for the Built-In render pipeline - but you can do much more complex operations that are specific to each render pipeline using this same technique. diff --git a/Packages/com.unity.shadergraph/Documentation~/Transformation-Matrix-Node.md b/Packages/com.unity.shadergraph/Documentation~/Transformation-Matrix-Node.md index 6031cfed947..fc69c20004f 100644 --- a/Packages/com.unity.shadergraph/Documentation~/Transformation-Matrix-Node.md +++ b/Packages/com.unity.shadergraph/Documentation~/Transformation-Matrix-Node.md @@ -6,6 +6,7 @@ Defines a constant **Matrix 4x4** value for a common **Transformation Matrix** i Two output value options for this node, **Inverse Projection** and **Inverse View Projection**, are not compatible with the Built-In Render Pipeline target. When you choose either of these options and target the Built-In Render Pipeline, this node produces an entirely black result. +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] ## Ports diff --git a/Packages/com.unity.shadergraph/Documentation~/install-shader-graph.md b/Packages/com.unity.shadergraph/Documentation~/install-shader-graph.md index fabdd054ab7..6a4ff4a7ef6 100644 --- a/Packages/com.unity.shadergraph/Documentation~/install-shader-graph.md +++ b/Packages/com.unity.shadergraph/Documentation~/install-shader-graph.md @@ -11,6 +11,8 @@ Use Shader Graph with either of the Scriptable Render Pipelines (SRPs) available As of Unity version 2021.2, you can also use Shader Graph with the [Built-In Render Pipeline](https://docs.unity3d.com/Documentation/Manual/built-in-render-pipeline.html). +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + > [!NOTE] > - Shader Graph support for the Built-In Render Pipeline is for compatibility purposes only. Shader Graph doesn't receive updates for Built-In Render Pipeline support, aside from bug fixes for existing features. It's recommended to use Shader Graph with the Scriptable Render Pipelines. > - In the Built-In Render Pipeline, Shader Graph doesn't support XR. diff --git a/Packages/com.unity.shadergraph/Documentation~/snippets/birp-deprecation-message.md b/Packages/com.unity.shadergraph/Documentation~/snippets/birp-deprecation-message.md new file mode 100644 index 00000000000..43add6ecaae --- /dev/null +++ b/Packages/com.unity.shadergraph/Documentation~/snippets/birp-deprecation-message.md @@ -0,0 +1,3 @@ +> [!IMPORTANT] +> The Built-In Render Pipeline is deprecated and will be made obsolete in a future release.
It remains supported, including bug fixes and maintenance, through the full Unity 6.7 LTS lifecycle.
For more information on migration, refer to [Migrating from the Built-In Render Pipeline to URP](https://docs.unity3d.com/6000.5/Documentation/Manual/urp/upgrading-from-birp.html) and [Render pipeline feature comparison](https://docs.unity3d.com/6000.5/Documentation/Manual/render-pipelines-feature-comparison.html). + diff --git a/Packages/com.unity.shadergraph/Documentation~/surface-options.md b/Packages/com.unity.shadergraph/Documentation~/surface-options.md index 6c668cef842..19564a60656 100644 --- a/Packages/com.unity.shadergraph/Documentation~/surface-options.md +++ b/Packages/com.unity.shadergraph/Documentation~/surface-options.md @@ -4,6 +4,8 @@ Enable **Allow Material Override** to modify a specific set of properties for Universal Render Pipeline Lit and Unlit Shader Graphs and for Built-In Render Pipeline Shader Graphs in the Material Inspector. +[!include[birp-deprecation-message](snippets/birp-deprecation-message.md)] + | Property | Behavior | | :--- | :--- | | **Workflow Mode** | Refer to the URP documentation for the [Lit URP](https://docs.unity3d.com/Manual/urp/lit-shader) Shader.
**Note**: Not applicable to URP Unlit and the Built-In Render Pipeline. | diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs index 9dad1c3c532..1de21058174 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphData.cs @@ -698,7 +698,7 @@ public void ClearChanges() m_MovedContexts = false; } - public void AddNode(AbstractMaterialNode node) + public void AddNode(AbstractMaterialNode node, bool usePreviewPref = true) { if (node is AbstractMaterialNode materialNode) { @@ -708,7 +708,8 @@ public void AddNode(AbstractMaterialNode node) return; } - materialNode.previewExpanded = ShaderGraphPreferences.newNodesPreview; + if (usePreviewPref && materialNode.UsePreviewPref) + materialNode.previewExpanded = ShaderGraphPreferences.newNodesPreview; AddNodeNoValidate(materialNode); @@ -887,6 +888,17 @@ public List GetActiveBlocksForAllActiveTargets() return context.activeBlocks; } + public void RefreshBadgesAndPreviews() + { + foreach (var node in this.m_Nodes) + { + if (node.value != null) + { + node.value.Dirty(ModificationScope.Graph); + } + } + } + public void UpdateActiveBlocks(List activeBlockDescriptors) { // Set Blocks as active based on supported Block list @@ -1660,40 +1672,49 @@ public ShaderInput AddCopyOfShaderInput(ShaderInput source, int insertIndex = -1 return copy; } - public void RemoveGraphInput(ShaderInput input) + // Removes a collection of shader inputs, deferring graph validation until all inputs have been removed + public void RemoveGraphInputs(IEnumerable inputs) { - switch (input) + foreach (ShaderInput input in inputs) { - case AbstractShaderProperty property: - var propertyNodes = GetNodes().Where(x => x.property == input).ToList(); - foreach (var propertyNode in propertyNodes) - ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode); - break; - } + switch (input) + { + case AbstractShaderProperty property: + var propertyNodes = GetNodes().Where(x => x.property == input).ToList(); + foreach (var propertyNode in propertyNodes) + ReplacePropertyNodeWithConcreteNodeNoValidate(propertyNode); + break; + } - // Also remove this input from any category it existed in - foreach (var categoryData in categories) - { - if (categoryData.IsItemInCategory(input)) + // Also remove this input from any category it existed in + foreach (var categoryData in categories) { - categoryData.RemoveItemFromCategory(input); - break; + if (categoryData.IsItemInCategory(input)) + { + categoryData.RemoveItemFromCategory(input); + break; + } } - } - foreach(var node in GetNodes()) - { - if (node.UsedReferenceNames().Contains(input.referenceName)) + foreach (var node in GetNodes()) { - node.ValidateNode(); - node.Dirty(ModificationScope.Graph); + if (node.UsedReferenceNames().Contains(input.referenceName)) + { + node.ValidateNode(); + node.Dirty(ModificationScope.Graph); + } } - } - RemoveGraphInputNoValidate(input); + RemoveGraphInputNoValidate(input); + } ValidateGraph(); } + public void RemoveGraphInput(ShaderInput input) + { + RemoveGraphInputs(new ShaderInput[] { input }); + } + public void MoveCategory(CategoryData category, int newIndex) { if (newIndex > m_CategoryData.Count || newIndex < 0) @@ -1878,8 +1899,7 @@ public void RemoveCategory(string categoryGUID) m_RemovedCategories.Add(existingCategory); // Whenever a category is removed, also remove any inputs within that category - foreach (var shaderInput in existingCategory.Children) - RemoveGraphInput(shaderInput); + RemoveGraphInputs(existingCategory.Children); } else AssertHelpers.Fail("Attempted to remove a category that does not exist in the graph."); @@ -2059,7 +2079,7 @@ public void ReplaceWith(GraphData other) m_MovedContexts = true; } - using (var inputsToRemove = PooledList.Get()) + using (ListPool.Get(out var inputsToRemove)) { foreach (var property in m_Properties.SelectValue()) inputsToRemove.Add(property); @@ -2114,7 +2134,7 @@ public void ReplaceWith(GraphData other) RemoveEdgeNoValidate(edge, false); } - using (var nodesToRemove = PooledList.Get()) + using (ListPool.Get(out var nodesToRemove)) { nodesToRemove.AddRange(m_Nodes.SelectValue()); foreach (var node in nodesToRemove) @@ -2290,7 +2310,7 @@ internal void PasteGraph(CopyPasteGraph graphToPaste, List } remappedNodes.Add(pastedNode); - AddNode(pastedNode); + AddNode(pastedNode, false); // add the node to the pasted node list m_PastedNodes.Add(pastedNode); @@ -2754,23 +2774,24 @@ void UpgradeFromBlockMap(Dictionary blockMap) ChangeVersion(latestVersion); } - PooledList<(LegacyUnknownTypeNode, AbstractMaterialNode)> updatedNodes = PooledList<(LegacyUnknownTypeNode, AbstractMaterialNode)>.Get(); - foreach (var node in m_Nodes.SelectValue()) + using (ListPool<(LegacyUnknownTypeNode, AbstractMaterialNode)>.Get(out var updatedNodes)) { - if (node is LegacyUnknownTypeNode lNode && lNode.foundType != null) + foreach (var node in m_Nodes.SelectValue()) + { + if (node is LegacyUnknownTypeNode lNode && lNode.foundType != null) + { + AbstractMaterialNode legacyNode = (AbstractMaterialNode)Activator.CreateInstance(lNode.foundType); + JsonUtility.FromJsonOverwrite(lNode.serializedData, legacyNode); + legacyNode.group = lNode.group; + updatedNodes.Add((lNode, legacyNode)); + } + } + foreach (var nodePair in updatedNodes) { - AbstractMaterialNode legacyNode = (AbstractMaterialNode)Activator.CreateInstance(lNode.foundType); - JsonUtility.FromJsonOverwrite(lNode.serializedData, legacyNode); - legacyNode.group = lNode.group; - updatedNodes.Add((lNode, legacyNode)); + m_Nodes.Add(nodePair.Item2); + ReplaceNodeWithNode(nodePair.Item1, nodePair.Item2); } } - foreach (var nodePair in updatedNodes) - { - m_Nodes.Add(nodePair.Item2); - ReplaceNodeWithNode(nodePair.Item1, nodePair.Item2); - } - updatedNodes.Dispose(); m_NodeDictionary = new Dictionary(m_Nodes.Count); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphDataUtils.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphDataUtils.cs index 662f277f083..591cea0e10d 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphDataUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/GraphDataUtils.cs @@ -11,8 +11,8 @@ public static class GraphDataUtils { public static void ApplyActionLeafFirst(GraphData graph, Action action) { - var temporaryMarks = PooledHashSet.Get(); - var permanentMarks = PooledHashSet.Get(); + var temporaryMarks = HashSetPool.Get(); + var permanentMarks = HashSetPool.Get(); var slots = ListPool.Get(); // Make sure we process a node's children before the node itself. @@ -58,8 +58,8 @@ public static void ApplyActionLeafFirst(GraphData graph, Action.Release(stack); ListPool.Release(slots); - temporaryMarks.Dispose(); - permanentMarks.Dispose(); + HashSetPool.Release(temporaryMarks); + HashSetPool.Release(permanentMarks); } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs index 2bb1efa905b..feb6713b6ae 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/ShaderGraphRequirements.cs @@ -215,6 +215,81 @@ internal ShaderGraphRequirements Union(ShaderGraphRequirements other) return newReqs; } + private static void FromSlot(MaterialSlot node, ref ShaderGraphRequirements reqs, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool[] texCoordNeedsDerivs = null) + { + if (node is IMayRequireTransform a) + reqs.m_RequiresTransforms.AddRange(a.RequiresTransform()); + + if (node is IMayRequireNormal b) + reqs.m_RequiresNormal |= b.RequiresNormal(stageCapability); + + if (node is IMayRequireBitangent c) + reqs.m_RequiresBitangent |= c.RequiresBitangent(stageCapability); + + if (node is IMayRequireTangent d) + reqs.m_RequiresTangent |= d.RequiresTangent(stageCapability); + + if (node is IMayRequireViewDirection e) + reqs.m_RequiresViewDir |= e.RequiresViewDirection(stageCapability); + + if (node is IMayRequirePosition f) + reqs.m_RequiresPosition |= f.RequiresPosition(stageCapability); + + if (node is IMayRequirePositionPredisplacement g) + reqs.m_RequiresPositionPredisplacement |= g.RequiresPositionPredisplacement(stageCapability); + + if (!reqs.m_RequiresScreenPosition && node is IMayRequireScreenPosition h) + reqs.m_RequiresScreenPosition = h.RequiresScreenPosition(stageCapability); + + if (!reqs.m_RequiresNDCPosition && node is IMayRequireNDCPosition i) + reqs.m_RequiresNDCPosition = i.RequiresNDCPosition(stageCapability); + + if (!reqs.m_RequiresPixelPosition && node is IMayRequirePixelPosition j) + reqs.m_RequiresPixelPosition = j.RequiresPixelPosition(stageCapability); + + if (!reqs.m_RequiresVertexColor && node is IMayRequireVertexColor k) + reqs.m_RequiresVertexColor = k.RequiresVertexColor(stageCapability); + + if (!reqs.m_RequiresFaceSign && node is IMayRequireFaceSign l) + reqs.m_RequiresFaceSign = l.RequiresFaceSign(stageCapability); + + if (!reqs.m_RequiresDepthTexture && node is IMayRequireDepthTexture m) + reqs.m_RequiresDepthTexture = m.RequiresDepthTexture(stageCapability); + + if (!reqs.m_RequiresCameraOpaqueTexture && node is IMayRequireCameraOpaqueTexture n) + reqs.m_RequiresCameraOpaqueTexture = n.RequiresCameraOpaqueTexture(stageCapability); + + if (!reqs.m_RequiresVertexSkinning && node is IMayRequireVertexSkinning o) + reqs.m_RequiresVertexSkinning = o.RequiresVertexSkinning(stageCapability); + + if (!reqs.m_RequiresVertexID && node is IMayRequireVertexID p) + reqs.m_RequiresVertexID = p.RequiresVertexID(stageCapability); + + if (node is IMayRequireMeshUV q) + { + for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex) + { + var channel = (UVChannel)uvIndex; + if (q.RequiresMeshUV(channel)) + { + reqs.m_RequiresMeshUVs.Add(channel); + if (texCoordNeedsDerivs is not null && + uvIndex < texCoordNeedsDerivs.Length && + texCoordNeedsDerivs[uvIndex]) + { + reqs.m_RequiresMeshUVDerivatives.Add(channel); + } + } + } + } + + if (!reqs.m_RequiresInstanceID && node is IMayRequireInstanceID r) + reqs.m_RequiresInstanceID = r.RequiresInstanceID(stageCapability); + + if (!reqs.m_RequiresUITK && node is IMayRequireUITK w) + reqs.m_RequiresUITK = w.RequiresUITK(stageCapability); + } + internal static ShaderGraphRequirements FromNodes(IEnumerable nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true, bool[] texCoordNeedsDerivs = null) where T : AbstractMaterialNode { @@ -226,6 +301,13 @@ internal static ShaderGraphRequirements FromNodes(IEnumerable nodes, Shade foreach (var node in nodes) { + using (UnityEngine.Pool.ListPool.Get(out var inputSlots)) + { + node.GetInputSlots(inputSlots); + foreach (var slot in inputSlots) + FromSlot(slot, ref reqs, stageCapability, texCoordNeedsDerivs); + } + if (node is IMayRequireTransform a) reqs.m_RequiresTransforms.AddRange(a.RequiresTransform()); @@ -303,6 +385,8 @@ internal static ShaderGraphRequirements FromNodes(IEnumerable nodes, Shade } reqs.m_RequiresTransforms = reqs.m_RequiresTransforms.Distinct().ToList(); + reqs.m_RequiresMeshUVDerivatives = reqs.m_RequiresMeshUVDerivatives.Distinct().ToList(); + reqs.m_RequiresMeshUVs = reqs.m_RequiresMeshUVs.Distinct().ToList(); // if anything needs tangentspace we have make // sure to have our othonormal basis! diff --git a/Packages/com.unity.shadergraph/Editor/Data/Graphs/SpaceMaterialSlot.cs b/Packages/com.unity.shadergraph/Editor/Data/Graphs/SpaceMaterialSlot.cs index bc63e160b52..f9759d1c12e 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Graphs/SpaceMaterialSlot.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Graphs/SpaceMaterialSlot.cs @@ -31,7 +31,10 @@ public override void CopyValuesFrom(MaterialSlot foundSlot) { var slot = foundSlot as SpaceMaterialSlot; if (slot != null) + { space = slot.space; + owner?.Dirty(ModificationScope.Topological); + } } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs b/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs index 79dabe57d86..76d95aedd8f 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Implementation/NodeUtils.cs @@ -263,13 +263,13 @@ private static void ActiveTreeExists(AbstractMaterialNode node, out bool activeL // NOTE: I cannot think if there is any case where the entirety of the connected graph would need to change, but if there are bugs // on certain nodes farther away from the node not updating correctly, a possible solution may be to get the entirety of the connected // graph instead of just what I have declared as the "local" connected graph - public static void ReevaluateActivityOfConnectedNodes(AbstractMaterialNode node, PooledHashSet changedNodes = null) + public static void ReevaluateActivityOfConnectedNodes(AbstractMaterialNode node, HashSet changedNodes = null) { var forest = GetForest(node); ReevaluateActivityOfNodeList(forest, changedNodes); } - public static void ReevaluateActivityOfNodeList(IEnumerable nodes, PooledHashSet changedNodes = null) + public static void ReevaluateActivityOfNodeList(IEnumerable nodes, HashSet changedNodes = null) { bool getChangedNodes = changedNodes != null; foreach (AbstractMaterialNode n in nodes) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs index 557850adac1..09e7ae121a9 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/AbstractMaterialNode.cs @@ -43,6 +43,8 @@ abstract class AbstractMaterialNode : JsonObject, IGroupItem, IRectInterface internal virtual bool ExposeToSearcher => true; + internal virtual bool UsePreviewPref => true; + protected virtual bool CanPropagateFloatLiteral => false; OnNodeModified m_OnModified; @@ -673,6 +675,7 @@ public virtual void PropagateFloatLiteral(List inputSlots, List inputSlots, List outputSlots) { var dynamicInputSlotsToCompare = DictionaryPool.Get(); @@ -732,6 +735,8 @@ public virtual void EvaluateDynamicMaterialSlots(List inputSlots, // we can now figure out the dynamic slotType // from here set all the var dynamicType = ConvertDynamicVectorInputTypeToConcrete(dynamicInputSlotsToCompare.Values); + lastKnownDynamicVectorLength = dynamicType.GetChannelCount(); + foreach (var dynamicKvP in dynamicInputSlotsToCompare) dynamicKvP.Key.SetConcreteType(dynamicType); foreach (var skippedSlot in skippedDynamicSlots) @@ -797,8 +802,8 @@ public virtual void Concretize() hasError = false; owner?.ClearErrorsForNode(this); - using (var inputSlots = PooledList.Get()) - using (var outputSlots = PooledList.Get()) + using (ListPool.Get(out var inputSlots)) + using (ListPool.Get(out var outputSlots)) { GetInputSlots(inputSlots); GetOutputSlots(outputSlots); @@ -847,9 +852,9 @@ protected string GetRayTracingError() => $@" public virtual void CollectPreviewMaterialProperties(List properties) { - using (var tempSlots = PooledList.Get()) - using (var tempPreviewProperties = PooledList.Get()) - using (var tempEdges = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) + using (ListPool.Get(out var tempPreviewProperties)) + using (ListPool.Get(out var tempEdges)) { GetInputSlots(tempSlots); foreach (var s in tempSlots) @@ -893,7 +898,7 @@ public virtual string GetVariableNameForNode() return defaultVariableName; } - public MaterialSlot AddSlot(MaterialSlot slot, bool attemptToModifyExistingInstance = true) + public MaterialSlot AddSlot(MaterialSlot slot, bool attemptToModifyExistingInstance = true, bool copyExistingValue = true) { if (slot == null) { @@ -956,7 +961,8 @@ public MaterialSlot AddSlot(MaterialSlot slot, bool attemptToModifyExistingInsta // foundSlot is of a different type; try to copy values // I think this is to support casting if implemented in CopyValuesFrom ? - slot.CopyValuesFrom(foundSlot); + if (copyExistingValue) + slot.CopyValuesFrom(foundSlot); foundSlot.owner = null; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs index fe1d07fda2d..eb08971407b 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/CodeFunctionNode.cs @@ -6,6 +6,7 @@ using UnityEngine; using UnityEditor.Graphing; using UnityEditor.ShaderGraph.Internal; +using UnityEngine.Pool; namespace UnityEditor.ShaderGraph { @@ -366,7 +367,7 @@ private static MaterialSlot CreateBoundSlot(Binding attributeBinding, int slotId public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetOutputSlots(tempSlots); foreach (var outSlot in tempSlots) @@ -410,7 +411,7 @@ private string GetFunctionHeader() { string header = "void " + GetFunctionName() + "("; - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetSlots(tempSlots); tempSlots.Sort((slot1, slot2) => slot1.id.CompareTo(slot2.id)); @@ -454,7 +455,7 @@ private string GetFunctionBody(MethodInfo info) // stomp any newline differences that might try to sneak in via this path result = result.Replace("\r\n", "\n"); - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetSlots(tempSlots); foreach (var slot in tempSlots) @@ -488,7 +489,7 @@ private static SlotAttribute GetSlotAttribute([NotNull] ParameterInfo info) public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapability) { var binding = NeededCoordinateSpace.None; - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) @@ -500,7 +501,7 @@ public NeededCoordinateSpace RequiresNormal(ShaderStageCapability stageCapabilit public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability) { var binding = NeededCoordinateSpace.None; - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) @@ -511,7 +512,7 @@ public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCa public NeededCoordinateSpace RequiresPosition(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var binding = NeededCoordinateSpace.None; @@ -523,7 +524,7 @@ public NeededCoordinateSpace RequiresPosition(ShaderStageCapability stageCapabil public NeededCoordinateSpace RequiresPositionPredisplacement(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var binding = NeededCoordinateSpace.None; @@ -535,7 +536,7 @@ public NeededCoordinateSpace RequiresPositionPredisplacement(ShaderStageCapabili public NeededCoordinateSpace RequiresTangent(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var binding = NeededCoordinateSpace.None; @@ -547,7 +548,7 @@ public NeededCoordinateSpace RequiresTangent(ShaderStageCapability stageCapabili public NeededCoordinateSpace RequiresBitangent(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var binding = NeededCoordinateSpace.None; @@ -559,7 +560,7 @@ public NeededCoordinateSpace RequiresBitangent(ShaderStageCapability stageCapabi public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) @@ -574,7 +575,7 @@ public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapabil public bool RequiresScreenPosition(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) @@ -588,7 +589,7 @@ public bool RequiresScreenPosition(ShaderStageCapability stageCapability) public bool RequiresNDCPosition(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) @@ -602,7 +603,7 @@ public bool RequiresNDCPosition(ShaderStageCapability stageCapability) public bool RequiresPixelPosition(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) @@ -616,7 +617,7 @@ public bool RequiresPixelPosition(ShaderStageCapability stageCapability) public bool RequiresVertexColor(ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/CalculateLevelOfDetailTexture2DNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/CalculateLevelOfDetailTexture2DNode.cs index 3530a123a24..dba0804bb68 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/CalculateLevelOfDetailTexture2DNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/CalculateLevelOfDetailTexture2DNode.cs @@ -99,7 +99,7 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/GatherTexture2DNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/GatherTexture2DNode.cs index d43552bde59..dbb86737199 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/GatherTexture2DNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/GatherTexture2DNode.cs @@ -110,7 +110,7 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DArrayNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DArrayNode.cs index f5cdb655d64..972edc540ce 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DArrayNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DArrayNode.cs @@ -116,7 +116,7 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs index f45c55579de..c73bde70350 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DLODNode.cs @@ -136,7 +136,7 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { var result = false; - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs index 8ef013af9fe..74f4637952e 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleTexture2DNode.cs @@ -3,6 +3,7 @@ using UnityEditor.Graphing; using UnityEditor.ShaderGraph.Drawing.Controls; using UnityEditor.ShaderGraph.Internal; +using UnityEngine.Pool; namespace UnityEditor.ShaderGraph { @@ -185,7 +186,7 @@ public virtual void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode gene public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleVirtualTextureNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleVirtualTextureNode.cs index 870f4914c63..be999b69a96 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleVirtualTextureNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/SampleVirtualTextureNode.cs @@ -540,7 +540,7 @@ public override void CollectShaderProperties(PropertyCollector properties, Gener public bool RequiresMeshUV(Internal.UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); foreach (var slot in tempSlots) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs index bd1a751d16f..6e1b69183b3 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/Texture/TextureStackNode.cs @@ -27,20 +27,20 @@ public static void GenerateVirtualTextureFeedback( // so per permutation we gather variables contribution to feedback and we generate // feedback gathering for each permutation individually. - var feedbackVariablesPerPermutation = PooledList>.Get(); + var feedbackVariablesPerPermutation = UnityEngine.Pool.ListPool>.Get(); try { if (shaderKeywords.permutations.Count >= 1) { for (int i = 0; i < shaderKeywords.permutations.Count; i++) { - feedbackVariablesPerPermutation.Add(PooledList.Get()); + feedbackVariablesPerPermutation.Add(UnityEngine.Pool.ListPool.Get()); } } else { // Create a dummy single permutation - feedbackVariablesPerPermutation.Add(PooledList.Get()); + feedbackVariablesPerPermutation.Add(UnityEngine.Pool.ListPool.Get()); } int index = 0; //for keywordPermutationsPerNode @@ -138,9 +138,9 @@ public static void GenerateVirtualTextureFeedback( { foreach (var list in feedbackVariablesPerPermutation) { - list.Dispose(); + UnityEngine.Pool.ListPool.Release(list); } - feedbackVariablesPerPermutation.Dispose(); + UnityEngine.Pool.ListPool>.Release(feedbackVariablesPerPermutation); } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementLayoutUVNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementLayoutUVNode.cs index b03a43168cd..8fb535852f6 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementLayoutUVNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementLayoutUVNode.cs @@ -1,12 +1,13 @@ using UnityEditor.Graphing; using UnityEditor.Rendering.UITK.ShaderGraph; +using UnityEditor.ShaderGraph.Internal; using UnityEngine; namespace UnityEditor.ShaderGraph { [Title("Input", "UI", "Element Layout UV")] [SubTargetFilter(typeof(IUISubTarget))] - class ElementLayoutUV : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireUITK + class ElementLayoutUV : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireUITK, IMayRequireMeshUV { public const int LayoutUVSlotId = 0; @@ -29,12 +30,25 @@ public override void UpdateNodeAfterDeserialization() public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - if (GetInputNodeFromSlot(LayoutUVSlotId) != null) sb.AppendLine(string.Format("$precision2 {0} = IN.layoutUV.xy;", GetVariableNameForSlot(LayoutUVSlotId))); + if (generationMode == GenerationMode.Preview) + { + // In preview mode, use standard mesh UV0 (will visualize as color: red = u, green = v) + sb.AppendLine("$precision2 {0} = IN.uv0.xy;", GetVariableNameForSlot(LayoutUVSlotId)); + return; + } + + if (GetInputNodeFromSlot(LayoutUVSlotId) != null) sb.AppendLine("$precision2 {0} = IN.layoutUV.xy;", GetVariableNameForSlot(LayoutUVSlotId)); } public bool RequiresUITK(ShaderStageCapability stageCapability) { return true; } + + public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) + { + // Require UV0 in preview mode for visualization + return channel == UVChannel.UV0; + } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureSizeNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureSizeNode.cs index eaa0f19b0f7..8f465d10f12 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureSizeNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureSizeNode.cs @@ -39,6 +39,16 @@ public override void UpdateNodeAfterDeserialization() public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { + if (generationMode == GenerationMode.Preview) + { + // In preview mode, return default values (1.0) + if (GetInputNodeFromSlot(TextureWidthSlotId) != null) sb.AppendLine("$precision1 {0} = 1.0;", GetVariableNameForSlot(TextureWidthSlotId)); + if (GetInputNodeFromSlot(TextureHeightSlotId) != null) sb.AppendLine("$precision1 {0} = 1.0;", GetVariableNameForSlot(TextureHeightSlotId)); + if (GetInputNodeFromSlot(TexelWidthSlotId) != null) sb.AppendLine("$precision1 {0} = 1.0;", GetVariableNameForSlot(TexelWidthSlotId)); + if (GetInputNodeFromSlot(TexelHeightSlotId) != null) sb.AppendLine("$precision1 {0} = 1.0;", GetVariableNameForSlot(TexelHeightSlotId)); + return; + } + if ((GetInputNodeFromSlot(TextureWidthSlotId) != null) || (GetInputNodeFromSlot(TextureHeightSlotId) != null) || (GetInputNodeFromSlot(TexelWidthSlotId) != null) || diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureUVNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureUVNode.cs index 62f4226cdb7..2c6f9125666 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureUVNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Input/UI/ElementTextureUVNode.cs @@ -1,12 +1,13 @@ using UnityEditor.Graphing; using UnityEditor.Rendering.UITK.ShaderGraph; +using UnityEditor.ShaderGraph.Internal; using UnityEngine; namespace UnityEditor.ShaderGraph { [Title("Input", "UI", "Element Texture UV")] [SubTargetFilter(typeof(IUISubTarget))] - class ElementTextureUVNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireUITK + class ElementTextureUVNode : AbstractMaterialNode, IGeneratesBodyCode, IMayRequireUITK, IMayRequireMeshUV { public const int TextureUVSlotId = 0; @@ -29,12 +30,25 @@ public override void UpdateNodeAfterDeserialization() public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - if (GetInputNodeFromSlot(TextureUVSlotId) != null) sb.AppendLine(string.Format("$precision2 {0} = IN.uvClip.xy;", GetVariableNameForSlot(TextureUVSlotId))); + if (generationMode == GenerationMode.Preview) + { + // In preview mode, use standard mesh UV0 (will visualize as color: red = u, green = v) + sb.AppendLine("$precision2 {0} = IN.uv0.xy;", GetVariableNameForSlot(TextureUVSlotId)); + return; + } + + if (GetInputNodeFromSlot(TextureUVSlotId) != null) sb.AppendLine("$precision2 {0} = IN.uvClip.xy;", GetVariableNameForSlot(TextureUVSlotId)); } public bool RequiresUITK(ShaderStageCapability stageCapability) { return true; } + + public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) + { + // Require UV0 in preview mode for visualization + return channel == UVChannel.UV0; + } } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs index 3b9cfa63f13..5b8f38803fc 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/GradientNoiseNode.cs @@ -123,7 +123,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/SimpleNoiseNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/SimpleNoiseNode.cs index 95ec9622fbb..8c412bd3a37 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/SimpleNoiseNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/SimpleNoiseNode.cs @@ -136,7 +136,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/VoronoiNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/VoronoiNode.cs index fc96c33e860..557857e0886 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/VoronoiNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Procedural/Noise/VoronoiNode.cs @@ -146,7 +146,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultBitmapTextNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultBitmapTextNode.cs index 2d8e4e4b3ef..7acf9e22c6f 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultBitmapTextNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultBitmapTextNode.cs @@ -33,7 +33,15 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo { string outputVarName = GetVariableNameForSlot(k_OutputSlotId); - sb.AppendLine("float4 {0} = float4(1, 1, 0, 1);", outputVarName); + sb.AppendLine("float4 {0} = float4(1, 1, 1, 1);", outputVarName); + + if (generationMode == GenerationMode.Preview) + { + bool hasTint = GetInputNodeFromSlot(k_InputSlotIdTint) != null; + if (hasTint) + sb.AppendLine("{0} = {1};", outputVarName, GetSlotValue(k_InputSlotIdTint, generationMode)); + return; + } sb.AppendLine("[branch] if ((_UIE_RENDER_TYPE_TEXT || _UIE_RENDER_TYPE_ANY) && round(IN.typeTexSettings.x) == k_FragTypeText && (!(GetTextureInfo(IN.typeTexSettings.y).sdfScale > 0.0)))"); using (sb.BlockScope()) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultGradientNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultGradientNode.cs index d5c2f7420d7..d94d3f231fb 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultGradientNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultGradientNode.cs @@ -29,7 +29,10 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo { string outputVarName = GetVariableNameForSlot(k_OutputSlotId); - sb.AppendLine("float4 {0} = float4(1, 1, 0, 1);", outputVarName); + sb.AppendLine("float4 {0} = float4(1, 1, 1, 1);", outputVarName); + + if (generationMode == GenerationMode.Preview) + return; sb.AppendLine("[branch] if (_UIE_RENDER_TYPE_GRADIENT || _UIE_RENDER_TYPE_ANY && round(IN.typeTexSettings.x) == k_FragTypeSvgGradient)"); using (sb.BlockScope()) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSDFTextNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSDFTextNode.cs index 8791c282b74..3c17868952d 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSDFTextNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSDFTextNode.cs @@ -33,7 +33,15 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo { string outputVarName = GetVariableNameForSlot(k_OutputSlotId); - sb.AppendLine("float4 {0} = float4(1, 1, 0, 1);", outputVarName); + sb.AppendLine("float4 {0} = float4(1, 1, 1, 1);", outputVarName); + + if (generationMode == GenerationMode.Preview) + { + bool hasTint = GetInputNodeFromSlot(k_InputSlotIdTint) != null; + if (hasTint) + sb.AppendLine("{0} = {1};", outputVarName, GetSlotValue(k_InputSlotIdTint, generationMode)); + return; + } sb.AppendLine("[branch] if ((_UIE_RENDER_TYPE_TEXT || _UIE_RENDER_TYPE_ANY) && round(IN.typeTexSettings.x) == k_FragTypeText && (GetTextureInfo(IN.typeTexSettings.y).sdfScale > 0.0))"); using (sb.BlockScope()) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSolidNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSolidNode.cs index 2f24f607cd5..d02938ca859 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSolidNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultSolidNode.cs @@ -29,7 +29,10 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo { string outputVarName = GetVariableNameForSlot(k_OutputSlotId); - sb.AppendLine("float4 {0} = float4(1, 1, 0, 1);", outputVarName); + sb.AppendLine("float4 {0} = float4(1, 1, 1, 1);", outputVarName); + + if (generationMode == GenerationMode.Preview) + return; sb.AppendLine("[branch] if (_UIE_RENDER_TYPE_SOLID || _UIE_RENDER_TYPE_ANY && round(IN.typeTexSettings.x) == k_FragTypeSolid)"); using (sb.BlockScope()) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultTextureNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultTextureNode.cs index 64c73d86836..fdbb5b0405d 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultTextureNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/DefaultTextureNode.cs @@ -36,7 +36,15 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo { string outputVarName = GetVariableNameForSlot(k_OutputSlotId); - sb.AppendLine("float4 {0} = float4(1, 1, 0, 1);", outputVarName); + sb.AppendLine("float4 {0} = float4(1, 1, 1, 1);", outputVarName); + + if (generationMode == GenerationMode.Preview) + { + bool hasTint = GetInputNodeFromSlot(k_InputSlotIdTint) != null; + if (hasTint) + sb.AppendLine("{0} = {1};", outputVarName, GetSlotValue(k_InputSlotIdTint, generationMode)); + return; + } sb.AppendLine("[branch] if (_UIE_RENDER_TYPE_TEXTURE || _UIE_RENDER_TYPE_ANY && round(IN.typeTexSettings.x) == k_FragTypeTexture)"); using (sb.BlockScope()) diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/IsForcedGammaNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/IsForcedGammaNode.cs index 1c812950f37..f46ac45e640 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/IsForcedGammaNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/IsForcedGammaNode.cs @@ -26,6 +26,13 @@ public sealed override void UpdateNodeAfterDeserialization() public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { + if (generationMode == GenerationMode.Preview) + { + // In preview mode, return false by default + sb.AppendLine("bool {0} = false;", GetVariableNameForSlot(k_OutputSlotId)); + return; + } + sb.AppendLine("bool {0} = _UIE_FORCE_GAMMA;", GetVariableNameForSlot(k_OutputSlotId)); } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeBranchNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeBranchNode.cs index 4d35f17f2fb..566185ff83b 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeBranchNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeBranchNode.cs @@ -49,9 +49,21 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo string outputVarNameColor = GetVariableNameForSlot(k_OutputSlotIdColor); string outputVarNameAlpha = GetVariableNameForSlot(k_OutputSlotIdAlpha); - sb.AppendLine("float3 {0} = float3(0, 0, 0);", outputVarNameColor); + sb.AppendLine("float3 {0} = float3(1, 1, 1);", outputVarNameColor); sb.AppendLine("float {0} = 1.0;", outputVarNameAlpha); + if (generationMode == GenerationMode.Preview) + { + // In preview mode the UITK render-type macros don't exist. + // Output the Solid input if connected. + if (GetInputNodeFromSlot(k_InputSlotIdSolid) != null) + { + sb.AppendLine("{0} = {1}.rgb;", outputVarNameColor, GetSlotValue(k_InputSlotIdSolid, generationMode)); + sb.AppendLine("{0} = {1}.a;", outputVarNameAlpha, GetSlotValue(k_InputSlotIdSolid, generationMode)); + } + return; + } + sb.AppendLine("[branch] if (_UIE_RENDER_TYPE_SOLID || _UIE_RENDER_TYPE_ANY && TestType(IN.typeTexSettings.x, k_FragTypeSolid))"); using (sb.BlockScope()) { @@ -95,7 +107,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo sb.AppendLine("{0} = Unity_UIE_RenderTypeSwitchNode_Output.color.a;", outputVarNameAlpha); } } - sb.AppendLine("else [branch] if ((_UIE_RENDER_TYPE_TEXT || _UIE_RENDER_TYPE_ANY) && TestType(IN.typeTexSettings.x, k_FragTypeText))"); + sb.AppendLine("else [branch] if (_UIE_RENDER_TYPE_TEXT || _UIE_RENDER_TYPE_ANY && TestType(IN.typeTexSettings.x, k_FragTypeText))"); using (sb.BlockScope()) { sb.AppendLine("[branch] if (GetTextureInfo(IN.typeTexSettings.y).sdfScale > 0.0)"); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeNode.cs index 3aaed5f3bcf..45a7663a8f7 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/RenderTypeNode.cs @@ -39,6 +39,18 @@ public sealed override void UpdateNodeAfterDeserialization() public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { + if (generationMode == GenerationMode.Preview) + { + // In preview mode the UITK render-type macros don't exist. + // Default to Solid render type. + sb.AppendLine("bool {0} = true;", GetVariableNameForSlot(k_OutputSlotIdSolid)); + sb.AppendLine("bool {0} = false;", GetVariableNameForSlot(k_OutputSlotIdTexture)); + sb.AppendLine("bool {0} = false;", GetVariableNameForSlot(k_OutputSlotIdSDFText)); + sb.AppendLine("bool {0} = false;", GetVariableNameForSlot(k_OutputSlotIdBitmapText)); + sb.AppendLine("bool {0} = false;", GetVariableNameForSlot(k_OutputSlotIdGradient)); + return; + } + sb.AppendLine("bool {0} = _UIE_RENDER_TYPE_SOLID || _UIE_RENDER_TYPE_ANY && round(IN.typeTexSettings.x) == k_FragTypeSolid;", GetVariableNameForSlot(k_OutputSlotIdSolid)); sb.AppendLine("bool {0} = _UIE_RENDER_TYPE_TEXTURE || _UIE_RENDER_TYPE_ANY && round(IN.typeTexSettings.x) == k_FragTypeTexture;", GetVariableNameForSlot(k_OutputSlotIdTexture)); sb.AppendLine("bool {0} = (_UIE_RENDER_TYPE_TEXT || _UIE_RENDER_TYPE_ANY) && round(IN.typeTexSettings.x) == k_FragTypeText && (GetTextureInfo(IN.typeTexSettings.y).sdfScale > 0.0);", GetVariableNameForSlot(k_OutputSlotIdSDFText)); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs index 24f2be454ac..2083a0d538b 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UI/SampleElementTextureNode.cs @@ -82,6 +82,16 @@ public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode gener public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { + if (generationMode == GenerationMode.Preview) + { + // In preview mode, return white + sb.AppendLine("$precision4 {0} = $precision4(1, 1, 1, 1);", GetVariableNameForSlot(Color0SlotId)); + sb.AppendLine("$precision4 {0} = $precision4(1, 1, 1, 1);", GetVariableNameForSlot(Color1SlotId)); + sb.AppendLine("$precision4 {0} = $precision4(1, 1, 1, 1);", GetVariableNameForSlot(Color2SlotId)); + sb.AppendLine("$precision4 {0} = $precision4(1, 1, 1, 1);", GetVariableNameForSlot(Color3SlotId)); + return; + } + sb.AppendLine("$precision4 {0};", GetVariableNameForSlot(Color0SlotId)); sb.AppendLine("$precision4 {0};", GetVariableNameForSlot(Color1SlotId)); sb.AppendLine("$precision4 {0};", GetVariableNameForSlot(Color2SlotId)); @@ -99,6 +109,13 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo GetVariableNameForSlot(Color1SlotId), GetVariableNameForSlot(Color2SlotId), GetVariableNameForSlot(Color3SlotId)); + + sb.AppendLine("#if _UIE_FORCE_GAMMA"); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color0SlotId), GetVariableNameForSlot(Color0SlotId)); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color1SlotId), GetVariableNameForSlot(Color1SlotId)); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color2SlotId), GetVariableNameForSlot(Color2SlotId)); + sb.AppendLine("{0}.rgb = uie_linear_to_gamma({1}.rgb);", GetVariableNameForSlot(Color3SlotId), GetVariableNameForSlot(Color3SlotId)); + sb.AppendLine("#endif"); } } diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/FlipbookNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/FlipbookNode.cs index 57aeea08e69..150a4838e76 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/FlipbookNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/FlipbookNode.cs @@ -178,7 +178,7 @@ private void AppendInvertSpecificLines(ShaderStringBuilder stringBuilder) public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxMappingNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxMappingNode.cs index 89322221acb..85087a75183 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxMappingNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxMappingNode.cs @@ -114,7 +114,7 @@ public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCa public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxOcclusionMappingNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxOcclusionMappingNode.cs index d9a49c56168..0dca94468d8 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxOcclusionMappingNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/UV/ParallaxOcclusionMappingNode.cs @@ -229,7 +229,7 @@ public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCa public bool RequiresMeshUV(UVChannel channel, ShaderStageCapability stageCapability) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { GetInputSlots(tempSlots); var result = false; diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs index 77236515a48..38001f0de7b 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/CustomFunctionNode.cs @@ -150,8 +150,8 @@ public string functionBody public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - using (var inputSlots = PooledList.Get()) - using (var outputSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var inputSlots)) + using (UnityEngine.Pool.ListPool.Get(out var outputSlots)) { GetInputSlots(inputSlots); GetOutputSlots(outputSlots); @@ -301,8 +301,8 @@ public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode gener void GetFunctionHeader(ShaderStringBuilder sb) { - using (var inputSlots = PooledList.Get()) - using (var outputSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var inputSlots)) + using (UnityEngine.Pool.ListPool.Get(out var outputSlots)) { GetInputSlots(inputSlots); GetOutputSlots(outputSlots); @@ -380,7 +380,7 @@ static bool IsValidFunction(HlslSourceType sourceType, string functionName, stri void ValidateSlotName() { - using (var slots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var slots)) { GetSlots(slots); foreach (var slot in slots) @@ -398,10 +398,10 @@ void ValidateSlotName() void ValidateBareTextureSlots() { - using (var outputSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var slots)) { - GetOutputSlots(outputSlots); - foreach (var slot in outputSlots) + GetOutputSlots(slots); + foreach (var slot in slots) { if (slot.bareResource) { diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs index f3810ccf737..dbd19e58051 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/KeywordNode.cs @@ -77,26 +77,25 @@ void UpdatePorts() case KeywordType.Boolean: { // Boolean type has preset slots - PooledList temp = PooledList.Get(); - GetInputSlots(temp); - if (temp.Any()) + using (UnityEngine.Pool.ListPool.Get(out var temp)) { - temp.Dispose(); - break; - } - else - { - temp.Dispose(); + GetInputSlots(temp); + if (temp.Count > 0) + { + break; + } } + AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, "Out", "Out", SlotType.Output, Vector4.zero)); AddSlot(new DynamicVectorMaterialSlot(1, "On", "On", SlotType.Input, Vector4.zero)); AddSlot(new DynamicVectorMaterialSlot(2, "Off", "Off", SlotType.Input, Vector4.zero)); RemoveSlotsNameNotMatching(new int[] { 0, 1, 2 }); break; + } case KeywordType.Enum: - using (var inputSlots = PooledList.Get()) - using (var slotIDs = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var inputSlots)) + using (UnityEngine.Pool.ListPool.Get(out var slotIDs)) { // Get slots GetInputSlots(inputSlots); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/SwitchNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/SwitchNode.cs index 55f46e12363..15ec7c7db28 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/SwitchNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/Logic/SwitchNode.cs @@ -114,8 +114,8 @@ public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode gener public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) { - using (var inputSlots = PooledList.Get()) - using (var outputSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var inputSlots)) + using (UnityEngine.Pool.ListPool.Get(out var outputSlots)) { GetInputSlots(inputSlots); GetOutputSlots(outputSlots); @@ -172,8 +172,8 @@ static string Op(ComparisonType op) void GetFunctionDefinition(ShaderStringBuilder sb) { - using (var inputSlots = PooledList.Get()) - using (var outputSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var inputSlots)) + using (UnityEngine.Pool.ListPool.Get(out var outputSlots)) { ShaderStringBuilder body = new(); body.AppendLine("Out = Fallback;"); diff --git a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/PreviewNode.cs b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/PreviewNode.cs index b40b821fdfa..7ce6a14f9c1 100644 --- a/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/PreviewNode.cs +++ b/Packages/com.unity.shadergraph/Editor/Data/Nodes/Utility/PreviewNode.cs @@ -8,6 +8,8 @@ class PreviewNode : CodeFunctionNode { public override bool hasPreview { get { return true; } } + internal override bool UsePreviewPref => false; + protected override bool CanPropagateFloatLiteral => true; [SerializeField] diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs b/Packages/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs deleted file mode 100644 index 6aab0b5c297..00000000000 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine.Assertions; - -namespace UnityEditor.ShaderGraph -{ - class PooledHashSet : HashSet, IDisposable - { - static Stack> s_Pool = new Stack>(); - bool m_Active; - - PooledHashSet() { } - - public static PooledHashSet Get() - { - if (s_Pool.Count == 0) - { - return new PooledHashSet { m_Active = true }; - } - - var list = s_Pool.Pop(); - list.m_Active = true; -#if DEBUG - GC.ReRegisterForFinalize(list); -#endif - return list; - } - - public void Dispose() - { - Assert.IsTrue(m_Active); - m_Active = false; - Clear(); - s_Pool.Push(this); -#if DEBUG - GC.SuppressFinalize(this); -#endif - } - - // Destructor causes some GC alloc so only do this sanity check in debug build -#if DEBUG - ~PooledHashSet() - { - throw new InvalidOperationException($"{nameof(PooledHashSet)} must be disposed manually."); - } - -#endif - } -} diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta b/Packages/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta deleted file mode 100644 index 9bf72638e9b..00000000000 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledHashSet.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 11c00f8215374c368941cd4c06242ed7 -timeCreated: 1582812009 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledList.cs b/Packages/com.unity.shadergraph/Editor/Data/Util/PooledList.cs deleted file mode 100644 index 2b0be80b0d5..00000000000 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledList.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine.Assertions; - -namespace UnityEditor.ShaderGraph -{ - class PooledList : List, IDisposable - { - static Stack> s_Pool = new Stack>(); - bool m_Active; - - PooledList() { } - - public static PooledList Get() - { - if (s_Pool.Count == 0) - { - return new PooledList { m_Active = true }; - } - - var list = s_Pool.Pop(); - list.m_Active = true; -#if DEBUG - GC.ReRegisterForFinalize(list); -#endif - return list; - } - - public void Dispose() - { - Assert.IsTrue(m_Active); - m_Active = false; - Clear(); - s_Pool.Push(this); -#if DEBUG - GC.SuppressFinalize(this); -#endif - } - - // Destructor causes some GC alloc so only do this sanity check in debug build -#if DEBUG - ~PooledList() - { - throw new InvalidOperationException($"{nameof(PooledList)} must be disposed manually."); - } - -#endif - } -} diff --git a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledList.cs.meta b/Packages/com.unity.shadergraph/Editor/Data/Util/PooledList.cs.meta deleted file mode 100644 index bbf2fbfe95b..00000000000 --- a/Packages/com.unity.shadergraph/Editor/Data/Util/PooledList.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 9f3065ccf1f64e219d8039d355a788a1 -timeCreated: 1579171175 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs b/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs index 19780d548b0..faf6197fdf8 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/PreviewManager.cs @@ -335,8 +335,8 @@ internal static void PropagateNodes(HashSet sources, Propa static void ForeachConnectedNode(AbstractMaterialNode node, PropagationDirection dir, Action action) { - using (var tempEdges = PooledList.Get()) - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempEdges)) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { // Loop through all nodes that the node feeds into. if (dir == PropagationDirection.Downstream) @@ -470,10 +470,10 @@ public void HandleGraphChanges() } private static readonly ProfilerMarker CollectPreviewPropertiesMarker = new ProfilerMarker("CollectPreviewProperties"); - void CollectPreviewProperties(IEnumerable nodesToCollect, PooledList perMaterialPreviewProperties) + void CollectPreviewProperties(IEnumerable nodesToCollect, List perMaterialPreviewProperties) { using (CollectPreviewPropertiesMarker.Auto()) - using (var tempPreviewProps = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempPreviewProps)) { // collect from all of the changed nodes foreach (var propNode in nodesToCollect) @@ -639,10 +639,10 @@ bool TimedNodesShouldUpdate(EditorWindow editorWindow) public void RenderPreviews(EditorWindow editorWindow, bool requestShaders = true) { using (RenderPreviewsMarker.Auto()) - using (var renderList2D = PooledList.Get()) - using (var renderList3D = PooledList.Get()) - using (var nodesToDraw = PooledHashSet.Get()) - using (var perMaterialPreviewProperties = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var renderList2D)) + using (UnityEngine.Pool.ListPool.Get(out var renderList3D)) + using (UnityEngine.Pool.HashSetPool.Get(out var nodesToDraw)) + using (UnityEngine.Pool.ListPool.Get(out var perMaterialPreviewProperties)) { // update topology cached data // including list of time-dependent previews, and the preview mode (2d/3d) @@ -830,7 +830,7 @@ void ProcessCompletedShaderCompilations() { // Check for shaders that finished compiling and set them to redraw using (ProcessCompletedShaderCompilationsMarker.Auto()) - using (var previewsCompiled = PooledHashSet.Get()) + using (UnityEngine.Pool.HashSetPool.Get(out var previewsCompiled)) { foreach (var preview in m_PreviewsCompiling) { @@ -905,7 +905,7 @@ void KickOffShaderCompilations() { // Start compilation for nodes that need to recompile using (KickOffShaderCompilationsMarker.Auto()) - using (var previewsToCompile = PooledHashSet.Get()) + using (UnityEngine.Pool.HashSetPool.Get(out var previewsToCompile)) { // master node compile is first in the priority list, as it takes longer than the other previews if (m_PreviewsCompiling.Count + previewsToCompile.Count < m_MaxPreviewsCompiling) @@ -940,7 +940,7 @@ void KickOffShaderCompilations() } if (previewsToCompile.Count >= 0) - using (var nodesToCompile = PooledHashSet.Get()) + using (UnityEngine.Pool.HashSetPool.Get(out var nodesToCompile)) { // remove the selected nodes from the recompile list m_PreviewsNeedsRecompile.ExceptWith(previewsToCompile); @@ -989,7 +989,7 @@ void UpdateShaders() { // nodes with shader changes cause all downstream nodes to need recompilation // (since they presumably include the code for these nodes) - using (var nodesToRecompile = PooledHashSet.Get()) + using (UnityEngine.Pool.HashSetPool.Get(out var nodesToRecompile)) { PropagateNodes(m_NodesShaderChanged, PropagationDirection.Downstream, nodesToRecompile); ForEachNodesPreview(nodesToRecompile, p => m_PreviewsNeedsRecompile.Add(p)); @@ -1255,7 +1255,7 @@ void UpdateTopology() return; using (UpdateTopologyMarker.Auto()) - using (var timedNodes = PooledHashSet.Get()) + using (UnityEngine.Pool.HashSetPool.Get(out var timedNodes)) { timedNodes.UnionWith(m_Graph.GetNodes().Where(n => n.RequiresTime())); @@ -1291,7 +1291,7 @@ void UpdateTopology() } private static readonly ProfilerMarker RenderPreviewMarker = new ProfilerMarker("RenderPreview"); - void RenderPreview(PreviewRenderData renderData, Mesh mesh, Matrix4x4 transform, PooledList perMaterialPreviewProperties) + void RenderPreview(PreviewRenderData renderData, Mesh mesh, Matrix4x4 transform, List perMaterialPreviewProperties) { using (RenderPreviewMarker.Auto()) { @@ -1402,7 +1402,9 @@ void CompileMasterNodeShader() // Skip generation for VFXTarget if (!m_Graph.isOnlyVFXTarget) { - var generator = new Generator(m_Graph, m_Graph.outputNode, GenerationMode.Preview, "Master"); + // UITK shaders need ForReals mode to have access to UITK macros for proper rendering + var mode = prefersUITKPreview ? GenerationMode.ForReals : GenerationMode.Preview; + var generator = new Generator(m_Graph, m_Graph.outputNode, mode, "Master"); shaderData.shaderString = generator.generatedShader; // record the blocks temporarily created for missing stack blocks diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs b/Packages/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs index cdcff291fb8..e0f07a5adf3 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/SearchWindowProvider.cs @@ -214,7 +214,7 @@ public void GenerateNodeEntries() node.InitializeFromProvider(provider); var header = node.Header; - string rawTitle = $"{header.category}/{header.uniqueName}"; + string rawTitle = $"{header.searchCategory}/{header.searchName}"; int orderFound = 0; while (providerCollisions.Contains(rawTitle)) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index 3aa71e400b2..f91d63a1f63 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -19,6 +19,7 @@ using UnityEditor.ShaderGraph.Internal; using UnityEditor.Experimental; using UnityEditor.PackageManager.UI; +using UnityEngine.Pool; namespace UnityEditor.ShaderGraph.Drawing { @@ -253,7 +254,7 @@ public GraphEditorView(EditorWindow editorWindow, GraphData graph, MessageManage GUILayout.Label("Color Mode"); var newColorIndex = EditorGUILayout.Popup(m_ColorManager.activeIndex, colorProviders, GUILayout.Width(100f)); GUILayout.Space(4); - + m_UserViewSettings.isBlackboardVisible = GUILayout.Toggle(m_UserViewSettings.isBlackboardVisible, BlackboardIcon, EditorStyles.toolbarButton); GUILayout.Space(6); @@ -1397,7 +1398,7 @@ void UpdateEdgeColors(HashSet nodeViews) nodeStack.Clear(); foreach (var nodeView in nodeViews) nodeStack.Push((Node)nodeView); - PooledList edgesToUpdate = PooledList.Get(); + var edgesToUpdate = ListPool.Get(); while (nodeStack.Any()) { var nodeView = nodeStack.Pop(); @@ -1456,7 +1457,7 @@ void UpdateEdgeColors(HashSet nodeViews) } } var edges = edgesToUpdate.ToArray(); - edgesToUpdate.Dispose(); + ListPool.Release(edgesToUpdate); schedule.Execute(() => { foreach (Edge e in edges) diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs index af1ca07c061..b4ca6e04f5f 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/MaterialGraphView.cs @@ -138,6 +138,7 @@ void ChangeTargetSettings() graph.AddRemoveBlocksFromActiveList(activeBlocks); } + graph.RefreshBadgesAndPreviews(); graph.UpdateActiveBlocks(activeBlocks); this.m_PreviewManagerUpdateDelegate(); this.m_InspectorUpdateDelegate(); diff --git a/Packages/com.unity.shadergraph/Editor/Drawing/Views/ReorderableSlotListView.cs b/Packages/com.unity.shadergraph/Editor/Drawing/Views/ReorderableSlotListView.cs index 94c410e8206..e3dd1653330 100644 --- a/Packages/com.unity.shadergraph/Editor/Drawing/Views/ReorderableSlotListView.cs +++ b/Packages/com.unity.shadergraph/Editor/Drawing/Views/ReorderableSlotListView.cs @@ -134,7 +134,7 @@ private void AddCallbacks() if (displayName != oldSlot.RawDisplayName()) { - using (var tempSlots = PooledList.Get()) + using (UnityEngine.Pool.ListPool.Get(out var tempSlots)) { m_Node.GetSlots(tempSlots); @@ -178,6 +178,8 @@ private void AddCallbacks() m_Node.SetSlotOrder(orderedSlotIds); RecreateList(); + // Editing a node's slots doesn't automatically re-concretize them, so we must explicitly do so + m_Node.Concretize(); m_Node.ValidateNode(); } }; diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs index fb9d8db6aaf..166bc223f47 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Processors/Generator.cs @@ -12,6 +12,7 @@ using UnityEngine.Assertions; using Pool = UnityEngine.Pool; using Unity.Profiling; +using UnityEditor.Rendering.UITK.ShaderGraph; namespace UnityEditor.ShaderGraph { @@ -192,6 +193,14 @@ Target[] GetTargetImplementations() } else { + var targets = m_GraphData.activeTargets.ToList(); + foreach (var target in targets) + { + if (target.activeSubTarget is IUISubTarget) + { + return new Target[] { new PreviewTarget(true) }; + } + } return new Target[] { new PreviewTarget() }; } } @@ -448,7 +457,8 @@ static PropertyCollector GetSubShaderPropertiesForTarget(Target target, GraphDat PropertyCollector subshaderProperties = new PropertyCollector(); // Collect shader properties declared by active nodes - using (var activeNodes = PooledHashSet.Get()) + + using (Pool.HashSetPool.Get(out var activeNodes)) { if (outputNode == null) { @@ -907,7 +917,7 @@ void ProcessStackForPass(ContextData contextData, BlockFieldDescriptor[] passBlo spliceCommands.Add("InterpolatorPack", interpolatorBuilder.ToCodeBlock()); } - // Generated String Builders for all struct types + // Generated String Builders for all struct types var passStructBuilder = new ShaderStringBuilder(humanReadable: m_HumanReadable); // using (s_profileStructTypes.Auto()) { @@ -1077,7 +1087,7 @@ void ProcessStackForPass(ContextData contextData, BlockFieldDescriptor[] passBlo if (propertyBuilder.length == 0) propertyBuilder.AppendLine("// GraphProperties: "); spliceCommands.Add("GraphProperties", propertyBuilder.ToCodeBlock()); - } + } // -------------------------------------------------- // Graph Defines diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl index 7d326cef6d9..1edf07826d8 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/Editor/ShaderGraph/Includes/BuiltInCanvasPass.hlsl @@ -77,6 +77,8 @@ Varyings BuildVaryings(Attributes input) float4 clampedRect = clamp(_ClipRect, -2e10, 2e10); float2 maskUV = (input.positionOS.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy); output.texCoord1 = float4(input.positionOS.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_UIMaskSoftnessX, _UIMaskSoftnessY) + abs(pixelSize.xy))); + #else + output.texCoord1 = input.uv1; #endif #endif diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl new file mode 100644 index 00000000000..5a1bca85b00 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl @@ -0,0 +1,3 @@ +#ifdef UITK_PREVIEW +#include "UIShim.hlsl" +#endif diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl.meta b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl.meta new file mode 100644 index 00000000000..021fe44fc02 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9f12249d09c77224c8a6d6fad6e252b5 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs b/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs index 89efef4d16b..a86514ba488 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/PreviewTarget.cs @@ -6,14 +6,21 @@ namespace UnityEditor.ShaderGraph { - sealed class PreviewTarget : Target + class PreviewTarget : Target { static readonly GUID kSourceCodeGuid = new GUID("7464b9fcde08e5645a16b9b8ae1e573c"); // PreviewTarget.cs - public PreviewTarget() + private bool isUITKPreview = false; + + public PreviewTarget() : this(false) + { + } + + public PreviewTarget(bool isUITKPreview) { displayName = "Preview"; isHidden = true; + this.isUITKPreview = isUITKPreview; } public override bool IsActive() => false; @@ -22,7 +29,7 @@ public PreviewTarget() public override void Setup(ref TargetSetupContext context) { context.AddAssetDependency(kSourceCodeGuid, AssetCollection.Flags.SourceDependency); - context.AddSubShader(SubShaders.Preview); + context.AddSubShader(SubShaders.GetPreview(isUITKPreview)); } public override void GetFields(ref TargetFieldContext context) @@ -41,69 +48,80 @@ public override void GetPropertiesGUI(ref TargetPropertyGUIContext context, Acti static class SubShaders { - public static SubShaderDescriptor Preview = new SubShaderDescriptor() + public static SubShaderDescriptor GetPreview(bool isUITKPreview) { - renderQueue = "Geometry", - renderType = "Opaque", - generatesPreview = true, - passes = new PassCollection { Passes.Preview }, - }; + var preview = new SubShaderDescriptor() + { + renderQueue = "Geometry", + renderType = "Opaque", + generatesPreview = true, + passes = new PassCollection { Passes.GetPreview(isUITKPreview) }, + }; + + return preview; + } } static class Passes { - public static PassDescriptor Preview = new PassDescriptor() + public static PassDescriptor GetPreview(bool isUITKPreview) { - // Definition - referenceName = "SHADERPASS_PREVIEW", - useInPreview = true, + var pass = new PassDescriptor() + { + // Definition + referenceName = "SHADERPASS_PREVIEW", + useInPreview = true, - // Templates - passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), - sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), + // Templates + passTemplatePath = GenerationUtils.GetDefaultTemplatePath("PassMesh.template"), + sharedTemplateDirectories = GenerationUtils.GetDefaultSharedTemplateDirectories(), - // Collections - structs = new StructCollection - { - { Structs.Attributes }, - { StructDescriptors.PreviewVaryings }, - { Structs.SurfaceDescriptionInputs }, - { Structs.VertexDescriptionInputs }, - }, - fieldDependencies = FieldDependencies.Default, - pragmas = new PragmaCollection - { - { Pragma.Vertex("vert") }, - { Pragma.Fragment("frag") }, - }, - defines = new DefineCollection - { - { KeywordDescriptors.PreviewKeyword, 1 }, - }, - includes = new IncludeCollection - { - // Pre-graph - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl", IncludeLocation.Pregraph }, // TODO: put this on a conditional - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl", IncludeLocation.Pregraph }, - { "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShim.hlsl", IncludeLocation.Pregraph }, - - // Post-graph - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewVaryings.hlsl", IncludeLocation.Postgraph }, - { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewPass.hlsl", IncludeLocation.Postgraph }, - } - }; + // Collections + structs = new StructCollection + { + { Structs.Attributes }, + { StructDescriptors.PreviewVaryings }, + { Structs.SurfaceDescriptionInputs }, + { Structs.VertexDescriptionInputs }, + }, + fieldDependencies = FieldDependencies.Default, + pragmas = new PragmaCollection + { + { Pragma.Vertex("vert") }, + { Pragma.Fragment("frag") }, + }, + defines = new DefineCollection + { + { KeywordDescriptors.PreviewKeyword, 1 }, + { KeywordDescriptors.UITKPreviewKeyword, isUITKPreview ? 1 : 0 } + }, + includes = new IncludeCollection + { + // Pre-graph + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/TextureStack.hlsl", IncludeLocation.Pregraph }, // TODO: put this on a conditional + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/NormalSurfaceGradient.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/Texture.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/UnityInstancing.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariables.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/ShaderVariablesFunctions.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/Functions.hlsl", IncludeLocation.Pregraph }, + { "Packages/com.unity.shadergraph/Editor/Generation/Targets/BuiltIn/ShaderLibrary/Shim/UIShimPreview.hlsl", IncludeLocation.Pregraph }, + + // Post-graph + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewVaryings.hlsl", IncludeLocation.Postgraph }, + { "Packages/com.unity.shadergraph/ShaderGraphLibrary/PreviewPass.hlsl", IncludeLocation.Postgraph }, + } + }; + + return pass; + } } - static class StructDescriptors + protected static class StructDescriptors { public static StructDescriptor PreviewVaryings = new StructDescriptor() { @@ -133,7 +151,7 @@ static class StructDescriptors }; } - static class KeywordDescriptors + protected static class KeywordDescriptors { public static KeywordDescriptor PreviewKeyword = new KeywordDescriptor() { @@ -144,6 +162,15 @@ static class KeywordDescriptors scope = KeywordScope.Global, stages = KeywordShaderStage.All, }; + public static KeywordDescriptor UITKPreviewKeyword = new KeywordDescriptor() + { + displayName = "UITK Preview", + referenceName = "UITK_PREVIEW", + type = KeywordType.Boolean, + definition = KeywordDefinition.MultiCompile, + scope = KeywordScope.Global, + stages = KeywordShaderStage.All, + }; } } } diff --git a/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs b/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs index 321ad95f8be..d69a5deb115 100644 --- a/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs +++ b/Packages/com.unity.shadergraph/Editor/Generation/Targets/UITK/UISubTarget.cs @@ -218,6 +218,9 @@ public string GetValidatorKey() return "UISubTarget"; } + const string kUVErrorMessageNode = "UI Material does not support UV1-7. Consider using 'UV0'."; + const string kUVErrorMessageSubGraph = "UI Material does not support UV1-7. Consider using 'UV0' in the subgraph."; + public INodeValidationExtension.Status GetValidationStatus(AbstractMaterialNode node, out string msg) { // Make sure node is in our graph first @@ -227,6 +230,12 @@ public INodeValidationExtension.Status GetValidationStatus(AbstractMaterialNode return INodeValidationExtension.Status.None; } + // Clear all Warning/Error message from other providers. + // The message from the graph (when loading the graph) will not be removed + // since it's not the same provider as the UISubTarget. It then stays present + // even if the UV0 is selected. + node.owner.messageManager.ClearNodeFromOtherProvider(this, new[] { node }); + foreach (var item in node.owner.activeTargets) { if (item.prefersUITKPreview) @@ -235,16 +244,6 @@ public INodeValidationExtension.Status GetValidationStatus(AbstractMaterialNode { return INodeValidationExtension.Status.Warning; } - - UVNode uvNode = node as UVNode; - if (uvNode != null) - { - if (uvNode.uvChannel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) - { - msg = "UI Material does not support UV1-7. Consider using 'UV0'."; - return INodeValidationExtension.Status.Warning; - } - } } } @@ -261,7 +260,17 @@ private bool ValidateUV(AbstractMaterialNode node, out string warningMessage) { if (uvSlot.channel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) { - warningMessage = "UI Material does not support UV1-7. Consider using 'UV0'."; + warningMessage = kUVErrorMessageNode; + return true; + } + } + + UVNode uvNode = node as UVNode; + if (uvNode != null) + { + if (uvNode.uvChannel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) + { + warningMessage = kUVErrorMessageNode; return true; } } @@ -283,7 +292,7 @@ public override bool ValidateNodeCompatibility(AbstractMaterialNode node, out st { if (uvSlot.channel != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) { - warningMessage = "UI Material does not support UV1-7. Consider using 'UV0'."; + warningMessage = kUVErrorMessageNode; return true; } } @@ -303,7 +312,7 @@ public override bool ValidateNodeCompatibility(AbstractMaterialNode node, out st { if (item != UnityEditor.ShaderGraph.Internal.UVChannel.UV0) { - warningMessage = "UI Material does not support UV1-7. Consider using 'UV0' in the subgraph."; + warningMessage = kUVErrorMessageSubGraph; return true; } } diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs index f383ea34bbc..e51b78257a6 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderGraphImporterEditor.cs @@ -140,6 +140,7 @@ GraphData GetGraphData(AssetImporter importer) GUIUtility.systemCopyBuffer = generator.generatedShader; } + EditorGUI.BeginDisabled(EditorApplication.isPlaying); EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(serializedObject.FindProperty(ShaderGraphImporter.UseAsTemplateFieldName)); @@ -155,6 +156,7 @@ GraphData GetGraphData(AssetImporter importer) EditorGUILayout.PropertyField(serializedObject.FindProperty(ShaderGraphImporter.TemplateFieldName)); needsSaveMetaFile |= EditorGUI.EndChangeCheck(); } + EditorGUI.EndDisabled(); if (materialEditor) { diff --git a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs index bc4907b071a..dcf4f63e281 100644 --- a/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs +++ b/Packages/com.unity.shadergraph/Editor/Importers/ShaderSubGraphImporter.cs @@ -194,8 +194,7 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph, ShaderGraphImp asset.documentationPath = documentationPath; var outputNode = graph.outputNode; - - var outputSlots = PooledList.Get(); + var outputSlots = UnityEngine.Pool.ListPool.Get(); outputNode.GetInputSlots(outputSlots); List nodes = new List(); @@ -287,7 +286,7 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph, ShaderGraphImp { asset.isValid = false; registry.ProvideFunction(asset.functionName, sb => { }); - outputSlots.Dispose(); + UnityEngine.Pool.ListPool.Release(outputSlots); return; } @@ -446,7 +445,7 @@ static void ProcessSubGraph(SubGraphAsset asset, GraphData graph, ShaderGraphImp } asset.WriteData(orderedProperties, keywordCollector.keywords, graph.dropdowns, collector.properties, outputSlots, graph.unsupportedTargets); - outputSlots.Dispose(); + UnityEngine.Pool.ListPool.Release(outputSlots); } static void GatherDescendentsFromGraph(GUID rootAssetGuid, out bool containsCircularDependency, out HashSet descendentGuids) diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/CommonShaderObjects.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/CommonShaderObjects.cs.meta deleted file mode 100644 index 32e5ef34f63..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/CommonShaderObjects.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 6c992aa7356b6d242ad431b5ab535c19 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionNode.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionNode.cs index de978ed7b1e..e84944c0719 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionNode.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionNode.cs @@ -1,8 +1,5 @@ - using System; using UnityEditor.ShaderGraph.Drawing.Controls; -using UnityEditor.ShaderGraph.Internal; -using UnityEngine; namespace UnityEditor.ShaderGraph.ProviderSystem { diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionProvider.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionProvider.cs.meta deleted file mode 100644 index 425f937b003..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionProvider.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 854d9d5b7499b4de8b33efe89dc97d2e \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/FunctionHeader.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/FunctionHeader.cs deleted file mode 100644 index 999c0c495aa..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/FunctionHeader.cs +++ /dev/null @@ -1,80 +0,0 @@ - -namespace UnityEditor.ShaderGraph.ProviderSystem -{ - // A "Header" object is an abstraction layer that interprets domain/context-free - // information from a ShaderObject (in this case a function) and translates it into - // domain specific information-- in this case, the Shader Graph tooling and conventions. - internal struct FunctionHeader - { - readonly internal bool isValid; - - readonly internal string referenceName; - readonly internal string displayName; - readonly internal string uniqueName; - readonly internal string tooltip; - - readonly internal IShaderType returnType; - internal bool hasReturnType => returnType.Name != "void"; - readonly internal string returnDisplayName; - - readonly internal string category; - - readonly internal string[] searchTerms; - - internal FunctionHeader(IProvider provider) - { - referenceName = null; - returnType = null; - displayName = null; - category = null; - searchTerms = null; - returnDisplayName = null; - uniqueName = null; - tooltip = null; - - isValid = provider != null && provider.Definition != null; - - if (!isValid) - return; - - var func = provider.Definition; - var path = AssetDatabase.GUIDToAssetPath(provider.AssetID); - - referenceName = func.Name; - returnType = func.ReturnType; - - if (!func.Hints.TryGetValue(Hints.Common.kDisplayName, out displayName)) - displayName = ObjectNames.NicifyVariableName(referenceName); - - if (!func.Hints.TryGetValue(Hints.Func.kSearchName, out uniqueName)) - uniqueName = ShaderObjectUtils.QualifySignature(func, false, true); - - - if (!func.Hints.TryGetValue(Hints.Func.kCategory, out category)) - { - // try to use a namespace if a user didn't provide a category. - bool hasNamespace = false; - foreach (var name in func.Namespace) - { - if (!hasNamespace) - category = "Reflected by Namespace"; - hasNamespace = true; - category += $"/{name}"; - } - // if there was no namespace, use the file path instead. - if (!hasNamespace) - { - category = $"Reflected by Path/{path}"; - } - - } - - if (func.Hints.TryGetValue(Hints.Func.kSearchName, out var terms)) - searchTerms = HeaderUtils.LazyTokenString(terms); - else searchTerms = new[] { referenceName }; - - if (!func.Hints.TryGetValue(Hints.Func.kReturnDisplayName, out returnDisplayName)) - returnDisplayName = "Out"; - } - } -} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/FunctionHeader.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/FunctionHeader.cs.meta deleted file mode 100644 index 6546dea4fda..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/FunctionHeader.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: a49239ad21003d64db1f49d00da3f871 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header.meta new file mode 100644 index 00000000000..b1022beeb0f --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9181c578b5a41418bbb0056172a05e4f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/CommonHints.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/CommonHints.cs new file mode 100644 index 00000000000..c394c2a9f94 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/CommonHints.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph.ProviderSystem.Hints +{ + internal static class Common + { + internal const string kDisplayName = "sg:DisplayName"; + internal const string kTooltip = "sg:Tooltip"; + } + + internal class DisplayName : IStrongHint where T : IShaderObject + { + public string Key { get; private set; } + public bool AlwaysProcess => true; + public IReadOnlyCollection Synonyms { get; } = new string[] { "Label", "Title" }; + string fallback; + internal DisplayName(string name = Common.kDisplayName, string fallback = null) { Key = name; this.fallback = fallback; } + public bool Process(bool found, string rawValue, T obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = found ? rawValue : fallback ?? obj.Name; + return true; // We always resolve a display name. + } + } + + internal class Tooltip : IStrongHint where T : IShaderObject + { + public string Key { get; private set; } + public IReadOnlyCollection Synonyms { get; } = new [] { "summary" }; + internal Tooltip(string name = Common.kTooltip) { Key = name; } + public bool Process(bool found, string rawValue, T obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + return found; + } + } + + internal class Flag : IStrongHint where T : IShaderObject + { + public string Key { get; private set; } + public IReadOnlyCollection Conflicts { get; private set; } + public IReadOnlyCollection Synonyms { get; private set; } + + internal Flag(string name) { Key = name; Conflicts = null; } + internal Flag(string name, string conflict) { Key = name; Conflicts = new[] { conflict }; } + internal Flag(string name, string[] conflicts) { Key = name; Conflicts = conflicts; } + internal Flag(string name, string[] conflicts, string[] synonyms) + { + Key = name; + Conflicts = conflicts; + Synonyms = synonyms; + } + + public bool Process(bool found, string rawValue, T obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + if (!string.IsNullOrWhiteSpace(rawValue)) + msg = $"Expects an empty argument string."; + return found; + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/CommonHints.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/CommonHints.cs.meta new file mode 100644 index 00000000000..9c0e2346cd7 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/CommonHints.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 243f79ed5c3a949dea27a2c712baeebd \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHeader.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHeader.cs new file mode 100644 index 00000000000..fb10ff4331b --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHeader.cs @@ -0,0 +1,69 @@ +namespace UnityEditor.ShaderGraph.ProviderSystem +{ + internal class FunctionHeader : StrongHeader + { + internal string referenceName { get; private set; } + + internal string displayName { get; private set; } + internal string tooltip { get; private set; } + + internal string returnDisplayName { get; private set; } + internal string returnTooltip { get; private set; } + internal IShaderType returnType { get; private set; } + internal bool hasReturnValueType => returnType.Name != "void"; + + internal string searchName { get; private set; } + internal string[] searchTerms { get; private set; } + internal string searchCategory { get; private set; } + + internal ParameterHeader returnHeader { get; private set; } + + internal bool allowPrecision { get; private set; } + + private static HintRegistry s_HintRegistry; + protected override HintRegistry GetHintRegistry() + { + if (s_HintRegistry == null) + { + s_HintRegistry = new(); + s_HintRegistry.RegisterStrongHint(new Hints.ProviderKey()); + + s_HintRegistry.RegisterStrongHint(new Hints.DisplayName()); + s_HintRegistry.RegisterStrongHint(new Hints.Tooltip()); + + // Duplicate Synonyms are getting registered and we aren't handling conflicts; + // but we should allow multimapping! + s_HintRegistry.RegisterStrongHint(new Hints.DisplayName(Hints.Func.kReturnDisplayName, "Out")); + s_HintRegistry.RegisterStrongHint(new Hints.Tooltip(Hints.Func.kReturnTooltip)); + + s_HintRegistry.RegisterStrongHint(new Hints.SearchName()); + s_HintRegistry.RegisterStrongHint(new Hints.SearchTerms()); + s_HintRegistry.RegisterStrongHint(new Hints.SearchCategory()); + + s_HintRegistry.RegisterStrongHint(new Hints.Flag(Hints.Func.kPrecision, null, new string[] { "Precision" })); + } + return s_HintRegistry; + } + + // Read processed data and make it more accessible to work with. + protected override void OnProcess(IShaderFunction func, IProvider provider) + { + referenceName = func.Name; + returnType = func.ReturnType; + + displayName = Get(Hints.Common.kDisplayName); + tooltip = Get(Hints.Common.kTooltip); + + returnDisplayName = Get(Hints.Func.kReturnDisplayName); + returnTooltip = Get(Hints.Func.kReturnTooltip); + + searchName = Get(Hints.Func.kSearchName); + searchTerms = Get(Hints.Func.kSearchTerms); + searchCategory = Get(Hints.Func.kSearchCategory); + + allowPrecision = Has(Hints.Func.kPrecision); + + returnHeader = new ParameterHeader(returnDisplayName, func.ReturnType, returnTooltip, provider); + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHeader.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHeader.cs.meta new file mode 100644 index 00000000000..9a87e42d068 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHeader.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 58b9d763af91544dc85fbb161b64d9c0 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHints.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHints.cs new file mode 100644 index 00000000000..f907fc18b36 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHints.cs @@ -0,0 +1,108 @@ +using System.Text; +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph.ProviderSystem.Hints +{ + internal static class Func + { + internal const string kProviderKey = "sg:ProviderKey"; + + internal const string kReturnDisplayName = "sg:ReturnDisplayName"; + + internal const string kSearchTerms = "sg:SearchTerms"; + internal const string kSearchName = "sg:SearchName"; + internal const string kSearchCategory = "sg:SearchCategory"; + + internal const string kPrecision = "sg:DynamicPrecision"; + + // Not yet implemented. + internal const string kGroupKey = "sg:GroupKey"; + internal const string kReturnTooltip = "sg:ReturnTooltip"; + internal const string kDocumentationLink = "sg:HelpURL"; + + // ProviderKey associated hints, Not yet implemented. + internal const string kDeprecated = "sg:Deprecated"; + internal const string kObsolete = "sg:Obsolete"; + internal const string kVersion = "sg:Version"; + } + + class ProviderKey : IStrongHint + { + public string Key => Func.kProviderKey; + public bool AlwaysProcess => true; + public bool AllowDisqualifiedSynonyms => false; + public bool Process(bool found, string rawValue, IShaderFunction obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + string sourcePath = AssetDatabase.GUIDToAssetPath(provider.AssetID); + + value = provider.ProviderKey; + msg = !found + ? $"Expected; but none found for '{provider.ProviderKey}' in '{sourcePath}'." + : null; + + return true; + } + } + + class SearchName : IStrongHint + { + public string Key => Func.kSearchName; + public bool AlwaysProcess => true; + public bool Process(bool found, string rawValue, IShaderFunction obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = found ? rawValue : ShaderObjectUtils.QualifySignature(obj, false, true); + return true; + } + } + + class SearchTerms : IStrongHint + { + public string Key => Func.kSearchTerms; + public bool AlwaysProcess => true; + public bool Process(bool found, string rawValue, IShaderFunction obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = found ? HeaderUtils.LazyTokenString(rawValue) : new string[] { obj.Name }; + return true; + } + } + + class SearchCategory : IStrongHint + { + public string Key => Func.kSearchCategory; + public bool AlwaysProcess => true; + public IReadOnlyCollection Synonyms { get; } = new[] { "Category" }; + public bool Process(bool found, string rawValue, IShaderFunction obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + if (found) + { + value = rawValue; + } + else + { + StringBuilder catsb = new(); + foreach(var name in obj.Namespace) + { + catsb.Append($"/{name}"); + } + var category = catsb.ToString(); + if (!string.IsNullOrWhiteSpace(category)) + { + value = $"Reflected by Namespace{category}"; + } + else if (provider.AssetID != default) + { + var path = AssetDatabase.GUIDToAssetPath(provider.AssetID); + value = $"Reflected by Path/{path}"; + } + else + { + value = "Uncategorized"; + } + } + return true; + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHints.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHints.cs.meta new file mode 100644 index 00000000000..d5246227c38 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/FunctionHints.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f51d58a379852433783c60d784f44626 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/HeaderUtils.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/HeaderUtils.cs new file mode 100644 index 00000000000..d979523cd44 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/HeaderUtils.cs @@ -0,0 +1,376 @@ +using UnityEngine; +using UnityEditor.Graphing; +using System.Collections.Generic; +using System; + +namespace UnityEditor.ShaderGraph.ProviderSystem +{ + internal static class HeaderUtils + { + internal static string ToShaderType(this MaterialSlot slot) + { + if (slot is ExternalMaterialSlot eslot) + return eslot.TypeName; + + return slot.concreteValueType.ToShaderString(); + } + + internal static bool IsNumeric(string typeName) + { + return TryParseTypeInfo(typeName, out _, out _, out _, out _, out _, out _, out _); + } + + internal static bool TryParseTypeInfo( + string type, + out string prim, + out bool isScalar, + out bool isVector, + out bool isMatrix, + out int rows, + out int cols, + out int length) + { + prim = null; + isScalar = false; + isVector = false; + isMatrix = false; + rows = -1; + cols = -1; + length = -1; + + // TODO: Array support isn't established yet, if we support multidim this wouldn't work. + if (type.Contains('[')) + return false; + + + if (type.StartsWith("uint")) prim = "uint"; + if (type.StartsWith("int")) prim = "int"; + if (type.StartsWith("bool")) prim = "bool"; + if (type.StartsWith("half")) prim = "half"; + if (type.StartsWith("float")) prim = "float"; + + if (prim == null) + return false; + + if (type == prim) + return isScalar = true; + + var remainder = type.Substring(prim.Length); + + if (remainder.Length == 1) + { + return isVector = int.TryParse(remainder, out rows) && rows >= 1 && rows <= 4; + } + if (remainder.Length == 3) + { + return isMatrix + = int.TryParse(remainder.Substring(0, 1), out rows) && rows >= 1 && rows <= 4 + && int.TryParse(remainder.Substring(2, 1), out cols) && cols >= 1 && cols <= 4; + } + return false; + } + + internal static bool TryCast(string shaderType, float[] values, out T value, T fallback = default) + { + try + { + return Cast(shaderType, values, out value, fallback); + } + catch + { + value = default; + return false; + } + } + + private static bool Cast(string shaderType, float[] values, out T value, T fallback = default) + { + object obj = default; + value = fallback; + + if (values == null || values.Length == 0) + return false; + + float[] v = new float[16]; + for (int i = 0; i < values.Length; ++i) + v[i] = values[i]; + + if (!TryParseTypeInfo(shaderType, out string prim, out bool isScalar, out bool isVector, out bool isMatrix, out int rows, out int cols, out int length)) + return false; + + if (isScalar || isVector && rows == 1 || isMatrix && rows == 1 && cols == 1) + { + var fv = v[0]; + + switch (prim) + { + case "bool": obj = fv != 0; break; + case "uint": obj = fv; break; + case "int": obj = fv; break; + case "float": + case "half": obj = fv; break; + default: return false; + } + } + if (isVector) + { + switch (rows) + { + case 2: obj = new Vector2(v[0], v[1]); break; + case 3: obj = new Vector3(v[0], v[1], v[2]); break; + case 4: obj = new Vector4(v[0], v[1], v[2], v[3]); break; + default: return false; + } + + } + if (isMatrix) + { + Matrix4x4 m = new(); + for (int i = 0; i < cols * rows; ++i) + { + // TODO: Validate with GTK + m[i % rows + rows * (i / rows)] = v[i]; + } + } + + value = (T)obj; + return true; + } + + internal static MaterialSlot MakeSlotFromParameter(ParameterHeader header, int slotId, SlotType dir) + { + MaterialSlot slot = null; + + Enum.TryParse(header.defaultString, true, out var defaultUVChannel); + if (!Enum.TryParse(header.defaultString, true, out var defaultCoordinateSpace)) + defaultCoordinateSpace = Internal.CoordinateSpace.Object; + Enum.TryParse(header.defaultString, true, out var defaultScreenSpaceType); + + // absolute world only works for position. + if (defaultCoordinateSpace == Internal.CoordinateSpace.AbsoluteWorld && header.Referable != Hints.Param.Ref.kPosition) + defaultCoordinateSpace = Internal.CoordinateSpace.Object; + + // Screen doesn't work for any of the Space Slots-- _why do they use this enum?_ + if (defaultCoordinateSpace == Internal.CoordinateSpace.Screen) + defaultCoordinateSpace = Internal.CoordinateSpace.Object; + + if (header.isReferable && dir == SlotType.Input) + { + switch(header.Referable) + { + case Hints.Param.Ref.kUV: + slot = new UVMaterialSlot(slotId, header.displayName, header.referenceName, defaultUVChannel); + break; + case Hints.Param.Ref.kPosition: + slot = new PositionMaterialSlot(slotId, header.displayName, header.referenceName, defaultCoordinateSpace); + break; + case Hints.Param.Ref.kNormal: + slot = new NormalMaterialSlot(slotId, header.displayName, header.referenceName, defaultCoordinateSpace); + break; + case Hints.Param.Ref.kTangent: + slot = new TangentMaterialSlot(slotId, header.displayName, header.referenceName, defaultCoordinateSpace); + break; + case Hints.Param.Ref.kBitangent: + slot = new BitangentMaterialSlot(slotId, header.displayName, header.referenceName, defaultCoordinateSpace); + break; + case Hints.Param.Ref.kVertexColor: + slot = new VertexColorMaterialSlot(slotId, header.displayName, header.referenceName); + break; + case Hints.Param.Ref.kViewDirection: + slot = new ViewDirectionMaterialSlot(slotId, header.displayName, header.referenceName, defaultCoordinateSpace); + break; + case Hints.Param.Ref.kScreenPosition: + slot = new ScreenPositionMaterialSlot(slotId, header.displayName, header.referenceName, defaultScreenSpaceType); + break; + + } + } + if (slot == null) + { + if (header.isDynamic) + { + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var v4, Vector4.zero); + slot = new DynamicVectorMaterialSlot(slotId, header.displayName, header.referenceName, dir, v4); + } + else if (header.isDropdown && dir == SlotType.Input) + { + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asIdx, 0.0f); + slot = new Vector1MaterialEnumSlot(slotId, header.displayName, header.referenceName, dir, header.options, asIdx); + } + else if (header.isSlider && dir == SlotType.Input) + { + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asRng, 0); + slot = new Vector1MaterialRangeSlot(slotId, header.displayName, header.referenceName, dir, asRng, new Vector2(header.sliderMin, header.sliderMax)); + } + else switch (header.typeName) + { + case "uint1": + case "uint": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asUint, 0u); + slot = new Vector1MaterialIntegerSlot(slotId, header.displayName, header.referenceName, dir, asUint, unsigned: true); break; + case "int1": + case "int": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asInt, 0); + slot = new Vector1MaterialIntegerSlot(slotId, header.displayName, header.referenceName, dir, asInt); break; + case "half": + case "half1": + case "float1": + case "float": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asFloat, 0.0f); + slot = new Vector1MaterialSlot(slotId, header.displayName, header.referenceName, dir, asFloat); break; + case "bool1": + case "bool": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asBool, false); + slot = new BooleanMaterialSlot(slotId, header.displayName, header.referenceName, dir, asBool); break; + case "half2": + case "float2": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asV2, Vector2.zero); + slot = new Vector2MaterialSlot(slotId, header.displayName, header.referenceName, dir, asV2); break; + case "half3": + case "float3": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asV3, Vector3.zero); + slot = !header.isColor + ? new Vector3MaterialSlot(slotId, header.displayName, header.referenceName, dir, asV3) + : new ColorRGBMaterialSlot(slotId, header.displayName, header.referenceName, dir, new Vector4(asV3.x, asV3.y, asV3.z, 1), Internal.ColorMode.Default); + break; + case "half4": + case "float4": + HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asV4, header.isColor ? new Vector4(0, 0, 0, 1) : Vector4.zero); + + slot = header.isColor + ? new ColorRGBAMaterialSlot(slotId, header.displayName, header.referenceName, dir, asV4) + : new Vector4MaterialSlot(slotId, header.displayName, header.referenceName, dir, asV4); + + break; + case "half2x2": + case "float2x2": slot = new Matrix2MaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + case "half3x3": + case "float3x3": slot = new Matrix3MaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + case "half4x4": + case "float4x4": slot = new Matrix4MaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + + case "SamplerState": + case "UnitySamplerState": slot = new SamplerStateMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + case "Texture2D": + case "UnityTexture2D": + slot = dir == SlotType.Input + ? new Texture2DInputMaterialSlot(slotId, header.displayName, header.referenceName) + : new Texture2DMaterialSlot(slotId, header.displayName, header.referenceName, dir); + break; + case "Texture2DArray": + case "UnityTexture2DArray": + slot = dir == SlotType.Input + ? new Texture2DArrayInputMaterialSlot(slotId, header.displayName, header.referenceName) + : new Texture2DArrayMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + case "TextureCube": + case "UnityTextureCube": + slot = dir == SlotType.Input + ? new CubemapInputMaterialSlot(slotId, header.displayName, header.referenceName) + : new CubemapMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + case "Texture3D": + case "UnityTexture3D": + slot = dir == SlotType.Input + ? new Texture3DInputMaterialSlot(slotId, header.displayName, header.referenceName) + : new Texture3DMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; + default: + slot = new ExternalMaterialSlot(slotId, header.displayName, header.referenceName, header.externalQualifiedTypeName, dir, header.defaultString); + break; + } + } + slot.hideConnector = header.isStatic && dir == SlotType.Input; + slot.hidden = header.isLocal; + slot.bareResource = header.isBareResource; + return slot; + } + + internal static float[] LazyTokenFloat(string arg) + { + var tokens = LazyTokenize(arg); + List asfloat = new(); + + foreach (var token in tokens) + if (float.TryParse(token, out float r)) + asfloat.Add(r); + + return asfloat.ToArray(); + } + + internal static string[] LazyTokenString(string arg) + { + List tokens = new(LazyTokenize(arg)); + return tokens.ToArray(); + } + + private static IEnumerable LazyTokenize(string arg) + { + foreach (var e in arg.Split(',')) + { + var result = e.Trim(); + if (!string.IsNullOrWhiteSpace(result)) + yield return e.Trim(); + } + } + + private static IShaderType ApplyLegacy(IShaderType type, string precisionToken, int dynamicLength) + { + var baseType = type.Name.Split('[')[0]; + + var newType = baseType; + + // TODO: DYNAMIC HINT only supports float, float2, float3, float4 and half, half2, half3, half4 + if (dynamicLength >= 1 && dynamicLength <= 4) + { + string halfType = $"half{(dynamicLength == 1 ? null : dynamicLength)}"; + string floatType = $"float{(dynamicLength == 1 ? null : dynamicLength)}"; + newType = System.Text.RegularExpressions.Regex.Replace(newType, "half[1-4]|half", halfType); + newType = System.Text.RegularExpressions.Regex.Replace(newType, "float[1-4]|float", floatType); + } + + if (precisionToken != null) + newType = newType.Replace("float", precisionToken).Replace("half", precisionToken); + + return new ShaderType(type.Name.Replace(baseType, newType)); + } + + internal static bool TryApplyLegacy(IShaderFunction func, FunctionHeader funcHeader, IReadOnlyDictionary paramHeaders, string precisionToken, int dynamicLength, out IShaderFunction result) + { + List fields = new(); + result = null; + + bool applyPrecision = funcHeader.allowPrecision; + bool anyDynamics = false; + + Debug.Assert(dynamicLength >= 0); + + foreach(var param in func.Parameters) + { + bool applyDynamics = paramHeaders.TryGetValue(param.Name, out var paramHeader) && paramHeader.isDynamic; + anyDynamics |= applyDynamics; + + var legacyType = ApplyLegacy(param.ShaderType, applyPrecision ? precisionToken : null, applyDynamics ? dynamicLength : 0); + + var field = new ShaderField(param.Name, param.IsInput, param.IsOutput, legacyType, param.Hints); + + fields.Add(field); + } + + if (!anyDynamics && !applyPrecision) + { + result = func; + return false; + } + + List namespaces = new(); + namespaces.AddRange(func.Namespace); + if (applyPrecision || anyDynamics) + namespaces.Add("unity_sg_generated"); + + string funcName = $"{func.Name}{(applyPrecision ? $"_{precisionToken}" : null)}{(anyDynamics ? dynamicLength : null)}"; + + // Dynamic typing isn't supported on return values. + IShaderType returnType = ApplyLegacy(func.ReturnType, applyPrecision ? precisionToken : null, 0); + result = new ShaderFunction(funcName, namespaces, fields, returnType, func.FunctionBody, func.Hints); + return true; + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/HeaderUtils.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/HeaderUtils.cs.meta new file mode 100644 index 00000000000..ff259a48cc5 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/HeaderUtils.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9fe94b29e1463438e8bc28a5e7905e1d \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHeader.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHeader.cs new file mode 100644 index 00000000000..7728955f292 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHeader.cs @@ -0,0 +1,150 @@ +using System.Collections.Generic; + +namespace UnityEditor.ShaderGraph.ProviderSystem +{ + internal class ParameterHeader : StrongHeader + { + internal string referenceName { get; private set; } + internal IShaderType shaderType { get; private set; } + internal string typeName => shaderType.Name; + + internal string displayName { get; private set; } + internal string tooltip { get; private set; } + + internal bool isInput { get; private set; } + internal bool isOutput { get; private set; } + + internal bool isColor { get; private set; } + + internal bool isStatic { get; private set; } + internal bool isLocal { get; private set; } + + internal bool isDropdown { get; private set; } + internal string[] options { get; private set; } + + internal bool isSlider { get; private set; } + internal float sliderMin { get; private set; } + internal float sliderMax { get; private set; } + + internal float[] defaultValue { get; private set; } + internal string defaultString { get; private set; } + + internal string externalQualifiedTypeName { get; private set; } + + internal bool isLiteral { get; private set; } + + internal bool isDynamic { get; private set; } + + internal bool isBareResource { get; private set; } + + internal bool isReferable { get; private set; } + internal string Referable { get; private set; } + + internal bool isLinkage { get; private set; } + internal string linkTarget { get; private set; } + + private static HintRegistry s_HintRegistry; + protected override HintRegistry GetHintRegistry() + { + if (s_HintRegistry == null) + { + s_HintRegistry = new(); + s_HintRegistry.RegisterStrongHint(new Hints.DisplayName()); + s_HintRegistry.RegisterStrongHint(new Hints.Tooltip()); + + s_HintRegistry.RegisterStrongHint(new Hints.Flag(Hints.Param.kLocal, new string[] { Hints.Param.kAccessModifier })); + + s_HintRegistry.RegisterStrongHint(new Hints.Literal()); + s_HintRegistry.RegisterStrongHint(new Hints.Static()); + s_HintRegistry.RegisterStrongHint(new Hints.Color()); + s_HintRegistry.RegisterStrongHint(new Hints.Range()); + s_HintRegistry.RegisterStrongHint(new Hints.Dropdown()); + s_HintRegistry.RegisterStrongHint(new Hints.Default()); + s_HintRegistry.RegisterStrongHint(new Hints.External()); + s_HintRegistry.RegisterStrongHint(new Hints.Referable()); + s_HintRegistry.RegisterStrongHint(new Hints.Dynamic()); + s_HintRegistry.RegisterStrongHint(new Hints.Linkage()); + } + return s_HintRegistry; + } + + // Read processed data and make it more accessible to work with. + protected override void OnProcess(IShaderField param, IProvider provider) + { + referenceName = param.Name; + + isInput = param.IsInput; + isOutput = param.IsOutput; + shaderType = param.ShaderType; + + // TODO: improve type handling. + string typeTest = shaderType.Name.ToLowerInvariant(); + bool isSampler = typeTest.Contains("sampler"); + bool isTexture = typeTest.Contains("texture"); + isBareResource = !typeTest.Contains("unity") && (isSampler || isTexture); + + displayName = Get(Hints.Common.kDisplayName); + tooltip = Get(Hints.Common.kTooltip); + + isStatic = this.Has(Hints.Param.kStatic); + isLocal = this.Has(Hints.Param.kLocal); + + if (isDropdown = this.Has(Hints.Param.kDropdown)) + options = this.Get(Hints.Param.kDropdown); + + isColor = this.Has(Hints.Param.kColor); + + if (isSlider = this.Has(Hints.Param.kRange)) + { + var range = this.Get(Hints.Param.kRange); + sliderMin = range[0]; + sliderMax = range[1]; + } + + if (this.Has(Hints.Param.kDefault)) + { + defaultString = this.Get(Hints.Param.kDefault); + defaultValue = HeaderUtils.LazyTokenFloat(defaultString); + } + + externalQualifiedTypeName = typeName; + var externalNamespace = Get(Hints.Param.kExternal); + if (!string.IsNullOrWhiteSpace(externalNamespace)) + externalQualifiedTypeName = $"{externalNamespace}::{typeName}"; + + isLiteral = Has(Hints.Param.kLiteral); + + if (isReferable = Has(Hints.Param.kReferable)) + { + Referable = Get(Hints.Param.kReferable); + } + + isDynamic = Has(Hints.Param.kDynamic); + + if (isLinkage = Has(Hints.Param.kLinkage)) + { + linkTarget = Get(Hints.Param.kLinkage); + isLocal = true; + } + + } + + internal ParameterHeader(IShaderField param, IProvider provider) + { + Process(param, provider); + } + + // For returns. + internal ParameterHeader(string displayName, IShaderType shaderType, string tooltip, IProvider provider) + { + var hints = new Dictionary() { + { Hints.Common.kDisplayName, displayName }, + { Hints.Common.kTooltip, tooltip }, + }; + + var field = new ShaderField("__UNITY_SHADERGRAPH_UNUSED", false, true, shaderType, hints); + + Process(field, provider); + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHeader.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHeader.cs.meta new file mode 100644 index 00000000000..6da3b5b9ceb --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHeader.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 73f8700d5e86e4ec397ed9c8ef0ffe90 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHints.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHints.cs new file mode 100644 index 00000000000..2ffb77fb2db --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHints.cs @@ -0,0 +1,439 @@ +using System.Collections.Generic; +using UnityEngine; + +namespace UnityEditor.ShaderGraph.ProviderSystem.Hints +{ + internal static class Param + { + internal const string kAccessModifier = "AccessModifier"; + internal const string kCustomEditor = "CustomEditor"; + + internal const string kStatic = "sg:Static"; + internal const string kLocal = "sg:Local"; + internal const string kLiteral = "sg:Literal"; + internal const string kColor = "sg:Color"; + internal const string kRange = "sg:Range"; + internal const string kDropdown = "sg:Dropdown"; + internal const string kDefault = "sg:Default"; + internal const string kExternal = "sg:External"; + + internal const string kSetting = "sg:Setting"; + internal const string kLinkage = "sg:Linkage"; + internal const string kDynamic = "sg:DynamicVector"; + internal const string kReferable = "sg:Referable"; + + internal static class Ref + { + internal const string kUV = "UV"; + internal const string kPosition = "Position"; + internal const string kNormal = "Normal"; + internal const string kBitangent = "Bitangent"; + internal const string kTangent = "Tangent"; + internal const string kViewDirection = "ViewDirection"; + internal const string kScreenPosition = "ScreenPosition"; + internal const string kVertexColor = "VertexColor"; + } + } + + internal class Range : IStrongHint + { + public string Key => Param.kRange; + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kCustomEditor }; + public IReadOnlyCollection Synonyms { get; } = new string[] { "Slider" }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + if (!found) + return false; + + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + if (obj.ShaderType.Name != "half" && obj.ShaderType.Name != "float") + { + msg = $"Expected floating point scalar, but found '{obj.ShaderType.Name}'."; + return false; + + } + + float min = 0; + float max = 1; + + if (string.IsNullOrWhiteSpace(rawValue)) + { + value = new float[] { min, max }; + return true; + } + + float[] values = HeaderUtils.LazyTokenFloat(rawValue); + + if (values.Length > 2 || !string.IsNullOrEmpty(rawValue) && values.Length == 0) + { + msg = $"Expected 0, 1, or 2 floating point values, but found '{values.Length}'."; + value = new float[] { min, max }; + return false; + } + + if (values.Length == 1) + { + if (values[0] < 0) + { + min = values[0]; + max = 0; + } + else max = values[0]; + } + else if (values.Length >= 2) + { + min = Mathf.Min(values); + max = Mathf.Max(values); + } + + if (min == max) + { + msg = $"Expected min and max to be different values, but both are '{min}'."; + } + + value = new float[2] { min, max }; + return true; + } + } + + internal class Dropdown : IStrongHint + { + public string Key => Param.kDropdown; + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kCustomEditor }; + public IReadOnlyCollection Synonyms { get; } = new string[] { "Enum" }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + if (!found) + return false; + + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + switch (obj.ShaderType.Name) + { + case "int": case "uint": case "float": case "half": break; + default: + msg = $"Expected numeric scalar, but found '{obj.ShaderType.Name}'."; + return false; + } + + string[] options = HeaderUtils.LazyTokenString(rawValue); + + if (options.Length == 0) + { + msg = $"Expected at least 1 comma separated option, but found none."; + return false; + } + + value = options; + return true; + } + } + + internal class Color : IStrongHint + { + public string Key => Param.kColor; + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kCustomEditor }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + if (found) + { + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + switch (obj.ShaderType.Name) + { + case "float3": case "float4": case "half3": case "half4": return true; + default: + msg = $"Expected floating point vector of length 3 or 4, but found '{obj.ShaderType.Name}'."; + return false; + } + } + return false; + } + } + + internal class Literal : IStrongHint + { + public string Key => Param.kLiteral; + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + + if (found) + { + switch (obj.ShaderType.Name) + { + case "float": case "half": case "int": case "uint": return true; + default: + msg = $"Expected numeric scalar, but found '{obj.ShaderType.Name}'."; + return false; + } + } + return found; + } + } + + internal class Static : IStrongHint + { + public string Key => Param.kStatic; + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kAccessModifier }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + if (!found) + return false; + + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + switch (obj.ShaderType.Name) + { + case "float": case "half": case "int": case "uint": case "bool": + return true; + + case "float3": case "float4": case "half3": case "half4": + if (obj.Hints.ContainsKey(Param.kColor)) + return true; + + msg = $"Requires '{Param.kColor}' to support '{obj.ShaderType.Name}'."; + return false; + + default: + msg = $"Expected '{Param.kColor}' or scalar, but found '{obj.ShaderType.Name}'."; + return false; + } + } + } + + internal class External : IStrongHint + { + public string Key => Param.kExternal; + public IReadOnlyCollection Synonyms { get; } = new string[] { "ExternalNamespace" }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + return true; + } + } + + internal class Default : IStrongHint + { + public string Key => Param.kDefault; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + // TODO(SVFXG-868): This is tricky because there are multiple formats we need to support. + // for now, we can pass along the raw value and allow the header to process it. + msg = null; + value = rawValue; + + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + return found; + } + } + + internal class Dynamic : IStrongHint + { + public string Key => Param.kDynamic; + + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kCustomEditor }; + public IReadOnlyCollection Synonyms { get; } = new string[] { "Dynamic" }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = rawValue; + if (!found) + return false; + + switch(obj.ShaderType.Name) + { + case "float": case "float2": case "float3": case "float4": + case "half": case "half2": case "half3": case "half4": + return true; + default: + msg = $"Expected floating point vector or scalar, but found {obj.ShaderType.Name}."; + return false; + } + } + } + + internal class Linkage : IStrongHint + { + public string Key => Param.kLinkage; + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kAccessModifier }; + + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + value = rawValue; + msg = null; + if (!found) + return false; + + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + if (obj.ShaderType.Name != "bool") + { + msg = $"Expected type bool, but found '{obj.ShaderType.Name}'."; + return false; + } + + var funcProvider = provider as IProvider; + if (funcProvider == null) + { + msg = "Expected to be associated with a function."; + return false; + } + + if (rawValue == obj.Name) + { + msg = $"Cannot check linkage state against itself."; + return false; + } + + var func = funcProvider.Definition; + + bool hasMatch = false; + foreach(var param in func.Parameters) + if (param.Name == rawValue) + { + hasMatch = true; + break; + } + + if (!hasMatch) + { + msg = $"Could not find expected parameter '{rawValue}'."; + return false; + } + return true; + } + } + + internal class Referable : IStrongHint + { + public string Key => Param.kReferable; + + static HashSet s_commonReferables; + + private static HashSet GetCommonReferables() + { + if (s_commonReferables == null) + { + s_commonReferables = new HashSet() { + Param.Ref.kUV, // only supports vec2 + + // vec3 only + Param.Ref.kPosition, + Param.Ref.kTangent, + Param.Ref.kNormal, + Param.Ref.kBitangent, + Param.Ref.kViewDirection, + + // vec4 only + Param.Ref.kVertexColor, + Param.Ref.kScreenPosition, + }; + } + return s_commonReferables; + } + + public IReadOnlyCollection Synonyms => GetCommonReferables(); + public IReadOnlyCollection Conflicts { get; } = new string[] { Param.kCustomEditor }; + + // This hint allows `sg:Referable(UV)` or just `UV`; this is a case where the synonym is _functional_. + // Note also that this hint relies on the Default hint to be used in tandem to set the initial referable value (ie. space or channel); + // When we move to GTK, we should allow the default value to be handled as well. + + // Another note: we would rather query the Interface/Target for available referables and their possible values. + // We'd need a way to push that information down (ie. an untyped context object that can be passed). + public bool Process(bool found, string rawValue, IShaderField obj, IProvider provider, out object value, out string msg, string actualHintKey) + { + msg = null; + value = Key == actualHintKey ? rawValue : actualHintKey; + + if (!obj.IsInput) + { + msg = $"Expected input parameter."; + return false; + } + + if (value == null) + { + msg = $"Could not resolve a referable type."; + return false; + } + else if (!GetCommonReferables().Contains((string)value)) + { + msg = $"'{value}' is not a supported referable key."; + return false; + } + + // TODO: The underlying type shouldn't matter, but SG only supports these configurations at the moment. + switch ((string)value) + { + case Param.Ref.kUV: + if (obj.ShaderType.Name != "half2" && obj.ShaderType.Name != "float2") + { + msg = $"'{(string)value}' expects floating point vector of length 2, but found '{obj.ShaderType.Name}'."; + return false; + } + break; + case Param.Ref.kVertexColor: + case Param.Ref.kScreenPosition: + if (obj.ShaderType.Name != "half4" && obj.ShaderType.Name != "float4") + { + msg = $"'{(string)value}' expects floating point vector of length 4, but found '{obj.ShaderType.Name}'."; + return false; + } + break; + default: + if (obj.ShaderType.Name != "half3" && obj.ShaderType.Name != "float3") + { + msg = $"'{(string)value}' expects floating point vector of length 3, but found '{obj.ShaderType.Name}'."; + return false; + } + break; + } + return true; + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHints.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHints.cs.meta new file mode 100644 index 00000000000..cc5496eadae --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/Header/ParameterHints.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: bc36eaef20dcb49c592cc866efc63f59 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/HeaderUtils.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/HeaderUtils.cs deleted file mode 100644 index 61d8e620104..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/HeaderUtils.cs +++ /dev/null @@ -1,322 +0,0 @@ -using UnityEngine; -using UnityEditor.Graphing; -using System.Collections.Generic; - -namespace UnityEditor.ShaderGraph.ProviderSystem -{ - internal static class Hints - { - internal static class Common - { - internal const string kDisplayName = "sg:DisplayName"; - - // Not yet implemented. - internal const string kTooltip = "sg:Tooltip"; // SG doesn't have tooltips - } - internal static class Func - { - internal const string kProviderKey = "sg:ProviderKey"; - - internal const string kReturnDisplayName = "sg:ReturnDisplayName"; - - internal const string kSearchTerms = "sg:SearchTerms"; - internal const string kSearchName = "sg:SearchName"; - internal const string kCategory = "sg:SearchCategory"; - - // Not yet implemented. - internal const string kGroupKey = "sg:GroupKey"; - internal const string kReturnTooltip = "sg:ReturnTooltip"; - internal const string kDocumentationLink = "sg:HelpURL"; - - // ProviderKey associated hints, Not yet implemented. - internal const string kDeprecated = "sg:Deprecated"; - internal const string kObsolete = "sg:Obsolete"; - internal const string kVersion = "sg:Version"; - } - - internal static class Param - { - internal const string kStatic = "sg:Static"; - internal const string kLocal = "sg:Local"; - internal const string kLiteral = "sg:Literal"; - internal const string kColor = "sg:Color"; - internal const string kRange = "sg:Range"; - internal const string kDropdown = "sg:Dropdown"; - internal const string kDefault = "sg:Default"; - - // Not yet implemented. - internal const string kSetting = "sg:Setting"; - internal const string kLinkage = "sg:Linkage"; - internal const string kPrecision = "sg:Precision"; - internal const string kDynamic = "sg:Dynamic"; - internal const string kReferable = "sg:Referable"; - internal const string kExternal = "sg:External"; - - // Hard coded referables, not yet implemented. - internal const string kUV = "sg:ref:UV"; - internal const string kPosition = "sg:ref:Position"; - internal const string kNormal = "sg:ref:Normal"; - internal const string kBitangent = "sg:ref:Bitangent"; - internal const string kTangent = "sg:ref:Tangent"; - internal const string kViewDirection = "sg:ref:ViewDirection"; - internal const string kScreenPosition = "sg:ref:ScreenPosition"; - internal const string kVertexColor = "sg:VertexColor"; - } - } - - internal static class HeaderUtils - { - internal static string ToShaderType(this MaterialSlot slot) - { - if (slot is ExternalMaterialSlot eslot) - return eslot.TypeName; - - return slot.concreteValueType.ToShaderString(); - } - - internal static bool IsNumeric(string typeName) - { - return TryParseTypeInfo(typeName, out _, out _, out _, out _, out _, out _, out _); - } - - internal static bool TryParseTypeInfo( - string type, - out string prim, - out bool isScalar, - out bool isVector, - out bool isMatrix, - out int rows, - out int cols, - out int length) - { - prim = null; - isScalar = false; - isVector = false; - isMatrix = false; - rows = -1; - cols = -1; - length = -1; - - // TODO: Array support isn't established yet, if we support multidim this wouldn't work. - if (type.Contains('[')) - return false; - - - if (type.StartsWith("uint")) prim = "uint"; - if (type.StartsWith("int")) prim = "int"; - if (type.StartsWith("bool")) prim = "bool"; - if (type.StartsWith("half")) prim = "half"; - if (type.StartsWith("float")) prim = "float"; - - if (prim == null) - return false; - - if (type == prim) - return isScalar = true; - - var remainder = type.Substring(prim.Length); - - if (remainder.Length == 1) - { - return isVector = int.TryParse(remainder, out rows) && rows >= 1 && rows <= 4; - } - if (remainder.Length == 3) - { - return isMatrix - = int.TryParse(remainder.Substring(0, 1), out rows) && rows >= 1 && rows <= 4 - && int.TryParse(remainder.Substring(2, 1), out cols) && cols >= 1 && cols <= 4; - } - return false; - } - - internal static bool TryCast(string shaderType, float[] values, out T value, T fallback = default) - { - try - { - return Cast(shaderType, values, out value, fallback); - } - catch - { - value = default; - return false; - } - } - - private static bool Cast(string shaderType, float[] values, out T value, T fallback = default) - { - object obj = default; - value = fallback; - - if (values == null || values.Length == 0) - return false; - - float[] v = new float[16]; - for (int i = 0; i < values.Length; ++i) - v[i] = values[i]; - - if (!TryParseTypeInfo(shaderType, out string prim, out bool isScalar, out bool isVector, out bool isMatrix, out int rows, out int cols, out int length)) - return false; - - if (isScalar || isVector && rows == 1 || isMatrix && rows == 1 && cols == 1) - { - var fv = v[0]; - - switch (prim) - { - case "bool": obj = fv != 0; break; - case "uint": obj = fv; break; - case "int": obj = fv; break; - case "float": - case "half": obj = fv; break; - default: return false; - } - } - if (isVector) - { - switch (rows) - { - case 2: obj = new Vector2(v[0], v[1]); break; - case 3: obj = new Vector3(v[0], v[1], v[2]); break; - case 4: obj = new Vector4(v[0], v[1], v[2], v[3]); break; - default: return false; - } - - } - if (isMatrix) - { - Matrix4x4 m = new(); - for (int i = 0; i < cols * rows; ++i) - { - // TODO: Validate with GTK - m[i % rows + rows * (i / rows)] = v[i]; - } - } - - value = (T)obj; - return true; - } - - internal static MaterialSlot MakeSlotFromParameter(ParameterHeader header, int slotId, SlotType dir) - { - MaterialSlot slot; - - if (header.isDropdown) - { - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asIdx, 0.0f); - slot = new Vector1MaterialEnumSlot(slotId, header.displayName, header.referenceName, dir, header.options, asIdx); - } - else if (header.isSlider) - { - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asRng, 0); - slot = new Vector1MaterialRangeSlot(slotId, header.displayName, header.referenceName, dir, asRng, new Vector2(header.sliderMin, header.sliderMax)); - } - else switch (header.typeName) - { - case "uint1": - case "uint": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asUint, 0u); - slot = new Vector1MaterialIntegerSlot(slotId, header.displayName, header.referenceName, dir, asUint, unsigned: true); break; - case "int1": - case "int": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asInt, 0); - slot = new Vector1MaterialIntegerSlot(slotId, header.displayName, header.referenceName, dir, asInt); break; - case "half": - case "half1": - case "float1": - case "float": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asFloat, 0.0f); - slot = new Vector1MaterialSlot(slotId, header.displayName, header.referenceName, dir, asFloat); break; - case "bool1": - case "bool": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asBool, false); - slot = new BooleanMaterialSlot(slotId, header.displayName, header.referenceName, dir, asBool); break; - case "half2": - case "float2": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asV2, Vector2.zero); - slot = new Vector2MaterialSlot(slotId, header.displayName, header.referenceName, dir, asV2); break; - case "half3": - case "float3": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asV3, Vector3.zero); - slot = !header.isColor - ? new Vector3MaterialSlot(slotId, header.displayName, header.referenceName, dir, asV3) - : new ColorRGBMaterialSlot(slotId, header.displayName, header.referenceName, dir, new Vector4(asV3.x, asV3.y, asV3.z, 1), Internal.ColorMode.Default); - break; - case "half4": - case "float4": - HeaderUtils.TryCast(header.typeName, header.defaultValue, out var asV4, header.isColor ? new Vector4(0, 0, 0, 1) : Vector4.zero); - - slot = header.isColor - ? new ColorRGBAMaterialSlot(slotId, header.displayName, header.referenceName, dir, asV4) - : new Vector4MaterialSlot(slotId, header.displayName, header.referenceName, dir, asV4); - - break; - case "half2x2": - case "float2x2": slot = new Matrix2MaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - case "half3x3": - case "float3x3": slot = new Matrix3MaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - case "half4x4": - case "float4x4": slot = new Matrix4MaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - - case "SamplerState": - case "UnitySamplerState": slot = new SamplerStateMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - case "Texture2D": - case "UnityTexture2D": - slot = dir == SlotType.Input - ? new Texture2DInputMaterialSlot(slotId, header.displayName, header.referenceName) - : new Texture2DMaterialSlot(slotId, header.displayName, header.referenceName, dir); - break; - case "Texture2DArray": - case "UnityTexture2DArray": - slot = dir == SlotType.Input - ? new Texture2DArrayInputMaterialSlot(slotId, header.displayName, header.referenceName) - : new Texture2DArrayMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - case "TextureCube": - case "UnityTextureCube": - slot = dir == SlotType.Input - ? new CubemapInputMaterialSlot(slotId, header.displayName, header.referenceName) - : new CubemapMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - case "Texture3D": - case "UnityTexture3D": - slot = dir == SlotType.Input - ? new Texture3DInputMaterialSlot(slotId, header.displayName, header.referenceName) - : new Texture3DMaterialSlot(slotId, header.displayName, header.referenceName, dir); break; - default: - slot = new ExternalMaterialSlot(slotId, header.displayName, header.referenceName, header.externalQualifiedTypeName, dir, header.defaultString); - break; - } - - slot.hideConnector = header.isStatic && header.isInput; - slot.hidden = header.isLocal; - slot.bareResource = header.isBareResource; - return slot; - } - - internal static float[] LazyTokenFloat(string arg) - { - var tokens = LazyTokenize(arg); - List asfloat = new(); - - foreach (var token in tokens) - if (float.TryParse(token, out float r)) - asfloat.Add(r); - - return asfloat.ToArray(); - } - - internal static string[] LazyTokenString(string arg) - { - List tokens = new(LazyTokenize(arg)); - return tokens.ToArray(); - } - - private static IEnumerable LazyTokenize(string arg) - { - foreach (var e in arg.Split(',')) - { - var result = e.Trim(); - if (!string.IsNullOrWhiteSpace(result)) - yield return e.Trim(); - } - } - } -} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/HeaderUtils.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/HeaderUtils.cs.meta deleted file mode 100644 index 832c0d858df..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/HeaderUtils.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 03da3bc1b8aa9064ea9e97a5eec5f074 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ParameterHeader.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ParameterHeader.cs deleted file mode 100644 index dfaab6b39fc..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ParameterHeader.cs +++ /dev/null @@ -1,220 +0,0 @@ - -using System.Collections.Generic; -using System.Text; - -namespace UnityEditor.ShaderGraph.ProviderSystem -{ - internal struct ParameterHeader - { - readonly internal bool isValid; - - readonly internal string referenceName; - readonly internal IShaderType shaderType; - readonly internal string typeName => shaderType.Name; - - readonly internal string displayName; - readonly internal string tooltip; - - readonly internal bool isInput; - readonly internal bool isOutput; - - readonly internal bool isColor; - - readonly internal bool isStatic; - readonly internal bool isLocal; - - readonly internal bool isDropdown; - readonly internal string[] options; - - readonly internal bool isSlider; - readonly internal float sliderMin; - readonly internal float sliderMax; - - readonly internal float[] defaultValue; - readonly internal string defaultString; - - readonly internal string externalQualifiedTypeName; - - readonly internal bool isNumeric; - readonly internal bool isTexture; - readonly internal bool isSampler; - readonly internal bool isStruct; - readonly internal bool isReference; - readonly internal bool isLiteral; - - readonly internal string referable; - - readonly internal bool isBareResource; - - readonly internal string knownIssue; - - private ParameterHeader(int a) - { - referenceName = null; - displayName = null; - shaderType = null; - tooltip = null; - isOutput = true; - isInput = false; - isColor = false; - defaultValue = null; - isStatic = false; - isDropdown = false; - options = null; - isSlider = false; - sliderMin = 0; - sliderMax = 1; - isBareResource = false; - isLocal = false; - isReference = false; - isLiteral = false; - isTexture = false; - isSampler = false; - isNumeric = false; - isStruct = false; - referable = null; - defaultString = null; - knownIssue = null; - externalQualifiedTypeName = null; - - isValid = false; - } - - // this is for return types. - internal ParameterHeader(string referenceName, IShaderType shaderType, string tooltip = null) : this(0) - { - if (string.IsNullOrWhiteSpace(referenceName) || string.IsNullOrWhiteSpace(shaderType.Name)) - { - isValid = false; - return; - } - - this.shaderType = shaderType; - this.externalQualifiedTypeName = shaderType.Name; - this.referenceName = referenceName; - this.displayName = referenceName; - this.tooltip = tooltip; - - string typeTest = shaderType.Name.ToLowerInvariant(); - - isNumeric = HeaderUtils.TryParseTypeInfo(typeName, out _, out _, out _, out _, out _, out _, out _); - isSampler = typeTest.Contains("sampler"); - isTexture = typeTest.Contains("texture"); - isBareResource = !typeTest.Contains("unity") && (isSampler || isTexture); // special handling case. - isStruct = !isTexture && !isSampler && !isNumeric; - isValid = true; - } - - internal ParameterHeader(IShaderField param, IShaderFunction owner) : this(param?.Name, param?.ShaderType) - { - if (!isValid || param == null) - return; - - isOutput = isInput = false; - isInput = param.IsInput; - isOutput = param.IsOutput; - - if (!param.Hints.TryGetValue(Hints.Common.kDisplayName, out displayName)) - displayName = ObjectNames.NicifyVariableName(referenceName); - - HeaderUtils.TryParseTypeInfo(typeName, out string prim, out bool isScalar, out bool isVector, out bool isMatrix, out int rows, out int cols, out _); - List editorHintsUsed = new(); - - - isLiteral = param.Hints.TryGetValue(Hints.Param.kLiteral, out _); // TODO: Only relevant for int, float, half, uint - - if (param.Hints.TryGetValue(Hints.Param.kExternal, out externalQualifiedTypeName)) - externalQualifiedTypeName += $"::{typeName}"; - else externalQualifiedTypeName = typeName; - - if (param.Hints.TryGetValue(Hints.Param.kColor, out _)) - { - editorHintsUsed.Add(Hints.Param.kColor); - if (rows != 3 && rows != 4 && !isVector) - { - knownIssue = $"'Color' hint on '{referenceName}' is not supported for '{typeName}'."; - } - else isColor = true; - } - - if (param.Hints.TryGetValue(Hints.Param.kStatic, out _)) - { - if (isOutput) - { - knownIssue = $"'Static' hint on '{referenceName}' is not supported for 'out' parameters."; - } - else if (!isScalar && !isColor) - { - knownIssue = $"'Static' hint on '{referenceName}' is not supported for '{typeName}'."; - } - else isStatic = true; - } - - if (param.Hints.TryGetValue(Hints.Param.kLocal, out _)) - { - editorHintsUsed.Add(Hints.Param.kLocal); - if (isStatic) // All Access Modifier style hints would conflict with each other, but we currently only have Local and Static - { - knownIssue = $"'Local' hint on '{referenceName}' conflicts with found 'Static' hint."; - } - else isLocal = true; - } - - if (param.Hints.TryGetValue(Hints.Param.kDropdown, out var dropdownString)) - { - editorHintsUsed.Add(Hints.Param.kDropdown); - options = HeaderUtils.LazyTokenString(dropdownString); - if (!isScalar || prim == "bool") - { - knownIssue = $"'Dropdown' hint on '{referenceName}' is not supported for '{typeName}'."; - } - else if (options.Length == 0) - { - knownIssue = $"'Dropdown' hint on '{referenceName}' has no options."; - } - else isDropdown = true; - } - - if (param.Hints.TryGetValue(Hints.Param.kRange, out var rangeValues)) - { - editorHintsUsed.Add(Hints.Param.kRange); - var values = HeaderUtils.LazyTokenFloat(rangeValues); - - if (!isScalar || prim == "bool") - { - knownIssue = $"'Range' hint on '{referenceName}' is not supported for '{typeName}'."; - } - else if (values.Length != 2 || values[0] == values[1]) - { - knownIssue = $"'Range' hint on '{referenceName}' expects two arguments of different values."; - } - else - { - sliderMin = values[0] < values[1] ? values[0] : values[1]; - sliderMax = values[0] > values[1] ? values[0] : values[1]; - isSlider = true; - } - } - - if (param.Hints.TryGetValue(Hints.Param.kDefault, out defaultString)) - { - defaultValue = HeaderUtils.LazyTokenFloat(defaultString); - } - - if(editorHintsUsed.Count > 1) - { - StringBuilder sb = new(); - bool first = true; - foreach(var hintName in editorHintsUsed) - { - if (!first) - sb.Append(", "); - first = false; - sb.Append($"{hintName}"); - } - - knownIssue = $"Found multiple conflicting editor hints on '{referenceName}': '{sb.ToString()}'."; - } - } - } -} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ParameterHeader.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ParameterHeader.cs.meta deleted file mode 100644 index 1b207f7b1b7..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ParameterHeader.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: df1b66f5ce54910438e02c0d87921c4f \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderAttribute.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderAttribute.cs.meta deleted file mode 100644 index 93ecad7ef00..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderAttribute.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 83c57d0908748409ba9167606f577a92 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNode.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNode.cs index 3c93e82c8cf..5752a05e8fd 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNode.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNode.cs @@ -34,13 +34,15 @@ public void GetSourceAssetDependencies(AssetCollection assetCollection) internal FunctionHeader Header { get; private set; } + internal Dictionary ParamHeaders { get; private set; } + internal IProvider Provider => m_provider; const int kReservedOutputSlot = 0; public override bool hasPreview => true; - public override bool canSetPrecision => false; + public override bool canSetPrecision => Header?.allowPrecision ?? false; internal override bool ExposeToSearcher => false; @@ -49,6 +51,7 @@ public void GetSourceAssetDependencies(AssetCollection assetCollection) public ProviderNode() { name = "Provider Based Node"; + Header = new(); } internal void InitializeFromProvider(IProvider provider) @@ -89,10 +92,11 @@ protected void Refresh() internal void UpdateModel() { - if (Provider == null || Provider.Definition == null) + if (Provider == null || Provider.Definition == null || !Provider.IsValid) return; - Header = new FunctionHeader(Provider); + Header.Process(Provider.Definition, Provider); + var header = Header; this.name = header.displayName; this.synonyms = header.searchTerms; @@ -116,33 +120,37 @@ internal void UpdateModel() oldSlotMap[oldSlot.shaderOutputName] = idTuple; } - List paramHeaders = new(); + ParamHeaders = new(); + List paramOrder = new(); List desiredSlotOrder = new(); // return type is a special case, because it has no parameter but still needs a slot // we reserve the 0 slotId for this and always make sure it's added first/at the top. - if (header.hasReturnType) + if (header.hasReturnValueType) { - var returnParam = new ParameterHeader(header.returnDisplayName, header.returnType, header.tooltip); usedSlotIds.Add(kReservedOutputSlot); desiredSlotOrder.Add(kReservedOutputSlot); - AddSlotFromParameter(returnParam, kReservedOutputSlot, SlotType.Output); + AddSlotFromParameter(header.returnHeader, kReservedOutputSlot, SlotType.Output); } // build the header data for our parameters and mark which slot ids are being reused. foreach(var param in parameters) { - paramHeaders.Add(new ParameterHeader(param, Provider.Definition)); + var paramHeader = new ParameterHeader(param, Provider); + ParamHeaders.Add(param.Name, paramHeader); + paramOrder.Add(paramHeader); if (oldSlotMap.TryGetValue(param.Name, out var idTuple)) { - if (idTuple.inputId > -1) usedSlotIds.Add(idTuple.inputId); - if (idTuple.outputId > -1) usedSlotIds.Add(idTuple.outputId); + if (idTuple.inputId > -1 && param.IsInput) + usedSlotIds.Add(idTuple.inputId); + if (idTuple.outputId > -1 && param.IsOutput) + usedSlotIds.Add(idTuple.outputId); } } // walk through our header data and build the actual slots. int nextSlot = kReservedOutputSlot; - foreach (var paramHeader in paramHeaders) + foreach (var paramHeader in paramOrder) { if (!oldSlotMap.TryGetValue(paramHeader.referenceName, out var idTuple)) idTuple = (-1, -1); @@ -172,7 +180,11 @@ void AddSlotFromParameter(ParameterHeader header, int slotId, SlotType dir) { var slot = HeaderUtils.MakeSlotFromParameter(header, slotId, dir); if (slot != null) - AddSlot(slot); + // Slots that use label control have no indication in the Model that they use them. + // However, the only _existing_ case where they'd meaningfully change are SpaceMaterialSlots, + // which also don't handle default values well either. In this case, we go nuclear and completely + // rebuild the slot. + AddSlot(slot, slot is not SpaceMaterialSlot, slot is not SpaceMaterialSlot); } public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMode) @@ -180,7 +192,10 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo if (this.Provider == null || this.Provider.Definition == null) return; - using (var slots = PooledList.Get()) + // Apply legacy precision/dynamic only before code generation/usage. + HeaderUtils.TryApplyLegacy(Provider.Definition, this.Header, this.ParamHeaders, PrecisionUtil.Token, lastKnownDynamicVectorLength, out var func); + + using (UnityEngine.Pool.ListPool.Get(out var slots)) { GetSlots(slots); Dictionary paramSlotMap = new(); @@ -212,7 +227,7 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo } bool first = true; - foreach (var param in Provider.Definition.Parameters) + foreach (var param in func.Parameters) { var inputSlot = paramSlotMap[param.Name].input; var outputSlot = paramSlotMap[param.Name].output; @@ -227,6 +242,21 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo var argument = valueString; // assume it's an input, in which case the arg will be the upstream value/connection. + // apply linkage override + if (ParamHeaders.TryGetValue(param.Name, out var ph) && ph.isLinkage) + { + var targetSlots = paramSlotMap[ph.linkTarget]; + + // this concept is awkward for inout slots, but that could be improved in the future. + // ie. add support for int and set it to 0 = none, 1 = in, 2 = out, 3 = both. + if (targetSlots.input != null && targetSlots.input.isConnected + || targetSlots.output != null && targetSlots.output.isConnected) + { + argument = "true"; + } + else argument = "false"; + } + if (outputSlot != null) { // inout and out define a variable to be used as the argument. @@ -242,30 +272,25 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo args.Append(argument); } - foreach (var name in Provider.Definition.Namespace) - call.Append($"{name}::"); - call.Append(Provider.Definition.Name); - call.Append("("); - call.Append(args.ToString()); - call.Append(");"); - - + call.Append(ShaderObjectUtils.GenerateCall(func, args.ToString())); sb.AddLine(call.ToString()); } } public void GenerateNodeFunction(FunctionRegistry registry, GenerationMode generationMode) { + if (Provider == null || !Provider.IsValid || Provider.Definition == null) + return; + if (Provider.AssetID != default) { var includePath = AssetDatabase.GUIDToAssetPath(Provider.AssetID); registry.RequiresIncludePath(includePath, false); } - if (requiresGeneration) + if (HeaderUtils.TryApplyLegacy(Provider.Definition, Header, ParamHeaders, PrecisionUtil.Token, lastKnownDynamicVectorLength, out var func) || requiresGeneration) { - var func = Provider.Definition; - string code = ShaderObjectUtils.GenerateCode(func, false, false); + string code = ShaderObjectUtils.GenerateCode(func, false, false, true); registry.ProvideFunction(func.Name, s => s.AppendLine(code)); } } @@ -275,24 +300,26 @@ public override void ValidateNode() base.ValidateNode(); if (Provider == null) { - owner.AddSetupError(this.objectId, "Node is in an invalid state and cannot recover."); + owner?.AddSetupError(this.objectId, "Node is in an invalid state and cannot recover."); return; } else if (Provider.AssetID != default && (Provider.Definition == null || !Provider.Definition.IsValid)) { var path = AssetDatabase.GUIDToAssetPath(Provider.AssetID); - owner.AddSetupError(this.objectId, $"Data for '{Provider.ProviderKey}' expected in '{path}'."); + owner?.AddSetupError(this.objectId, $"Data for '{Provider.ProviderKey}' expected in '{path}'."); return; } else { - foreach(var param in Provider.Definition.Parameters) + foreach(var msg in Header.Messages) + { + owner?.AddValidationError(this.objectId, msg, Rendering.ShaderCompilerMessageSeverity.Warning); + } + foreach(var param in ParamHeaders.Values) { - var header = new ParameterHeader(param, Provider.Definition); - if (!string.IsNullOrWhiteSpace(header.knownIssue)) + foreach(var msg in param.Messages) { - owner.AddValidationError(this.objectId, header.knownIssue, Rendering.ShaderCompilerMessageSeverity.Warning); - break; // We can only show one error badge at a time. + owner?.AddValidationError(this.objectId, msg, Rendering.ShaderCompilerMessageSeverity.Warning); } } } diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNodePropertyDrawer.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNodePropertyDrawer.cs index 1fe1ef32bdf..91e9fc549ee 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNodePropertyDrawer.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderNodePropertyDrawer.cs @@ -1,7 +1,7 @@ using System; using UnityEngine.UIElements; using UnityEditor.ShaderGraph.ProviderSystem; -using UnityEngine; +using System.Text; namespace UnityEditor.ShaderGraph.Drawing.Inspector.PropertyDrawers { @@ -14,37 +14,65 @@ internal override void AddCustomNodeProperties(VisualElement parentElement, Abst { node = nodeBase as ProviderNode; var provider = node.Provider; - var definition = node.Provider.Definition; string sourcePath = AssetDatabase.GUIDToAssetPath(node.Provider.AssetID); - string providerKey = provider.ProviderKey; - string qualifiedSignature = ShaderObjectUtils.QualifySignature(node.Provider.Definition, true, true); - bool hasProviderKey = definition?.Hints?.ContainsKey(Hints.Func.kProviderKey) ?? false; - if (provider == null) + if (!provider.IsValid) { - parentElement.Add(new HelpBoxRow("Provider node is in an invalid and irrecoverable state.", MessageType.Error)); + parentElement.Add(new HelpBoxRow($"Could not find '{providerKey}' in '{sourcePath}'.", MessageType.Error)); + // TODO: When this happens, we should offer to update the AssetID if it's found elsewhere in the provider library. + // This should be a consideration for API Management Hints (SVFXG-865). return; } - bool isAnAsset = provider.AssetID != default; + // TODO: We could show this for all ProviderNodes, but the inspector isn't currently refreshed on topological changes. + if (provider.AssetID != default) + { + parentElement.Add(new Label("Provider Key")); + parentElement.Add(new HelpBoxRow(providerKey, MessageType.None)); - if (!isAnAsset) - return; + parentElement.Add(new Label("Source Path")); + parentElement.Add(new HelpBoxRow(sourcePath, MessageType.None)); + + string qualifiedSignature = ShaderObjectUtils.QualifySignature(node.Provider.Definition, true, true); + parentElement.Add(new Label("Qualified Signature")); + parentElement.Add(new HelpBoxRow(qualifiedSignature, MessageType.None)); - else if (!provider.IsValid) + string code = ShaderObjectUtils.GenerateCode(provider.Definition, false, false, false); + parentElement.Add(new Label("Expected Definition")); + parentElement.Add(new HelpBoxRow(code, MessageType.None)); + } + + StringBuilder sb = new(); + bool hasMsg = false; + + // Function + foreach (var msg in node.Header.Messages) { - parentElement.Add(new HelpBoxRow($"Could not find '{providerKey}' in '{sourcePath}'.", MessageType.Error)); + hasMsg = true; + sb.AppendLine(msg); } - else if (!hasProviderKey) + if (hasMsg) { - parentElement.Add(new HelpBoxRow($"'{providerKey}' in '{sourcePath}' does not have a 'ProviderKey' hint. If the namespace, name, or parameter list changes- this node instance will become invalidated.", MessageType.Warning)); + parentElement.Add(new Label("Function Hint Messages")); + parentElement.Add(new HelpBoxRow(sb.ToString(), MessageType.Warning)); } - else + + // Parameters + foreach (var paramHeader in node.ParamHeaders.Values) { - parentElement.Add(new HelpBoxRow($"Provider Key '{providerKey}' for \n" + - $"Function Signature '{qualifiedSignature}' found in \n" + - $"File Path '{sourcePath}'.", MessageType.Info)); + hasMsg = false; + sb.Clear(); + foreach(var msg in paramHeader.Messages) + { + hasMsg = true; + sb.AppendLine(msg); + } + if (hasMsg) + { + parentElement.Add(new Label($"Parameter '{paramHeader.referenceName}' Hint Messages")); + parentElement.Add(new HelpBoxRow(sb.ToString(), MessageType.Warning)); + } } } } diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider.meta new file mode 100644 index 00000000000..89f33e7526d --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d21febea789d748cb9d2cd29153e7b1b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionProvider.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ExpressionProvider.cs similarity index 94% rename from Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionProvider.cs rename to Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ExpressionProvider.cs index 2a284bd23fe..b535d1ef9cc 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ExpressionProvider.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ExpressionProvider.cs @@ -14,7 +14,7 @@ internal class ExpressionProvider : IProvider public string ProviderKey => kExpressionProviderKey; public GUID AssetID => default; public bool RequiresGeneration => true; - private static readonly string[] kNamespace = { "unity", "shadergraph", "expression" }; + private static readonly string[] kNamespace = { "unity_sg_expression" }; internal string Expression => m_expression; internal string ShaderType => m_type; @@ -43,7 +43,7 @@ public IShaderFunction Definition [NonSerialized] IShaderFunction m_definition; - internal ExpressionProvider() : this("Expression", "", "float") { } + internal ExpressionProvider() : this("Expression", "A", "float") { } internal ExpressionProvider(string name, string expression, string type) { @@ -60,8 +60,9 @@ public void Reload() { Hints.Common.kDisplayName, "Expression" }, { Hints.Func.kProviderKey, kExpressionProviderKey }, { Hints.Func.kSearchName, "Expression" }, - { Hints.Func.kCategory, "Utility" }, - { Hints.Func.kSearchTerms, "equation, calculation, inline, code" } + { Hints.Func.kSearchCategory, "Utility" }, + { Hints.Func.kSearchTerms, "equation, calculation, inline, code" }, + { Hints.Func.kPrecision, "" } }; internal void UpdateExpression(string name, string expression, string type) @@ -113,6 +114,7 @@ string HandleName(string name) IShaderType shaderType = new ShaderType(type); List parameters = new(); + foreach (var paramName in orderedNames) parameters.Add(new ShaderField(paramName, true, false, shaderType, null)); diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ExpressionProvider.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ExpressionProvider.cs.meta new file mode 100644 index 00000000000..65765f16ba2 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ExpressionProvider.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 8905563cd559b4cceac8102dba04bc1a \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderAttribute.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ProviderAttribute.cs similarity index 63% rename from Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderAttribute.cs rename to Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ProviderAttribute.cs index 2885493f1fa..5ed162c6a18 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Model/ProviderAttribute.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ProviderAttribute.cs @@ -1,4 +1,3 @@ - using System; using System.Collections.Generic; using System.Reflection; @@ -13,7 +12,6 @@ internal class ProviderModelAttribute : Attribute public ProviderModelAttribute(string providerKey) { ProviderKey = providerKey; } } - // This marks a provider to be included in the ProviderLibrary internal class ScriptedProviderAttribute : Attribute { } internal static class ProviderTypeCache @@ -28,19 +26,16 @@ private static void BuildCache() s_providerModels = new(); s_scriptedProviders = new(); - foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) + foreach(var type in TypeCache.GetTypesWithAttribute()) { - foreach (Type type in assembly.GetTypes()) - { - var providerKey = type.GetCustomAttribute()?.ProviderKey ?? null; - if (providerKey != null) - if (!s_providerModels.TryAdd(providerKey, type)) - Debug.LogError($"Attempted to register '{type.Name}' with provider key '{providerKey}', but key is already registered to '{s_providerModels[providerKey]}'."); - - if (type.GetCustomAttribute() != null) - s_scriptedProviders.Add(type); - } + var providerKey = type.GetCustomAttribute()?.ProviderKey ?? null; + if (providerKey != null) + if (!s_providerModels.TryAdd(providerKey, type)) + Debug.LogError($"Attempted to register '{type.Name}' with provider key '{providerKey}', but key is already registered to '{s_providerModels[providerKey]}'."); } + + foreach (var type in TypeCache.GetTypesWithAttribute()) + s_scriptedProviders.Add(type); } } diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ProviderAttribute.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ProviderAttribute.cs.meta new file mode 100644 index 00000000000..26ad735c011 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ProviderAttribute.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fe9988d529a2c48c092ade760150cd71 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ReflectedFunctionProvider.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ReflectedFunctionProvider.cs similarity index 94% rename from Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ReflectedFunctionProvider.cs rename to Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ReflectedFunctionProvider.cs index fad32e29bc5..47cb1aa3f88 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ReflectedFunctionProvider.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ReflectedFunctionProvider.cs @@ -1,4 +1,3 @@ - using System; using UnityEditor.ShaderApiReflection; using UnityEngine; @@ -10,7 +9,6 @@ internal class ReflectedFunctionProvider : IProvider { public string ProviderKey => m_providerKey; public GUID AssetID => m_sourceAssetId; - public bool RequiresGeneration => false; // TODO: Becomes true with dynamic/precision. public IShaderFunction Definition { diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ReflectedFunctionProvider.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ReflectedFunctionProvider.cs.meta new file mode 100644 index 00000000000..f4d9807ba4b --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Provider/ReflectedFunctionProvider.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 323995a5201d24acfbf34e49a52da528 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ReflectedFunctionProvider.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ReflectedFunctionProvider.cs.meta deleted file mode 100644 index 51e22478b3d..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ReflectedFunctionProvider.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 038ab7ce009192243b6d1d84f54a250b \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ShaderReflectionUtils.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ShaderReflectionUtils.cs index b3352e9f647..896b872f9c5 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ShaderReflectionUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/Reflection/ShaderReflectionUtils.cs @@ -1,6 +1,4 @@ - using System.Collections.Generic; -using System.Text; using UnityEditor.ShaderApiReflection; using UnityEngine; diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjectUtils.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjectUtils.cs.meta deleted file mode 100644 index 7c7e3b238e3..00000000000 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjectUtils.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 3567c810dd85b9b4a9c617ae8e5310e4 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects.meta new file mode 100644 index 00000000000..5e1aa42e5f7 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b35cb9aeb54d2447bb4c0735964a7fca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/CommonShaderObjects.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/CommonShaderObjects.cs similarity index 99% rename from Packages/com.unity.shadergraph/Editor/ProviderSystem/CommonShaderObjects.cs rename to Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/CommonShaderObjects.cs index a5bc838e3cf..f6d727418e9 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/CommonShaderObjects.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/CommonShaderObjects.cs @@ -1,4 +1,3 @@ - using System.Collections.Immutable; using System.Collections.Generic; diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/CommonShaderObjects.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/CommonShaderObjects.cs.meta new file mode 100644 index 00000000000..4c7d71c5bbf --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/CommonShaderObjects.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c0b02fca1cdef4cc186295b20e831bba \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjectUtils.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/ShaderObjectUtils.cs similarity index 84% rename from Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjectUtils.cs rename to Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/ShaderObjectUtils.cs index ff2fce58b8e..0d0f77bddf9 100644 --- a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjectUtils.cs +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/ShaderObjectUtils.cs @@ -1,4 +1,3 @@ - using System.Collections.Generic; using System.Text; @@ -71,7 +70,11 @@ private static string DeclareField(IShaderField a) } var t = SplitTypeName(a.ShaderType.Name); - return $"{t.typeName} {a.Name}{t.arraySpec}"; + var typeName = t.typeName; + + string access = a.IsInput && a.IsOutput ? "inout " : a.IsOutput ? "out " : ""; + + return $"{access}{typeName} {a.Name}{t.arraySpec}"; } private static string GenerateHints(string closure, IReadOnlyDictionary hints, string name = null) @@ -89,13 +92,30 @@ private static string GenerateHints(string closure, IReadOnlyDictionary where T : IShaderObject + { + internal bool isValid { get; private set; } + + protected HintRegistry HintRegistry => GetHintRegistry(); + + Dictionary m_values; + List m_msgs; + + internal IEnumerable Messages => m_msgs; + + protected bool Has(string key) => m_values.ContainsKey(key); + + protected V Get(string key) + { + m_values.TryGetValue(key, out object value); + return value is V ? (V)value : default; + } + + abstract protected HintRegistry GetHintRegistry(); + + // Runs once per Process call, which should be run whenever the ShaderOject and subsequent model are updated. + // Get/Has should be used here to populate the Header with meaningful information. + abstract protected void OnProcess(T obj, IProvider provider); + + internal void Process(T obj, IProvider provider) + { + isValid = obj != null && obj.IsValid && provider != null && provider.IsValid; + + if (!isValid) + return; + + HintRegistry.ProcessObject(obj, provider, out m_values, out m_msgs); + OnProcess(obj, provider); + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHeader.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHeader.cs.meta new file mode 100644 index 00000000000..d53de8ab9c2 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHeader.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: f8dbcdb5f80df4f758fb8d5911ff5c85 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHint.cs b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHint.cs new file mode 100644 index 00000000000..72b123e5701 --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHint.cs @@ -0,0 +1,165 @@ +using System.Collections.Generic; +using System.Text; + +namespace UnityEditor.ShaderGraph.ProviderSystem +{ + interface IStrongHint where T : IShaderObject + { + string Key { get; } + + // Indicate that this hint should attempt to be processed even if it wasn't found; + // this allows hints like 'DisplayName' to be able to handle determining a fallback. + bool AlwaysProcess => false; + bool AllowDisqualifiedSynonyms => true; + + IReadOnlyCollection Synonyms => null; + IReadOnlyCollection Conflicts => null; + + bool Process(bool found, string rawValue, T obj, IProvider provider, out object value, out string msg, string actualHintKey); + } + + internal class HintRegistry where T : IShaderObject + { + Dictionary> m_hintsByKey = new(); + Dictionary> m_synonymMap = new(); + + internal void RegisterStrongHint(IStrongHint hint) + { + // add the new hint; + m_hintsByKey.Add(hint.Key, hint); + + // add the hint's actual key as a synonym with highest priority + int priority = 0; + if (!m_synonymMap.TryAdd(hint.Key, new() { (hint.Key, priority) })) + m_synonymMap[hint.Key].Add((hint.Key, priority)); + + if (!hint.AllowDisqualifiedSynonyms) + return; + + // build a list of alternates by disqualifying the hint.key. + var alternates = new List(DisqualifyKey(hint.Key)); + + // Look through the hints synonyms and also add them and their disqualifications. + if (hint.Synonyms != null) + foreach(var synonym in hint.Synonyms) + alternates.AddRange(DisqualifyKey(synonym, true)); + + // for each subsequent alternate, the priority decreases. + foreach(var alternate in alternates) + { + priority++; + // Since a single synonym could be used by multiple hints, we need to register + // each StrongHint.Key to the synonym. + if (!m_synonymMap.TryAdd(alternate, new() { (hint.Key, priority) })) + m_synonymMap[alternate].Add((hint.Key, priority)); + } + } + + // eg. (unity:engine:sg:HintKey) => engine:sg:HintKey, sg:HintKey, HintKey + internal static IEnumerable DisqualifyKey(string key, bool inclusive = false) + { + if (inclusive) + yield return key; + + for (int i = 0; i < key.Length - 1; ++i) + { + if (key[i] == ':') + { + int j; + // find next non ':' index. + for (j = i + 1; j < key.Length && key[j] == ':'; ++j); + + string candidate = key[j..]; + if (!string.IsNullOrEmpty(candidate)) + yield return candidate; + } + } + } + + internal void ProcessObject(T obj, IProvider provider, out Dictionary values, out List msgs) + { + values = new(); + msgs = new(); + + Dictionary foundHints = new(); + Dictionary> conflictCases = new(); + HashSet conflictedHints = new(); + + // prepass, match the discovered hints to strong hint keys- this allows us to determine which strong hints shouldn't be skipped. + foreach(var rawHintKey in obj.Hints.Keys) + { + if (m_synonymMap.TryGetValue(rawHintKey, out var matches)) + { + foreach(var hint in matches) + { + // track priority so that we don't accidentally match a a synonym over the actual key. + if (!foundHints.TryAdd(hint.StrongHintKey, (rawHintKey, hint.Priority))) + { + // newly found synonym is higher priority (lower number), so use that instead. + if (hint.Priority < foundHints[hint.StrongHintKey].Priority) + foundHints[hint.StrongHintKey] = (rawHintKey, hint.Priority); + } + + // we can also determine which conflict classes we'll run into here. + if (m_hintsByKey[hint.StrongHintKey].Conflicts != null) + foreach (var conflictClass in m_hintsByKey[hint.StrongHintKey].Conflicts) + if (!conflictCases.TryAdd(conflictClass, new HashSet() { hint.StrongHintKey })) + conflictCases[conflictClass].Add(hint.StrongHintKey); + } + } + } + + // Conflict cases allow us to early out processing hints. + foreach(var caseKV in conflictCases) + { + if (caseKV.Value.Count == 1) + continue; + + // Aggregate conflicted hints so that we know which aren't being processed because they are in conflict. + conflictedHints.UnionWith(caseKV.Value); + + // Build conflict message. + StringBuilder sb = new(); + bool first = true; + sb.Append($"Conflicting hints of class '{caseKV.Key}' found, ignoring: "); + foreach (var conflictKey in caseKV.Value) + { + if (!first) + sb.Append(", "); + sb.Append($"'{conflictKey}'"); + first = false; + } + msgs.Add(sb.ToString()); + } + + // Now that we know which hints are both in use and valid, we can skip the ones not in use. + foreach (var strongHint in m_hintsByKey.Values) + { + if (conflictedHints.Contains(strongHint.Key)) + continue; + + string synonymUsed = null; + string rawHintValue = null; + bool found; + bool shouldProcess = strongHint.AlwaysProcess; + + + if (found = foundHints.TryGetValue(strongHint.Key, out var rawHintData)) + { + shouldProcess = true; + synonymUsed = rawHintData.Synonym; + rawHintValue = obj.Hints[synonymUsed]; + } + + if (!shouldProcess) + continue; + + if (strongHint.Process(found, rawHintValue, obj, provider, out var value, out var msg, synonymUsed)) + values.Add(strongHint.Key, value); + + if (!string.IsNullOrWhiteSpace(msg)) + msgs.Add($"{strongHint.Key}: {msg}"); + } + } + } +} diff --git a/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHint.cs.meta b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHint.cs.meta new file mode 100644 index 00000000000..ea1d3e83f1f --- /dev/null +++ b/Packages/com.unity.shadergraph/Editor/ProviderSystem/ShaderObjects/StrongHint.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 39d187709fcb149e182cd6c69ce13ed4 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/EnumControlView.uss b/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/EnumControlView.uss index db35ecc15a2..f6b234b4411 100644 --- a/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/EnumControlView.uss +++ b/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/EnumControlView.uss @@ -1,12 +1,13 @@ EnumControlView { flex-direction: row; align-items: center; - margin-left: 8px; - margin-right: 5px; + padding-left: 8px; + padding-right: 5px; + max-width: 200px; } .unity-base-field { - width: 80px; + min-width: 80px; margin-top: 4px; margin-bottom: 4px; } @@ -16,9 +17,8 @@ EnumControlView { } EnumControlView > Label { - max-width: 140px; - width: 30px; + min-width: 30px; -unity-text-align: middle-left; flex-grow: 1; - margin-right: 8px; + padding-right: 8px; } diff --git a/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/MultiFloatControlView.uss b/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/MultiFloatControlView.uss index a7d25350758..53c4bf85109 100644 --- a/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/MultiFloatControlView.uss +++ b/Packages/com.unity.shadergraph/Editor/Resources/Styles/Controls/MultiFloatControlView.uss @@ -14,7 +14,7 @@ MultiFloatControlView > #dummy > Label { .unity-base-field { - width: 30px; + width: 46px; /* Width is chosen such that if the field's value is "Infinity" it isn't clipped */ margin-top: 1px; margin-bottom: 1px; margin-left: 0; diff --git a/Packages/com.unity.shadergraph/Editor/Resources/Styles/MaterialNodeView.uss b/Packages/com.unity.shadergraph/Editor/Resources/Styles/MaterialNodeView.uss index 4d9c8d83077..3597c2d7893 100644 --- a/Packages/com.unity.shadergraph/Editor/Resources/Styles/MaterialNodeView.uss +++ b/Packages/com.unity.shadergraph/Editor/Resources/Styles/MaterialNodeView.uss @@ -1,5 +1,6 @@ MaterialNodeView { overflow: visible; + --preview-width: 200px; } MaterialNodeView.graphElement.node.MaterialNode { @@ -10,11 +11,11 @@ MaterialNodeView.graphElement.node.MaterialNode { } MaterialNodeView.master { - min-width: 200px; + min-width: var(--preview-width); } MaterialNodeView.blockData { - width: 200px; + width: var(--preview-width); } MaterialNodeView.blockData > #portInputContainer { @@ -27,8 +28,8 @@ MaterialNodeView #collapsible-area { } MaterialNodeView #previewFiller.expanded { - width: 200px; - padding-bottom: 200px; + width: var(--preview-width); + padding-bottom: var(--preview-width); } MaterialNodeView #previewFiller, @@ -41,9 +42,18 @@ MaterialNodeView #controls > #items { padding-bottom: 4px; } -/* Stop dropdown properties from overflowing the node's container */ +MaterialNodeView PropertyRow > #container { + max-width: var(--preview-width); +} + MaterialNodeView PropertyRow > #container > #label { - min-width: 92px; + min-width: auto; + flex-basis: auto; +} + +MaterialNodeView PropertyRow > #container > #content { + min-width: auto; + flex-basis: auto; } MaterialNodeView #title { @@ -60,8 +70,8 @@ MaterialNodeView > #previewContainer { } MaterialNodeView > #previewContainer > #preview { - width: 200px; - height: 200px; + width: var(--preview-width); + height: var(--preview-width); align-items:center; } diff --git a/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs b/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs index 2878744ae55..90d75b39bb4 100644 --- a/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs +++ b/Packages/com.unity.shadergraph/Editor/Util/MessageManager.cs @@ -124,6 +124,24 @@ public void ClearNodesFromProvider(object messageProvider, IEnumerable nodes) + { + foreach (var key in m_Messages.Keys) + { + if (key != messageProvider) + { + foreach (var node in nodes) + { + if (m_Messages[key].TryGetValue(node.objectId, out var messages)) + { + nodeMessagesChanged |= messages.Count > 0; + messages.Clear(); + } + } + } + } + } + public void ClearAll() { m_Messages.Clear(); diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Channel/Append.shadergraph b/Packages/com.unity.shadergraph/Samples~/NodeReference/Channel/Append.shadergraph new file mode 100644 index 00000000000..42abe974fcb --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Channel/Append.shadergraph @@ -0,0 +1,1940 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "3d43890caeac47b4857309d5344ed7b3", + "m_Properties": [], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "b6b433a517334abe98afacd485c86ad4" + } + ], + "m_Nodes": [ + { + "m_Id": "aaa285eb61084de6a2e4c74dd14b132b" + }, + { + "m_Id": "a86fd2dbe5b84c7bb1fa59addf1b46d2" + }, + { + "m_Id": "b15e5484768949429eac99779c886569" + }, + { + "m_Id": "802221319818402e9440bebbd036f3b7" + }, + { + "m_Id": "b84fa87d4eae4d91bb8635310ef8160b" + }, + { + "m_Id": "2fd957cca76f4bafb0875e96a8bebab6" + }, + { + "m_Id": "0c2b75bf870a406ab3c61b43aef36bcc" + }, + { + "m_Id": "9f7a3f56456c4a7387c90bbd70b4e76c" + }, + { + "m_Id": "170b8fac15614523b7774e84812e42b7" + }, + { + "m_Id": "fcc99598371c4b3f82f325255d31aba3" + }, + { + "m_Id": "be4df4a548cc4e51864143b04be25df0" + }, + { + "m_Id": "3b280c12cb7c442a9078a0135031a768" + }, + { + "m_Id": "7edbe96ce50f4413bcebe4aab53cebf9" + }, + { + "m_Id": "ad104ced631942eaaa340b0672bf4872" + }, + { + "m_Id": "26275f9466d54c5b8a15ea5395384960" + }, + { + "m_Id": "47253d9d3d3c4018b79c1bc4bef1d4bb" + } + ], + "m_GroupDatas": [ + { + "m_Id": "49442e7afc504a96aa54c221a4199a76" + }, + { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + { + "m_Id": "baa56fadc05a49ea87859f9e6767ee42" + } + ], + "m_StickyNoteDatas": [ + { + "m_Id": "948d7d8cb87844e192fde60c790675f5" + }, + { + "m_Id": "2c68662fd8aa48789d607f56a37819a0" + }, + { + "m_Id": "7fd982932a854caaa0a2c47792d66963" + } + ], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "0c2b75bf870a406ab3c61b43aef36bcc" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fcc99598371c4b3f82f325255d31aba3" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "170b8fac15614523b7774e84812e42b7" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "be4df4a548cc4e51864143b04be25df0" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "26275f9466d54c5b8a15ea5395384960" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "47253d9d3d3c4018b79c1bc4bef1d4bb" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "2fd957cca76f4bafb0875e96a8bebab6" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "170b8fac15614523b7774e84812e42b7" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "3b280c12cb7c442a9078a0135031a768" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7edbe96ce50f4413bcebe4aab53cebf9" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7edbe96ce50f4413bcebe4aab53cebf9" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "26275f9466d54c5b8a15ea5395384960" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "ad104ced631942eaaa340b0672bf4872" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7edbe96ce50f4413bcebe4aab53cebf9" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b84fa87d4eae4d91bb8635310ef8160b" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "170b8fac15614523b7774e84812e42b7" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fcc99598371c4b3f82f325255d31aba3" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "be4df4a548cc4e51864143b04be25df0" + }, + "m_SlotId": 1 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 484.79998779296875, + "y": -15.20001220703125 + }, + "m_Blocks": [ + { + "m_Id": "aaa285eb61084de6a2e4c74dd14b132b" + }, + { + "m_Id": "a86fd2dbe5b84c7bb1fa59addf1b46d2" + }, + { + "m_Id": "b15e5484768949429eac99779c886569" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 484.79998779296875, + "y": 184.79998779296875 + }, + "m_Blocks": [ + { + "m_Id": "802221319818402e9440bebbd036f3b7" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_SubDatas": [], + "m_ActiveTargets": [ + { + "m_Id": "68bc63adb418480cbc0cafc20bde6486" + }, + { + "m_Id": "48377aa648cf4e79b754a6317af8e747" + }, + { + "m_Id": "9857d69dfb32495ab6160d974eea695d" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "063b358aa26a4abe82960826d453c0f1", + "m_Id": 1, + "m_DisplayName": "Width", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Width", + "m_StageCapability": 3, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "06b1d302146b4d67bfaa548af6e16bc7", + "m_Id": 4, + "m_DisplayName": "A", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalVectorNode", + "m_ObjectId": "0c2b75bf870a406ab3c61b43aef36bcc", + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + "m_Name": "Normal Vector", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1293.0001220703125, + "y": 237.00003051757813, + "width": 206.0, + "height": 130.50003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "6daa12acda5b451793069c97d65513a3" + } + ], + "synonyms": [ + "surface direction" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Space": 2 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.AppendVectorNode", + "m_ObjectId": "170b8fac15614523b7774e84812e42b7", + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + "m_Name": "Append", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1051.2000732421875, + "y": 47.19999694824219, + "width": 127.20001220703125, + "height": 117.59999084472656 + } + }, + "m_Slots": [ + { + "m_Id": "48c980cfa5f849b7b7b3236c9fc688be" + }, + { + "m_Id": "74b16a0df53f46e8b8c7cde8be1087d5" + }, + { + "m_Id": "3c783196c8f34c28873c38df4d9f7494" + } + ], + "synonyms": [ + "join", + "combine" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "246c3b8388eb4c919907f64f9de02992", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SplitNode", + "m_ObjectId": "26275f9466d54c5b8a15ea5395384960", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Split", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -201.60000610351563, + "y": 37.60002136230469, + "width": 118.4000244140625, + "height": 76.79998016357422 + } + }, + "m_Slots": [ + { + "m_Id": "6c9112fc4cbb482386de3a5e49c04246" + }, + { + "m_Id": "fae8e34e9e57450c89f75161c9f5d12b" + }, + { + "m_Id": "341ccdfbd7d643199743ab116cb959bc" + }, + { + "m_Id": "461e266a0e2848ca901d04828e6c665b" + }, + { + "m_Id": "06b1d302146b4d67bfaa548af6e16bc7" + } + ], + "synonyms": [ + "separate" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "2c68662fd8aa48789d607f56a37819a0", + "m_Title": "", + "m_Content": "The Append node can append components from various different types of inputs into a single vector output.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -933.5000610351563, + "y": 276.5000305175781, + "width": 200.0, + "height": 100.0 + }, + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SliderNode", + "m_ObjectId": "2fd957cca76f4bafb0875e96a8bebab6", + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + "m_Name": "Slider", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1319.0001220703125, + "y": 91.00001525878906, + "width": 232.0, + "height": 146.00001525878906 + } + }, + "m_Slots": [ + { + "m_Id": "4c9bf6a73b0a4d7493634d6971332442" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "31e26d9d077d4df4ba0a168bb277cb40", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "32986f0de7474c6781953e72a6a5f64d", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "341ccdfbd7d643199743ab116cb959bc", + "m_Id": 2, + "m_DisplayName": "G", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "G", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "3ae6ab336c364cdcaf652ff639fe789b", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.ColorNode", + "m_ObjectId": "3b280c12cb7c442a9078a0135031a768", + "m_Group": { + "m_Id": "49442e7afc504a96aa54c221a4199a76" + }, + "m_Name": "Color", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -659.9999389648438, + "y": 16.000003814697266, + "width": 208.0, + "height": 123.19998168945313 + } + }, + "m_Slots": [ + { + "m_Id": "4ca9ded2b7224605a2742f0fd21d2e86" + } + ], + "synonyms": [ + "rgba" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Color": { + "color": { + "r": 0.39800000190734863, + "g": 0.6930000185966492, + "b": 0.5680000185966492, + "a": 1.0 + }, + "mode": 0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "3c783196c8f34c28873c38df4d9f7494", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalUnlitSubTarget", + "m_ObjectId": "3dbc2c1a96a449b5a43d9778ac1f0f60", + "m_KeepLightingVariants": false, + "m_DefaultDecalBlending": true, + "m_DefaultSSAO": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "421c8bcac9eb473890a83b4e579eb5c3", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "4382f1840d20429785522762c47fc272", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "4551b64553d244edbfd5854727833fb3", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "461e266a0e2848ca901d04828e6c665b", + "m_Id": 3, + "m_DisplayName": "B", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PreviewNode", + "m_ObjectId": "47253d9d3d3c4018b79c1bc4bef1d4bb", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Preview", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -70.4000244140625, + "y": 37.60002136230469, + "width": 208.00003051757813, + "height": 277.60003662109375 + } + }, + "m_Slots": [ + { + "m_Id": "3ae6ab336c364cdcaf652ff639fe789b" + }, + { + "m_Id": "31e26d9d077d4df4ba0a168bb277cb40" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Width": 208.0, + "m_Height": 208.0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "48377aa648cf4e79b754a6317af8e747", + "m_ActiveSubTarget": { + "m_Id": "dd5f6b0ddd374de9829b7c396be880c0" + }, + "m_Datas": [ + { + "m_Id": "4ad1701da82b4a5b936e8145496974d8" + }, + { + "m_Id": "8b91cd4b3add49eab4a83c2fc15c60ac" + }, + { + "m_Id": "d8c5eead9806497499757ba472b0bc0f" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false, + "m_SupportLineRendering": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "48c980cfa5f849b7b7b3236c9fc688be", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "49442e7afc504a96aa54c221a4199a76", + "m_Title": "Alpha Overwrite", + "m_Position": { + "x": -685.5999755859375, + "y": -44.79998779296875 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "4ad1701da82b4a5b936e8145496974d8", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_TransparentPerPixelSorting": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "4c9bf6a73b0a4d7493634d6971332442", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "4ca9ded2b7224605a2742f0fd21d2e86", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "53276f50eec04c4d93262e0f1ce787b7", + "m_Id": 3, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 2, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "535199153a2540c09953b37c369e37b2", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "56f49e285c82413996c6838e2522ae4b", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "6072a260af96487989792637c6097d81", + "m_Id": 0, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "68bc63adb418480cbc0cafc20bde6486", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "6b3994bb6b1e4fde9b51ed9ffa5fc0d5" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInUnlitSubTarget", + "m_ObjectId": "6b3994bb6b1e4fde9b51ed9ffa5fc0d5" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "6c9112fc4cbb482386de3a5e49c04246", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "6daa12acda5b451793069c97d65513a3", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "70ed19b50859462abb1fb31a0031967b", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "72a558644eac45a7ab5c381d6b8be806", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "73f779c0bdd84100bd153206cb3fe7f2", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "74b16a0df53f46e8b8c7cde8be1087d5", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.AppendVectorNode", + "m_ObjectId": "7edbe96ce50f4413bcebe4aab53cebf9", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Append", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -419.7663269042969, + "y": 37.83367156982422, + "width": 208.0, + "height": 301.6000061035156 + } + }, + "m_Slots": [ + { + "m_Id": "70ed19b50859462abb1fb31a0031967b" + }, + { + "m_Id": "b93423b34c0d46ae98046afe76d0943a" + }, + { + "m_Id": "c2e56c9e6ffb499e98f6d8f704b82f17" + } + ], + "synonyms": [ + "join", + "combine" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "7fd982932a854caaa0a2c47792d66963", + "m_Title": "", + "m_Content": "The Append node can be use to append a float or vector value to an other float or vector value, with a maximum of 4 combined channels.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -1585.60009765625, + "y": 20.799999237060547, + "width": 200.0, + "height": 170.39999389648438 + }, + "m_Group": { + "m_Id": "baa56fadc05a49ea87859f9e6767ee42" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "802221319818402e9440bebbd036f3b7", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "ff7e38ad362249f9a34112ac97ef065c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "8b91cd4b3add49eab4a83c2fc15c60ac", + "m_MaterialNeedsUpdateHash": 0, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_DebugSymbols": false, + "m_Version": 2, + "inspectorFoldoutMask": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "948d7d8cb87844e192fde60c790675f5", + "m_Title": "", + "m_Content": "You can use the maximum of 3 channels input limit of the Append node to easily overwrite the alpha of a Vector4 value.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -436.79998779296875, + "y": 202.39999389648438, + "width": 200.0, + "height": 142.40000915527344 + }, + "m_Group": { + "m_Id": "49442e7afc504a96aa54c221a4199a76" + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "9857d69dfb32495ab6160d974eea695d", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "3dbc2c1a96a449b5a43d9778ac1f0f60" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_DisableTint": false, + "m_Sort3DAs2DCompatible": false, + "m_AdditionalMotionVectorMode": 0, + "m_AlembicMotionVectors": false, + "m_SupportsLODCrossFade": false, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "9ca885a167d44cc0b900d87b7a19f87c", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.AppendVectorNode", + "m_ObjectId": "9f7a3f56456c4a7387c90bbd70b4e76c", + "m_Group": { + "m_Id": "baa56fadc05a49ea87859f9e6767ee42" + }, + "m_Name": "Append", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1728.0, + "y": 32.799991607666016, + "width": 127.199951171875, + "height": 117.60003662109375 + } + }, + "m_Slots": [ + { + "m_Id": "535199153a2540c09953b37c369e37b2" + }, + { + "m_Id": "4551b64553d244edbfd5854727833fb3" + }, + { + "m_Id": "4382f1840d20429785522762c47fc272" + } + ], + "synonyms": [ + "join", + "combine" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "a86fd2dbe5b84c7bb1fa59addf1b46d2", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "a990d727bbc94d128f59d2f7f79cd554" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "a990d727bbc94d128f59d2f7f79cd554", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "aaa285eb61084de6a2e4c74dd14b132b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "73f779c0bdd84100bd153206cb3fe7f2" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RectangleNode", + "m_ObjectId": "ad104ced631942eaaa340b0672bf4872", + "m_Group": { + "m_Id": "49442e7afc504a96aa54c221a4199a76" + }, + "m_Name": "Rectangle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -604.7999267578125, + "y": 144.8000030517578, + "width": 152.79998779296875, + "height": 174.3999786376953 + } + }, + "m_Slots": [ + { + "m_Id": "6072a260af96487989792637c6097d81" + }, + { + "m_Id": "063b358aa26a4abe82960826d453c0f1" + }, + { + "m_Id": "cdd7a15f9fea4721aef667758b344c8b" + }, + { + "m_Id": "53276f50eec04c4d93262e0f1ce787b7" + } + ], + "synonyms": [ + "square" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_ClampType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "b15e5484768949429eac99779c886569", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "72a558644eac45a7ab5c381d6b8be806" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "b6b433a517334abe98afacd485c86ad4", + "m_Name": "", + "m_ChildObjectList": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1Node", + "m_ObjectId": "b84fa87d4eae4d91bb8635310ef8160b", + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + "m_Name": "Float", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1212.5, + "y": 14.000032424926758, + "width": 125.4998779296875, + "height": 76.99998474121094 + } + }, + "m_Slots": [ + { + "m_Id": "d8e59541a3744fd0ae2ffd1a734579f0" + }, + { + "m_Id": "246c3b8388eb4c919907f64f9de02992" + } + ], + "synonyms": [ + "Vector 1", + "1", + "v1", + "vec1", + "scalar" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": 0.0, + "m_ConstIntMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "b93423b34c0d46ae98046afe76d0943a", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "baa56fadc05a49ea87859f9e6767ee42", + "m_Title": "The Basics", + "m_Position": { + "x": -1753.5999755859375, + "y": -40.0000114440918 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.AppendVectorNode", + "m_ObjectId": "be4df4a548cc4e51864143b04be25df0", + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + "m_Name": "Append", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -887.2000122070313, + "y": 114.39997100830078, + "width": 129.60003662109375, + "height": 117.60001373291016 + } + }, + "m_Slots": [ + { + "m_Id": "56f49e285c82413996c6838e2522ae4b" + }, + { + "m_Id": "421c8bcac9eb473890a83b4e579eb5c3" + }, + { + "m_Id": "e53bdf09fb6c4772985674b7e7ac9ae5" + } + ], + "synonyms": [ + "join", + "combine" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "c2e56c9e6ffb499e98f6d8f704b82f17", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "cdd7a15f9fea4721aef667758b344c8b", + "m_Id": 2, + "m_DisplayName": "Height", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Height", + "m_StageCapability": 3, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "d013bad94eee4798bd677084fab1a635", + "m_Title": "Combining Components From Various Sources", + "m_Position": { + "x": -1344.0, + "y": -46.399993896484375 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitData", + "m_ObjectId": "d8c5eead9806497499757ba472b0bc0f", + "m_EnableShadowMatte": false, + "m_DistortionOnly": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d8e59541a3744fd0ae2ffd1a734579f0", + "m_Id": 1, + "m_DisplayName": "X", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "X", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitSubTarget", + "m_ObjectId": "dd5f6b0ddd374de9829b7c396be880c0" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "e53bdf09fb6c4772985674b7e7ac9ae5", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fae8e34e9e57450c89f75161c9f5d12b", + "m_Id": 1, + "m_DisplayName": "R", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "R", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "fcc99598371c4b3f82f325255d31aba3", + "m_Group": { + "m_Id": "d013bad94eee4798bd677084fab1a635" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1077.60009765625, + "y": 236.8000030517578, + "width": 130.4000244140625, + "height": 119.99998474121094 + } + }, + "m_Slots": [ + { + "m_Id": "9ca885a167d44cc0b900d87b7a19f87c" + }, + { + "m_Id": "32986f0de7474c6781953e72a6a5f64d" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "xz", + "convertedMask": "xz" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "ff7e38ad362249f9a34112ac97ef065c", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Channel/Append.shadergraph.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Channel/Append.shadergraph.meta new file mode 100644 index 00000000000..7a5924bde79 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Channel/Append.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 1686acea44f6b7d428001d374b16611b +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Expression.shadergraph b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Expression.shadergraph new file mode 100644 index 00000000000..0d1fb539838 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Expression.shadergraph @@ -0,0 +1,3863 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "6ede961201ec4e039938d90323345d3a", + "m_Properties": [], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "5090fb8e6f754c109fea9d0dd88f5cc7" + } + ], + "m_Nodes": [ + { + "m_Id": "7bf1166be7484e618d1655ab47cc168b" + }, + { + "m_Id": "46d8a6e8124446e08f11ca6e0b9ed890" + }, + { + "m_Id": "409b2b8a091d48d693c5d89cb4559fc5" + }, + { + "m_Id": "0b8b05b8ca914d99b7c2aa4472897680" + }, + { + "m_Id": "5d5abdbbe4744ca0aab2f61866a9c0c5" + }, + { + "m_Id": "28368c7f65414fb9942fef0abf2620a9" + }, + { + "m_Id": "9bf266b4e7d54be0bb374f24145fc6c5" + }, + { + "m_Id": "5adf8b23af7042fbb9f1171f4122be78" + }, + { + "m_Id": "0893e6232a7848328d0f016d6cf21dd0" + }, + { + "m_Id": "1d908b3017e04363bc2aa45760239fb7" + }, + { + "m_Id": "1e830ee6fee44974b715d6da7c70f98a" + }, + { + "m_Id": "1983a39f6bd14c29a950964c34f52fa8" + }, + { + "m_Id": "3d5a436cff814c9ab68d08bcbf86a17b" + }, + { + "m_Id": "c72f677e5bea4b8280cd589d8860e775" + }, + { + "m_Id": "fafe0aa0d2b24db9ba1b758bb898bf5d" + }, + { + "m_Id": "3377f4a284ca4b3481d3f444ffc17887" + }, + { + "m_Id": "17c4c3c0ab94441abfcc05df0ca0c958" + }, + { + "m_Id": "11fce5465cc9489c95a393a7a4f62164" + }, + { + "m_Id": "d3c0c93859c04326a3ad72b456e98f37" + }, + { + "m_Id": "1b23de12bbb8413da8103687473775fa" + }, + { + "m_Id": "9c70808c03674ae5966a912497533bf9" + }, + { + "m_Id": "73ed7081a75249a6927c970d78e4b1ce" + }, + { + "m_Id": "05372dd024594974b8c4bbdd6f286740" + }, + { + "m_Id": "49fcfa540be24bcc910c4849cf001534" + }, + { + "m_Id": "d2d9c44a951743139d70d685734e78ee" + }, + { + "m_Id": "8d7184b891124e6eb57e8a8fe9242a6a" + }, + { + "m_Id": "68fe71479fec4e42a0b61c214d76dc49" + }, + { + "m_Id": "ef13800c5fa5440aae40182b3ebf74ef" + }, + { + "m_Id": "b75d9b1cf2c447dfa32b91871bb1d8c0" + }, + { + "m_Id": "1e74c3cbca1a4d87af2689069ae08d5e" + } + ], + "m_GroupDatas": [ + { + "m_Id": "587f4a8a5290432a99a318c534102216" + }, + { + "m_Id": "46e22ad50c5e400bafac498eb1ce9baf" + }, + { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + { + "m_Id": "a2c8bdaac83c4158bd79571b707bbd34" + }, + { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + { + "m_Id": "b00a275add7c48d7b290e74740b8966f" + }, + { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + } + ], + "m_StickyNoteDatas": [ + { + "m_Id": "a969794fd7694e05b735f5d87a7c5368" + }, + { + "m_Id": "247130bf3875444f81b20436820239fd" + }, + { + "m_Id": "757f804eeebc48fd9964d980292cdc29" + }, + { + "m_Id": "855af0d3383745da8be9a891f13e564c" + }, + { + "m_Id": "430d8807240a4e4e8ee801c0c8ca299b" + }, + { + "m_Id": "e17b5b973ad84669bfa4e0162defbff5" + }, + { + "m_Id": "f37bf274088a4d4bbb7a7541a09015cd" + }, + { + "m_Id": "a19c45d9e4dd433e82617f6d2eaa239f" + } + ], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "05372dd024594974b8c4bbdd6f286740" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "11fce5465cc9489c95a393a7a4f62164" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "0893e6232a7848328d0f016d6cf21dd0" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1d908b3017e04363bc2aa45760239fb7" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "11fce5465cc9489c95a393a7a4f62164" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fafe0aa0d2b24db9ba1b758bb898bf5d" + }, + "m_SlotId": 4 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "17c4c3c0ab94441abfcc05df0ca0c958" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fafe0aa0d2b24db9ba1b758bb898bf5d" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1983a39f6bd14c29a950964c34f52fa8" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fafe0aa0d2b24db9ba1b758bb898bf5d" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1b23de12bbb8413da8103687473775fa" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "11fce5465cc9489c95a393a7a4f62164" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1d908b3017e04363bc2aa45760239fb7" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1e830ee6fee44974b715d6da7c70f98a" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "1e830ee6fee44974b715d6da7c70f98a" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1983a39f6bd14c29a950964c34f52fa8" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "3377f4a284ca4b3481d3f444ffc17887" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fafe0aa0d2b24db9ba1b758bb898bf5d" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "3d5a436cff814c9ab68d08bcbf86a17b" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "0893e6232a7848328d0f016d6cf21dd0" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5adf8b23af7042fbb9f1171f4122be78" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "9bf266b4e7d54be0bb374f24145fc6c5" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "68fe71479fec4e42a0b61c214d76dc49" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8d7184b891124e6eb57e8a8fe9242a6a" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "73ed7081a75249a6927c970d78e4b1ce" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "d3c0c93859c04326a3ad72b456e98f37" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8d7184b891124e6eb57e8a8fe9242a6a" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1e74c3cbca1a4d87af2689069ae08d5e" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8d7184b891124e6eb57e8a8fe9242a6a" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b75d9b1cf2c447dfa32b91871bb1d8c0" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "9bf266b4e7d54be0bb374f24145fc6c5" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "0893e6232a7848328d0f016d6cf21dd0" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "9c70808c03674ae5966a912497533bf9" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1b23de12bbb8413da8103687473775fa" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "c72f677e5bea4b8280cd589d8860e775" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "0893e6232a7848328d0f016d6cf21dd0" + }, + "m_SlotId": 4 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "d2d9c44a951743139d70d685734e78ee" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "28368c7f65414fb9942fef0abf2620a9" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "d3c0c93859c04326a3ad72b456e98f37" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "05372dd024594974b8c4bbdd6f286740" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "ef13800c5fa5440aae40182b3ebf74ef" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8d7184b891124e6eb57e8a8fe9242a6a" + }, + "m_SlotId": 2 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fafe0aa0d2b24db9ba1b758bb898bf5d" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "0b8b05b8ca914d99b7c2aa4472897680" + }, + "m_SlotId": 0 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 346.99993896484375, + "y": -130.99998474121094 + }, + "m_Blocks": [ + { + "m_Id": "7bf1166be7484e618d1655ab47cc168b" + }, + { + "m_Id": "46d8a6e8124446e08f11ca6e0b9ed890" + }, + { + "m_Id": "409b2b8a091d48d693c5d89cb4559fc5" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 346.99993896484375, + "y": 69.00000762939453 + }, + "m_Blocks": [ + { + "m_Id": "0b8b05b8ca914d99b7c2aa4472897680" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"fileID\":10210,\"guid\":\"0000000000000000e000000000000000\",\"type\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_SubDatas": [], + "m_ActiveTargets": [ + { + "m_Id": "5468ac27d6574da593d00428fddce641" + }, + { + "m_Id": "c14afcd87ebe46a8a770ba66c3b40cde" + }, + { + "m_Id": "54bb74188f1b4f1ebf5c6024d74e7325" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "00903f3479bb4e729f839f3c0c902dd4", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "01a0e476587244b2ab200f8e3b5e9c7f", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "01daccc80f4c4fcab53a5a92ff85bdd9", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "05372dd024594974b8c4bbdd6f286740", + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -564.0, + "y": 939.9999389648438, + "width": 208.0, + "height": 330.99993896484375 + } + }, + "m_Slots": [ + { + "m_Id": "8fb1e00776054b02b07d24736398055f" + }, + { + "m_Id": "ccdaac35a469407bba836575c2ac8088" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_05372dd024594974b8c4bbdd6f286740", + "m_expression": "a+0.5", + "m_type": "float" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "0893e6232a7848328d0f016d6cf21dd0", + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -734.0, + "y": 117.00000762939453, + "width": 145.0, + "height": 219.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "79b5bc8736f64b4ea9d3202399161b10" + }, + { + "m_Id": "29889c8b324f4802b7df10a005ce0c9c" + }, + { + "m_Id": "3baf5853063a4eaa88358a67b9366b3c" + }, + { + "m_Id": "a5c8d8923ef4475f8d6ce12923e856d3" + }, + { + "m_Id": "9338d15259474c138d2c5cc68bc7bc51" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_a4975077783045ba8f663eafcf65bc3f", + "m_expression": "saturate(abs(distance(a, b)-c)-d)", + "m_type": "float2" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "0b8b05b8ca914d99b7c2aa4472897680", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "12f2c2097ee14c7ba3ea5cd3570e9d26" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "11d0628e294a4080a573622b5a0908b3", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "11fce5465cc9489c95a393a7a4f62164", + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -332.0, + "y": 585.0000610351563, + "width": 208.0001220703125, + "height": 355.0 + } + }, + "m_Slots": [ + { + "m_Id": "36510391231940c5a1ae8bbbc13b2943" + }, + { + "m_Id": "3acfcff90fb540cf87f890434dfc8cc9" + }, + { + "m_Id": "8430ce877cd143a7a485f910e57d2a4b" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_11fce5465cc9489c95a393a7a4f62164", + "m_expression": "a > b", + "m_type": "float" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "1265dbb541bd47b5b92f7c930081250a", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "12f2c2097ee14c7ba3ea5cd3570e9d26", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "13a6c1189f154f418f6e3ac4bfcb07d3", + "m_Id": 1, + "m_DisplayName": "Center", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Center", + "m_StageCapability": 3, + "m_Value": { + "x": 0.5, + "y": 0.5 + }, + "m_DefaultValue": { + "x": 0.5, + "y": 0.5 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInUnlitSubTarget", + "m_ObjectId": "14a5c917c8ca4236a2338d2e39a7ae3d" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "15db05292fd1438bbbbb383aab082e6a", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.ColorNode", + "m_ObjectId": "17c4c3c0ab94441abfcc05df0ca0c958", + "m_Group": { + "m_Id": "a2c8bdaac83c4158bd79571b707bbd34" + }, + "m_Name": "Color", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -26.999893188476563, + "y": -56.000022888183594, + "width": 207.9999542236328, + "height": 125.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "da661ea92c7146c8a40aee1c7118ab0c" + } + ], + "synonyms": [ + "rgba" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Color": { + "color": { + "r": 1.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + }, + "mode": 0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.OneMinusNode", + "m_ObjectId": "1983a39f6bd14c29a950964c34f52fa8", + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + "m_Name": "One Minus", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -332.0, + "y": 117.00000762939453, + "width": 208.0001220703125, + "height": 278.0 + } + }, + "m_Slots": [ + { + "m_Id": "c376022c6b7347529cc702d95bb7cf6e" + }, + { + "m_Id": "7734c2c589f543d1b900cd51a7311246" + } + ], + "synonyms": [ + "complement", + "invert", + "opposite" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "1b23de12bbb8413da8103687473775fa", + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -564.0, + "y": 585.0000610351563, + "width": 208.00006103515625, + "height": 355.0 + } + }, + "m_Slots": [ + { + "m_Id": "ae4be77803e64b568851a29b8da26a48" + }, + { + "m_Id": "f64de38c137f4eb2bd9231dcf988068c" + }, + { + "m_Id": "be17bdeb461e4df58c8f2847c9156fbd" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_1b23de12bbb8413da8103687473775fa", + "m_expression": "frac(a/b)", + "m_type": "float" + } + } + ] + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "1d908b3017e04363bc2aa45760239fb7", + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -589.0, + "y": 117.00000762939453, + "width": 128.00003051757813, + "height": 122.00000762939453 + } + }, + "m_Slots": [ + { + "m_Id": "f9238fb726884634b83ecb0f6dd24980" + }, + { + "m_Id": "15db05292fd1438bbbbb383aab082e6a" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "x", + "convertedMask": "x" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "1e74c3cbca1a4d87af2689069ae08d5e", + "m_Group": { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2116.999755859375, + "y": 888.9999389648438, + "width": 207.9998779296875, + "height": 306.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "7ff3fdb3fc784d4faf112c2afc5edc41" + }, + { + "m_Id": "00903f3479bb4e729f839f3c0c902dd4" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "w", + "convertedMask": "w" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SmoothstepNode", + "m_ObjectId": "1e830ee6fee44974b715d6da7c70f98a", + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + "m_Name": "Smoothstep", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -460.9999694824219, + "y": 117.00000762939453, + "width": 128.00009155273438, + "height": 94.00000762939453 + } + }, + "m_Slots": [ + { + "m_Id": "ae84259b3af24c18b386d7471e947255" + }, + { + "m_Id": "4cda4e6b1da04086bca0d2c49e59dfad" + }, + { + "m_Id": "462e6149e950407e9d6ecce8b834271e" + }, + { + "m_Id": "a830bf87c94f488785d2c4f4a187d2f7" + } + ], + "synonyms": [ + "curve" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "247130bf3875444f81b20436820239fd", + "m_Title": "", + "m_Content": "In this basic example, we make time loop every 5 seconds by using frac(time/5)*5.\n\nYou can use any HLSL intrinsic functions.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2174.0, + "y": 319.0, + "width": 200.0, + "height": 123.0 + }, + "m_Group": { + "m_Id": "587f4a8a5290432a99a318c534102216" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "28368c7f65414fb9942fef0abf2620a9", + "m_Group": { + "m_Id": "587f4a8a5290432a99a318c534102216" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2114.999755859375, + "y": 117.0, + "width": 145.0, + "height": 170.99996948242188 + } + }, + "m_Slots": [ + { + "m_Id": "b0760f3a0cc44538a2a34dce8ac415a4" + }, + { + "m_Id": "5d4d586f5bc8404d8046c8a72bbadab1" + }, + { + "m_Id": "aa3a6a61556b4262afb4f2aeea83bb6e" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_28368c7f65414fb9942fef0abf2620a9", + "m_expression": "frac(a/b)*b", + "m_type": "float" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "29889c8b324f4802b7df10a005ce0c9c", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "2f659f2099ec4ce2a96d29685c0e281b", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "30c0fdcafdab4649899752ae229487b9", + "m_Id": 4, + "m_DisplayName": "Smooth Delta", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Smooth Delta", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "31bfb53402b942e39708e0ecce074e3a", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.ColorNode", + "m_ObjectId": "3377f4a284ca4b3481d3f444ffc17887", + "m_Group": { + "m_Id": "a2c8bdaac83c4158bd79571b707bbd34" + }, + "m_Name": "Color", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -26.999893188476563, + "y": -181.00001525878906, + "width": 207.9999542236328, + "height": 124.99999237060547 + } + }, + "m_Slots": [ + { + "m_Id": "bc32c278ea964f779e418bdbb9ecb4bb" + } + ], + "synonyms": [ + "rgba" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Color": { + "color": { + "r": 0.08500000089406967, + "g": 0.08500000089406967, + "b": 0.08500000089406967, + "a": 1.0 + }, + "mode": 0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "36510391231940c5a1ae8bbbc13b2943", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "36b7a61f099c48d39c4964ac9ec02d34", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "377a7057554547549b51bbcb0ea682f4", + "m_Id": 0, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "3acfcff90fb540cf87f890434dfc8cc9", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "3baf5853063a4eaa88358a67b9366b3c", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SliderNode", + "m_ObjectId": "3d5a436cff814c9ab68d08bcbf86a17b", + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + "m_Name": "Slider", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1107.0, + "y": 190.0, + "width": 232.0, + "height": 146.00003051757813 + } + }, + "m_Slots": [ + { + "m_Id": "f2c14ac1b70245898e12c918d965a839" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.2919999957084656, + "y": 0.0, + "z": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "3f9a9a8bd4ba475d9f13bc35ac40f84d", + "m_Id": 3, + "m_DisplayName": "Delta Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Delta Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "409b2b8a091d48d693c5d89cb4559fc5", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "fbb76735c8f541b790e2bd2f33a9ff16" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "420862e9f1e942c3be60d9c8d585a2d8", + "m_Id": 4, + "m_DisplayName": "Smooth Delta", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Smooth Delta", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "430d8807240a4e4e8ee801c0c8ca299b", + "m_Title": "", + "m_Content": "Quickly remap UVs from 0,1 to -1,1", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -1612.0, + "y": 256.0, + "width": 200.0, + "height": 92.93133544921875 + }, + "m_Group": { + "m_Id": "46e22ad50c5e400bafac498eb1ce9baf" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "4403773f925142888d9ccefde293c62c", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitData", + "m_ObjectId": "44f2536efb364e8db6fafa129c0747bc", + "m_EnableShadowMatte": false, + "m_DistortionOnly": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "462e6149e950407e9d6ecce8b834271e", + "m_Id": 2, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "46d8a6e8124446e08f11ca6e0b9ed890", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "4403773f925142888d9ccefde293c62c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "46e22ad50c5e400bafac498eb1ce9baf", + "m_Title": "Remap UVs", + "m_Position": { + "x": -1637.0, + "y": 57.999996185302734 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "49fcfa540be24bcc910c4849cf001534", + "m_Group": { + "m_Id": "b00a275add7c48d7b290e74740b8966f" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2509.999755859375, + "y": 117.0, + "width": 145.0, + "height": 195.0 + } + }, + "m_Slots": [ + { + "m_Id": "b4de3d41c6544136ae3bbb66bb7a31ca" + }, + { + "m_Id": "dc736c81f35f41e7b3a7b4daf37e2e74" + }, + { + "m_Id": "692b96158dc94807b1fa1d3f551fa601" + }, + { + "m_Id": "4ca07ff49d074eb3b4eecbdfbc52b5ef" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_28368c7f65414fb9942fef0abf2620a9", + "m_expression": "a+b*c", + "m_type": "float" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "4ca07ff49d074eb3b4eecbdfbc52b5ef", + "m_Id": 3, + "m_DisplayName": "c", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "c", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "4cda4e6b1da04086bca0d2c49e59dfad", + "m_Id": 1, + "m_DisplayName": "Edge2", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Edge2", + "m_StageCapability": 3, + "m_Value": { + "x": 0.019999999552965164, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "4f19fcaf7401421795962896e04cd22c", + "m_Id": 4, + "m_DisplayName": "d", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "d", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "5090fb8e6f754c109fea9d0dd88f5cc7", + "m_Name": "", + "m_ChildObjectList": [] +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "5468ac27d6574da593d00428fddce641", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "14a5c917c8ca4236a2338d2e39a7ae3d" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "54bb74188f1b4f1ebf5c6024d74e7325", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "95e6edf6bfa1454ca0673681bc8ac466" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_DisableTint": false, + "m_Sort3DAs2DCompatible": false, + "m_AdditionalMotionVectorMode": 0, + "m_AlembicMotionVectors": false, + "m_SupportsLODCrossFade": false, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "587f4a8a5290432a99a318c534102216", + "m_Title": "Intrinsic", + "m_Position": { + "x": -2303.58935546875, + "y": 58.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVNode", + "m_ObjectId": "5adf8b23af7042fbb9f1171f4122be78", + "m_Group": { + "m_Id": "46e22ad50c5e400bafac498eb1ce9baf" + }, + "m_Name": "UV", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1552.0001220703125, + "y": 117.00000762939453, + "width": 145.0001220703125, + "height": 127.99999237060547 + } + }, + "m_Slots": [ + { + "m_Id": "2f659f2099ec4ce2a96d29685c0e281b" + } + ], + "synonyms": [ + "texcoords", + "coords", + "coordinates" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_OutputChannel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5d4d586f5bc8404d8046c8a72bbadab1", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "5d5abdbbe4744ca0aab2f61866a9c0c5", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1010.0, + "y": -190.00001525878906, + "width": 145.0, + "height": 147.00001525878906 + } + }, + "m_Slots": [ + { + "m_Id": "fc9907b91c3f4cb9a3652569e03d54f1" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "Expression", + "m_expression": "", + "m_type": "float" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "603723f283304d958d29251f9b153ba2", + "m_Title": "Signed Distance Functions", + "m_Position": { + "x": -1132.0, + "y": 57.999996185302734 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.ColorNode", + "m_ObjectId": "68fe71479fec4e42a0b61c214d76dc49", + "m_Group": { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + }, + "m_Name": "Color", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2628.999755859375, + "y": 582.9999389648438, + "width": 208.0, + "height": 125.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "736573d4fec4457e9cd2150c3560347c" + } + ], + "synonyms": [ + "rgba" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Color": { + "color": { + "r": 1.0, + "g": 0.0, + "b": 0.0, + "a": 1.0 + }, + "mode": 0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "692b96158dc94807b1fa1d3f551fa601", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "696d6db543e445a3a157d9e91c017eca", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "6a614111e8db43b98322900231411333", + "m_Id": 0, + "m_DisplayName": "Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "736573d4fec4457e9cd2150c3560347c", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PolarCoordinatesNode", + "m_ObjectId": "73ed7081a75249a6927c970d78e4b1ce", + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + "m_Name": "Polar Coordinates", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -960.0000610351563, + "y": 940.0000610351563, + "width": 188.00006103515625, + "height": 166.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "377a7057554547549b51bbcb0ea682f4" + }, + { + "m_Id": "13a6c1189f154f418f6e3ac4bfcb07d3" + }, + { + "m_Id": "b8cd57254c1a410eb9de59fdfcde42cf" + }, + { + "m_Id": "bc250a833fa747469c23f1a56c56ceb5" + }, + { + "m_Id": "f30de325a8a54178af84b524a75b4a9d" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "757f804eeebc48fd9964d980292cdc29", + "m_Title": "", + "m_Content": "In this basic example, we're \nadding the product of B and C to A.\nYou can use math operators such as +, -, *, /, as well as comparisons like ==, <, >.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2568.0, + "y": 317.0, + "width": 200.0, + "height": 123.0 + }, + "m_Group": { + "m_Id": "b00a275add7c48d7b290e74740b8966f" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "7734c2c589f543d1b900cd51a7311246", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "79b5bc8736f64b4ea9d3202399161b10", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7bf1166be7484e618d1655ab47cc168b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "cabc1f6561334be2aba206fcc517a02c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "7ff3fdb3fc784d4faf112c2afc5edc41", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "8430ce877cd143a7a485f910e57d2a4b", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "855af0d3383745da8be9a891f13e564c", + "m_Title": "", + "m_Content": "You can swizzle input components and reconstruct new vectors.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2350.0, + "y": 771.0, + "width": 204.0, + "height": 100.0 + }, + "m_Group": { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "8d7184b891124e6eb57e8a8fe9242a6a", + "m_Group": { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2287.999755859375, + "y": 582.9999389648438, + "width": 145.0, + "height": 171.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "31bfb53402b942e39708e0ecce074e3a" + }, + { + "m_Id": "a9fa09e9ab774788b608cfd7bb049962" + }, + { + "m_Id": "e356891d5e30459e916361e2b590b303" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_8d7184b891124e6eb57e8a8fe9242a6a", + "m_expression": "float4(a.rgb, b.a)", + "m_type": "float4" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitSubTarget", + "m_ObjectId": "8f7ffd8c635b4de086a7fdd8a4bc2080" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "8fb1e00776054b02b07d24736398055f", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "9148468d683544e1a6ed2330e7ada8ca", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "91b0c18cfe494e3ba5e320466195e37f", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "9338d15259474c138d2c5cc68bc7bc51", + "m_Id": 4, + "m_DisplayName": "d", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "d", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "93c291dfe0dc42c69f9f7d751c539650", + "m_Title": "Timing", + "m_Position": { + "x": -984.9999389648438, + "y": 526.0 + } +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalUnlitSubTarget", + "m_ObjectId": "95e6edf6bfa1454ca0673681bc8ac466", + "m_KeepLightingVariants": false, + "m_DefaultDecalBlending": true, + "m_DefaultSSAO": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "9bf266b4e7d54be0bb374f24145fc6c5", + "m_Group": { + "m_Id": "46e22ad50c5e400bafac498eb1ce9baf" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1407.0, + "y": 117.00000762939453, + "width": 208.0, + "height": 331.0 + } + }, + "m_Slots": [ + { + "m_Id": "d27439c5968b48cb87e24a00f8ac703b" + }, + { + "m_Id": "91b0c18cfe494e3ba5e320466195e37f" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_cdfa2f1bf0994baeb59835fce9261e8f", + "m_expression": "a * 2 - 1", + "m_type": "float2" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TimeNode", + "m_ObjectId": "9c70808c03674ae5966a912497533bf9", + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + "m_Name": "Time", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -772.0, + "y": 585.0000610351563, + "width": 78.99993896484375, + "height": 77.0 + } + }, + "m_Slots": [ + { + "m_Id": "ba0e65845dec43ea9f2a369fcc5281d6" + }, + { + "m_Id": "a51faa06346540158981fd9b31a78a1c" + }, + { + "m_Id": "c8e8f3f72d2244f7a174054efdca54c0" + }, + { + "m_Id": "ee56cef243eb4407a38b9aa4bcd293a3" + }, + { + "m_Id": "420862e9f1e942c3be60d9c8d585a2d8" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a052daa6679846fbbba8cb77fcc409ca", + "m_Id": 1, + "m_DisplayName": "Sine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Sine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "a19c45d9e4dd433e82617f6d2eaa239f", + "m_Title": "", + "m_Content": "Combine several inputs with different weights using simple math.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -20.0, + "y": 485.0, + "width": 194.0, + "height": 111.99365234375 + }, + "m_Group": { + "m_Id": "a2c8bdaac83c4158bd79571b707bbd34" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "a252687d5f5c49da955fc66968eebac8", + "m_MaterialNeedsUpdateHash": 0, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_DebugSymbols": false, + "m_Version": 2, + "inspectorFoldoutMask": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "a2c8bdaac83c4158bd79571b707bbd34", + "m_Title": "Custom Mix", + "m_Position": { + "x": -52.00010681152344, + "y": -240.00006103515625 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "a300931a25914bdfb9693626948d22ca", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_TransparentPerPixelSorting": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a51faa06346540158981fd9b31a78a1c", + "m_Id": 1, + "m_DisplayName": "Sine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Sine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "a5c8d8923ef4475f8d6ce12923e856d3", + "m_Id": 3, + "m_DisplayName": "c", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "c", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "a830bf87c94f488785d2c4f4a187d2f7", + "m_Id": 3, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "a969794fd7694e05b735f5d87a7c5368", + "m_Title": "Expression Node", + "m_Content": "The Expression Node allows you to gather several operations in one node, without having to write and setup a Custom Function.\n\nYou can use math, HLSL intrinsic functions, swizzling and vector construction.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -817.0, + "y": -186.0, + "width": 248.0, + "height": 140.7496795654297 + }, + "m_Group": { + "m_Id": "" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "a9fa09e9ab774788b608cfd7bb049962", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "aa3a6a61556b4262afb4f2aeea83bb6e", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": 5.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "ab2734bbfcc54a4dbe88c42cc7f20198", + "m_Id": 3, + "m_DisplayName": "c", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "c", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ae4be77803e64b568851a29b8da26a48", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ae84259b3af24c18b386d7471e947255", + "m_Id": 0, + "m_DisplayName": "Edge1", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Edge1", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "b00a275add7c48d7b290e74740b8966f", + "m_Title": "Math", + "m_Position": { + "x": -2592.58935546875, + "y": 58.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b0760f3a0cc44538a2a34dce8ac415a4", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b4de3d41c6544136ae3bbb66bb7a31ca", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "b75d9b1cf2c447dfa32b91871bb1d8c0", + "m_Group": { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2116.999755859375, + "y": 582.9999389648438, + "width": 207.9998779296875, + "height": 306.0 + } + }, + "m_Slots": [ + { + "m_Id": "01a0e476587244b2ab200f8e3b5e9c7f" + }, + { + "m_Id": "01daccc80f4c4fcab53a5a92ff85bdd9" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "xyz", + "convertedMask": "xyz" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b8cd57254c1a410eb9de59fdfcde42cf", + "m_Id": 2, + "m_DisplayName": "Radial Scale", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "RadialScale", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ba0e65845dec43ea9f2a369fcc5281d6", + "m_Id": 0, + "m_DisplayName": "Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "bc250a833fa747469c23f1a56c56ceb5", + "m_Id": 3, + "m_DisplayName": "Length Scale", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "LengthScale", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "bc32c278ea964f779e418bdbb9ecb4bb", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "be17bdeb461e4df58c8f2847c9156fbd", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": 2.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "bf8a5e49f545495eb2ebec3b5a04e09b", + "m_Id": 2, + "m_DisplayName": "Cosine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Cosine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "c14afcd87ebe46a8a770ba66c3b40cde", + "m_ActiveSubTarget": { + "m_Id": "8f7ffd8c635b4de086a7fdd8a4bc2080" + }, + "m_Datas": [ + { + "m_Id": "a300931a25914bdfb9693626948d22ca" + }, + { + "m_Id": "a252687d5f5c49da955fc66968eebac8" + }, + { + "m_Id": "44f2536efb364e8db6fafa129c0747bc" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false, + "m_SupportLineRendering": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "c376022c6b7347529cc702d95bb7cf6e", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SliderNode", + "m_ObjectId": "c72f677e5bea4b8280cd589d8860e775", + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + }, + "m_Name": "Slider", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1107.0, + "y": 336.0000305175781, + "width": 232.0, + "height": 146.0 + } + }, + "m_Slots": [ + { + "m_Id": "11d0628e294a4080a573622b5a0908b3" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.04500000178813934, + "y": 0.0, + "z": 0.20000000298023224 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "c8e8f3f72d2244f7a174054efdca54c0", + "m_Id": 2, + "m_DisplayName": "Cosine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Cosine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "cabc1f6561334be2aba206fcc517a02c", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ccdaac35a469407bba836575c2ac8088", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "d27439c5968b48cb87e24a00f8ac703b", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TimeNode", + "m_ObjectId": "d2d9c44a951743139d70d685734e78ee", + "m_Group": { + "m_Id": "587f4a8a5290432a99a318c534102216" + }, + "m_Name": "Time", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -2278.999755859375, + "y": 117.0, + "width": 79.0, + "height": 77.0 + } + }, + "m_Slots": [ + { + "m_Id": "6a614111e8db43b98322900231411333" + }, + { + "m_Id": "a052daa6679846fbbba8cb77fcc409ca" + }, + { + "m_Id": "bf8a5e49f545495eb2ebec3b5a04e09b" + }, + { + "m_Id": "3f9a9a8bd4ba475d9f13bc35ac40f84d" + }, + { + "m_Id": "30c0fdcafdab4649899752ae229487b9" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "d3022ff6f14d4783b484ba8f5e7a31ee", + "m_Title": "Swizzling and Vector Construction", + "m_Position": { + "x": -2653.589111328125, + "y": 524.0 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "d3c0c93859c04326a3ad72b456e98f37", + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -772.0, + "y": 940.0000610351563, + "width": 208.0, + "height": 306.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "9148468d683544e1a6ed2330e7ada8ca" + }, + { + "m_Id": "fe79f0ab356e48b8b71daf41e6990e4a" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "y", + "convertedMask": "y" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "da661ea92c7146c8a40aee1c7118ab0c", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "dc736c81f35f41e7b3a7b4daf37e2e74", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "e17b5b973ad84669bfa4e0162defbff5", + "m_Title": "", + "m_Content": "Use intrinsic functions (distance, abs, saturate) on one line to make a signed distance function.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -732.0, + "y": 339.0, + "width": 325.0, + "height": 56.43115234375 + }, + "m_Group": { + "m_Id": "603723f283304d958d29251f9b153ba2" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "e356891d5e30459e916361e2b590b303", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ee56cef243eb4407a38b9aa4bcd293a3", + "m_Id": 3, + "m_DisplayName": "Delta Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Delta Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "ee8387a37c904cf18354747eb1785b44", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.ColorNode", + "m_ObjectId": "ef13800c5fa5440aae40182b3ebf74ef", + "m_Group": { + "m_Id": "d3022ff6f14d4783b484ba8f5e7a31ee" + }, + "m_Name": "Color", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2628.999755859375, + "y": 708.0, + "width": 208.0, + "height": 125.0 + } + }, + "m_Slots": [ + { + "m_Id": "1265dbb541bd47b5b92f7c930081250a" + } + ], + "synonyms": [ + "rgba" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Color": { + "color": { + "r": 0.15517449378967285, + "g": 1.0, + "b": 0.0, + "a": 0.4117647111415863 + }, + "mode": 0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f2c14ac1b70245898e12c918d965a839", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "f30de325a8a54178af84b524a75b4a9d", + "m_Id": 4, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "f37bf274088a4d4bbb7a7541a09015cd", + "m_Title": "", + "m_Content": "Gather simple or more complex timing operations in one or a few nodes.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -752.0, + "y": 698.0, + "width": 165.0, + "height": 100.0 + }, + "m_Group": { + "m_Id": "93c291dfe0dc42c69f9f7d751c539650" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f64de38c137f4eb2bd9231dcf988068c", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f9238fb726884634b83ecb0f6dd24980", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExpressionNode", + "m_ObjectId": "fafe0aa0d2b24db9ba1b758bb898bf5d", + "m_Group": { + "m_Id": "a2c8bdaac83c4158bd79571b707bbd34" + }, + "m_Name": "Expression", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -26.999893188476563, + "y": 69.00000762939453, + "width": 207.9999542236328, + "height": 403.0000305175781 + } + }, + "m_Slots": [ + { + "m_Id": "696d6db543e445a3a157d9e91c017eca" + }, + { + "m_Id": "36b7a61f099c48d39c4964ac9ec02d34" + }, + { + "m_Id": "ee8387a37c904cf18354747eb1785b44" + }, + { + "m_Id": "ab2734bbfcc54a4dbe88c42cc7f20198" + }, + { + "m_Id": "4f19fcaf7401421795962896e04cd22c" + } + ], + "synonyms": [ + "equation", + "calculation", + "inline", + "code" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ExpressionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_name": "ExpressionNode_71ce746883b1478bbee6a241ba0a3b68", + "m_expression": "a+b*c*d", + "m_type": "float3" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "fbb76735c8f541b790e2bd2f33a9ff16", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fc9907b91c3f4cb9a3652569e03d54f1", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fe79f0ab356e48b8b71daf41e6990e4a", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Expression.shadergraph.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Expression.shadergraph.meta new file mode 100644 index 00000000000..03687992d8b --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Expression.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: d0bf1fc66f4dca84080ee253f17c2ac5 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ReflectedFunction.shadergraph b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ReflectedFunction.shadergraph new file mode 100644 index 00000000000..405d3ed71d9 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ReflectedFunction.shadergraph @@ -0,0 +1,5645 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "6ede961201ec4e039938d90323345d3a", + "m_Properties": [], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "5090fb8e6f754c109fea9d0dd88f5cc7" + } + ], + "m_Nodes": [ + { + "m_Id": "7bf1166be7484e618d1655ab47cc168b" + }, + { + "m_Id": "46d8a6e8124446e08f11ca6e0b9ed890" + }, + { + "m_Id": "409b2b8a091d48d693c5d89cb4559fc5" + }, + { + "m_Id": "0b8b05b8ca914d99b7c2aa4472897680" + }, + { + "m_Id": "7b376931c64f4a92b0449f05e3e5d1d4" + }, + { + "m_Id": "cbddd487454e49788cb3d119498dafd1" + }, + { + "m_Id": "8e9e4a47bfb54f3c9a91a8068ba31bde" + }, + { + "m_Id": "410660cb18cf403d801ad9a36884937d" + }, + { + "m_Id": "866e8721665647028258218cf8168271" + }, + { + "m_Id": "03989c994fd54d23a3ea863932c0f145" + }, + { + "m_Id": "7ffa0a34c89840b897b9ed9ad5773797" + }, + { + "m_Id": "99d8a15ec91744c3a69805bc3be3d4df" + }, + { + "m_Id": "d76c45512a9b48aca250bb4ebbbd8aef" + }, + { + "m_Id": "cc6264bba642465bbf1a3cc6d2059738" + }, + { + "m_Id": "a0cd74d6fe61452fa1a72093bbc050d3" + }, + { + "m_Id": "d3d1c5f6c6fb4826876c7643db1bf7e9" + }, + { + "m_Id": "fbcd31f799f446459eb6e4427e6dd5b1" + }, + { + "m_Id": "89d56a2f38124a56b9ef778824c610ec" + }, + { + "m_Id": "643cc3d3f0544d9d8cf1fef5742d4c93" + }, + { + "m_Id": "bcc261bee5bd4d7180f8984d4ab9c52e" + }, + { + "m_Id": "dce8a6099a7243e48d878215d429b0ef" + }, + { + "m_Id": "950c1f682d044de7895cef5db917a787" + }, + { + "m_Id": "516817136f5b427eb1b684c1f4eeae76" + }, + { + "m_Id": "cb1e49334a344b4ab4a0f8f1dc4a4cf5" + }, + { + "m_Id": "770782c726d64429b5b4d2c1a5e1d912" + }, + { + "m_Id": "8103ffdc531c40c1964c4712ea2b6f00" + }, + { + "m_Id": "45eeae7aab4d4c499805960f568e95fc" + }, + { + "m_Id": "e853b9e06a5e42c0bc752d6d77a80408" + }, + { + "m_Id": "f45b51da2803449c83859952e28e4b85" + }, + { + "m_Id": "8dbc4d96191f4d03a1f3765d98729bb2" + }, + { + "m_Id": "3a4010eed5544bde9b3d9d4e824c5415" + }, + { + "m_Id": "30812e910c88404f867da8d64db34643" + }, + { + "m_Id": "b9450bb77d1a4e1f9db31b3c546072ed" + }, + { + "m_Id": "3e71080c9bc34bc6ab87ba7d67b7869a" + }, + { + "m_Id": "1f05f16528be403ea2335093d53b3ea2" + }, + { + "m_Id": "a3bb0e41fac940948839fcbacdb233d2" + }, + { + "m_Id": "3f5900b6dbad4f10a972758d7676197f" + } + ], + "m_GroupDatas": [ + { + "m_Id": "587f4a8a5290432a99a318c534102216" + }, + { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + { + "m_Id": "0917fa34a2534125a5502fdaf5d26666" + }, + { + "m_Id": "395e687c1c3844b5928a6c0f9b0db35d" + }, + { + "m_Id": "fb7001c484e442778b74cc94d1d09c4e" + }, + { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + { + "m_Id": "a336489e22914f4a9470f05854e32387" + }, + { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + }, + { + "m_Id": "45d837fe36d5481d96d2af7ed2d45e80" + } + ], + "m_StickyNoteDatas": [ + { + "m_Id": "a969794fd7694e05b735f5d87a7c5368" + }, + { + "m_Id": "247130bf3875444f81b20436820239fd" + }, + { + "m_Id": "a9d5d744fb7b4a7e9ab4f9bfa0cdc1a7" + }, + { + "m_Id": "757c17bba5e44b679138da67f0388ca8" + }, + { + "m_Id": "28e6b95fce0143b59bf91030eede55e9" + }, + { + "m_Id": "dfb68d35b2db4a95873ed16d388b2e30" + }, + { + "m_Id": "401ff46c9a1641aea7a99cbd40d6e205" + }, + { + "m_Id": "82547848cbc445c597d67f716f175fe4" + }, + { + "m_Id": "8fe8c3aac55d450ca3c8d3e6bc7c46bc" + }, + { + "m_Id": "f6737123fbeb437b97d2046900252fe0" + }, + { + "m_Id": "f10027bf57de454cb3fb662a899d58b1" + } + ], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "03989c994fd54d23a3ea863932c0f145" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "866e8721665647028258218cf8168271" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "3a4010eed5544bde9b3d9d4e824c5415" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f45b51da2803449c83859952e28e4b85" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "3e71080c9bc34bc6ab87ba7d67b7869a" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "1f05f16528be403ea2335093d53b3ea2" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "410660cb18cf403d801ad9a36884937d" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7ffa0a34c89840b897b9ed9ad5773797" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "45eeae7aab4d4c499805960f568e95fc" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8103ffdc531c40c1964c4712ea2b6f00" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "643cc3d3f0544d9d8cf1fef5742d4c93" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "45eeae7aab4d4c499805960f568e95fc" + }, + "m_SlotId": 4 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7b376931c64f4a92b0449f05e3e5d1d4" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "cbddd487454e49788cb3d119498dafd1" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "7ffa0a34c89840b897b9ed9ad5773797" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "866e8721665647028258218cf8168271" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8103ffdc531c40c1964c4712ea2b6f00" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "0b8b05b8ca914d99b7c2aa4472897680" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8103ffdc531c40c1964c4712ea2b6f00" + }, + "m_SlotId": 6 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "cc6264bba642465bbf1a3cc6d2059738" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8103ffdc531c40c1964c4712ea2b6f00" + }, + "m_SlotId": 6 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "e853b9e06a5e42c0bc752d6d77a80408" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "866e8721665647028258218cf8168271" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8e9e4a47bfb54f3c9a91a8068ba31bde" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8dbc4d96191f4d03a1f3765d98729bb2" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "3a4010eed5544bde9b3d9d4e824c5415" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "8e9e4a47bfb54f3c9a91a8068ba31bde" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "cbddd487454e49788cb3d119498dafd1" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "99d8a15ec91744c3a69805bc3be3d4df" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7ffa0a34c89840b897b9ed9ad5773797" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "a0cd74d6fe61452fa1a72093bbc050d3" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "3a4010eed5544bde9b3d9d4e824c5415" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b9450bb77d1a4e1f9db31b3c546072ed" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a3bb0e41fac940948839fcbacdb233d2" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b9450bb77d1a4e1f9db31b3c546072ed" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "3f5900b6dbad4f10a972758d7676197f" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "cbddd487454e49788cb3d119498dafd1" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a0cd74d6fe61452fa1a72093bbc050d3" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "d76c45512a9b48aca250bb4ebbbd8aef" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "8e9e4a47bfb54f3c9a91a8068ba31bde" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f45b51da2803449c83859952e28e4b85" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7bf1166be7484e618d1655ab47cc168b" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f45b51da2803449c83859952e28e4b85" + }, + "m_SlotId": 3 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "46d8a6e8124446e08f11ca6e0b9ed890" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f45b51da2803449c83859952e28e4b85" + }, + "m_SlotId": 4 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "409b2b8a091d48d693c5d89cb4559fc5" + }, + "m_SlotId": 0 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": -1486.000244140625, + "y": 782.0001220703125 + }, + "m_Blocks": [ + { + "m_Id": "7bf1166be7484e618d1655ab47cc168b" + }, + { + "m_Id": "46d8a6e8124446e08f11ca6e0b9ed890" + }, + { + "m_Id": "409b2b8a091d48d693c5d89cb4559fc5" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": -1485.9998779296875, + "y": 1486.9998779296875 + }, + "m_Blocks": [ + { + "m_Id": "0b8b05b8ca914d99b7c2aa4472897680" + }, + { + "m_Id": "cc6264bba642465bbf1a3cc6d2059738" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"fileID\":10200,\"guid\":\"0000000000000000e000000000000000\",\"type\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_SubDatas": [], + "m_ActiveTargets": [ + { + "m_Id": "5468ac27d6574da593d00428fddce641" + }, + { + "m_Id": "c14afcd87ebe46a8a770ba66c3b40cde" + }, + { + "m_Id": "54bb74188f1b4f1ebf5c6024d74e7325" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBAMaterialSlot", + "m_ObjectId": "0345bc9038b0476ca3b0188b617e26b9", + "m_Id": 3, + "m_DisplayName": "color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "color", + "m_StageCapability": 3, + "m_Value": { + "x": 0.5471698045730591, + "y": 0.29165181517601013, + "z": 0.29165181517601013, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.PositionNode", + "m_ObjectId": "03989c994fd54d23a3ea863932c0f145", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3204.999755859375, + "y": 1075.9998779296875, + "width": 206.0, + "height": 130.0 + } + }, + "m_Slots": [ + { + "m_Id": "1ff6002362f5489d8e6a455aa426d605" + } + ], + "synonyms": [ + "location" + ], + "m_Precision": 1, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Space": 2, + "m_PositionSource": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "042ff503b62843ca9b9f64445fbde212", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "04585ab4c4bd47c1813dc6214b6860f3", + "m_Id": 2, + "m_DisplayName": "overrideSkyColor", + "m_SlotType": 0, + "m_Hidden": true, + "m_HideConnector": false, + "m_ShaderOutputName": "overrideSkyColor", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "063e347714ad42d0b4b6f5d2bcbaa2ce", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "06668ed6c3894e69ba26c62e92cba30b", + "m_Title": "Using Structs", + "m_Position": { + "x": -3462.0, + "y": 723.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "07b44f630450449da7b55e4e262a5835", + "m_Id": 2, + "m_DisplayName": "Cosine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Cosine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "08593919df534513b51507fb21a0abea", + "m_Id": 2, + "m_DisplayName": "uv", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "uv", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "08886ae2b3134582829ec420b2125b74", + "m_Id": 3, + "m_DisplayName": "animated", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": true, + "m_ShaderOutputName": "animated", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "0917fa34a2534125a5502fdaf5d26666", + "m_Title": "Dynamic Vectors", + "m_Position": { + "x": -4079.0, + "y": 91.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "0b8b05b8ca914d99b7c2aa4472897680", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "12f2c2097ee14c7ba3ea5cd3570e9d26" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExternalMaterialSlot", + "m_ObjectId": "0c7d3b07884846638acc1879bf4bb0e3", + "m_Id": 1, + "m_DisplayName": "Vertex Data", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "vertex", + "m_StageCapability": 3, + "m_typeName": "ShaderFunctionReflectionStructExample::VertexData", + "m_rawDefaultValueString": "0" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "107c85e296314b3daf89bcca3e90f884", + "m_Id": 1, + "m_DisplayName": "color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "color", + "m_StageCapability": 3, + "m_Value": { + "x": 0.30588236451148987, + "y": 0.7176470756530762, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "12f2c2097ee14c7ba3ea5cd3570e9d26", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "12fa3e39ff814c4ab115664fd00aea40", + "m_Id": 5, + "m_DisplayName": "Z Buffer Sign", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Z Buffer Sign", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInUnlitSubTarget", + "m_ObjectId": "14a5c917c8ca4236a2338d2e39a7ae3d" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "14d5d8e93e484aea851e9ef4890a46e7", + "m_Id": 1, + "m_DisplayName": "X", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "X", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "1506e6162ae44a9ebd92c55e409dbfe6", + "m_Id": 1, + "m_DisplayName": "Sine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Sine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "195ab6ab771341b4bc0e6b3cba2be2b3", + "m_Id": 3, + "m_DisplayName": "Near Plane", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Near Plane", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "1994ae4644e24962b70c99779a6ff389", + "m_Id": 3, + "m_DisplayName": "tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "tangent", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "1f05f16528be403ea2335093d53b3ea2", + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2781.0, + "y": 243.0, + "width": 56.0, + "height": 24.0 + } + }, + "m_Slots": [ + { + "m_Id": "9f0d45be4873482fa18f2c4cdb9b7359" + }, + { + "m_Id": "8b0492e3d54e4a0fa6e486b7077e0e28" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "1ff6002362f5489d8e6a455aa426d605", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "214e0b8cec0746cfae4f8b1a5951d793", + "m_Id": 4, + "m_DisplayName": "Smooth Delta", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Smooth Delta", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "233042094a01446bb75f367bf5b09495", + "m_Id": 5, + "m_DisplayName": "center", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "center", + "m_StageCapability": 3, + "m_Value": { + "x": 0.5, + "y": 0.5 + }, + "m_DefaultValue": { + "x": 0.5, + "y": 0.5 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "23d145713d9048c68b350d904fa6452a", + "m_Id": 4, + "m_DisplayName": "Smooth Delta", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Smooth Delta", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "247130bf3875444f81b20436820239fd", + "m_Title": "", + "m_Content": "In this basic example, we're multiplying the 'inout' color parameter by a multiplier parameter.\n\nReflected Functions can use a return type, out or inout parameters to feature an Output Port.\n\nThe multiplier shows as a slider with no input port by using the hint.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -4417.0, + "y": 475.0, + "width": 200.0, + "height": 199.0 + }, + "m_Group": { + "m_Id": "587f4a8a5290432a99a318c534102216" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "289df4b795604ab7b97bc654a55c42a3", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExternalMaterialSlot", + "m_ObjectId": "28e5c14972d4439a9b04650651933ad4", + "m_Id": 1, + "m_DisplayName": "Vertex Data", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "vertex", + "m_StageCapability": 3, + "m_typeName": "ShaderFunctionReflectionStructExample::VertexData", + "m_rawDefaultValueString": "0" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "28e6b95fce0143b59bf91030eede55e9", + "m_Title": "", + "m_Content": "This function features the hint.\n\nYou can change its precision in the Node Settings. ", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -3519.0, + "y": 293.0, + "width": 200.0, + "height": 106.0 + }, + "m_Group": { + "m_Id": "395e687c1c3844b5928a6c0f9b0db35d" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "2a86e53b5ad648958c79ebfde23d1e16", + "m_Id": 2, + "m_DisplayName": "uv", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "uv", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "2d17a49a3483480bbb23ea244db26a63", + "m_Id": 3, + "m_DisplayName": "thickness", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "thickness", + "m_StageCapability": 3, + "m_Value": 0.009999999776482582, + "m_DefaultValue": 0.009999999776482582, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "2fea7068c87f4d0c894bc0e64d2c33f8", + "m_Id": 0, + "m_DisplayName": "UV", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "UV", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "30812e910c88404f867da8d64db34643", + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + "m_Name": "Linkage Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2543.0, + "y": 150.0, + "width": 225.0, + "height": 335.0 + } + }, + "m_Slots": [ + { + "m_Id": "765c03230145400889a3e1fa426dd81a" + }, + { + "m_Id": "d05a945dd8ac46948092b564201d7546" + }, + { + "m_Id": "b09062b1082c4c689d82b4564f5b87c4" + }, + { + "m_Id": "04585ab4c4bd47c1813dc6214b6860f3" + }, + { + "m_Id": "df3caaef43f44d5cb5012e67911e5952" + }, + { + "m_Id": "b6a07950c02c4a67a88ee4700e3e8cba" + }, + { + "m_Id": "c3cbda0d119b42a88d793c492b05cc18" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 2, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Linkage.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "3192fd7038ae493d991ea487b6afc7ea", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "3215710ee5574d53b4f5115b4fa2ca3b", + "m_Title": "Function Examples", + "m_Position": { + "x": -3114.0, + "y": 1428.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "35731b4e41a54e7a994cb2857082e89c", + "m_Id": 3, + "m_DisplayName": "Delta Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Delta Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "3695a57810344f91a2339471ef195f1e", + "m_Id": 3, + "m_DisplayName": "color", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "color", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 1.0, + "y": 1.0, + "z": 1.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.VertexColorMaterialSlot", + "m_ObjectId": "384d3991b2d1423291930959f1c5a0a8", + "m_Id": 3, + "m_DisplayName": "vc", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "vc", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "395e687c1c3844b5928a6c0f9b0db35d", + "m_Title": "Dual Precision", + "m_Position": { + "x": -3544.0, + "y": 91.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "3a4010eed5544bde9b3d9d4e824c5415", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Push Vertex", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2110.999755859375, + "y": 781.9998779296875, + "width": 224.9998779296875, + "height": 127.0001220703125 + } + }, + "m_Slots": [ + { + "m_Id": "28e5c14972d4439a9b04650651933ad4" + }, + { + "m_Id": "f1b29fa0c7934661a912fd0f9c63332b" + }, + { + "m_Id": "a33b4a6cf3e84ca982997d1d39afcd81" + } + ], + "synonyms": [ + "Reference", + "Struct" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Struct.PushVertex.Example", + "m_sourceAssetId": "0882c87d582a0a04ba360b2e13db6129" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "3ab7645ebbd446e99acb782375852392", + "m_Id": 0, + "m_DisplayName": "Alpha", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Alpha", + "m_StageCapability": 2, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CameraNode", + "m_ObjectId": "3e71080c9bc34bc6ab87ba7d67b7869a", + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + "m_Name": "Camera", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -2913.0, + "y": 251.0, + "width": 102.0, + "height": 77.0 + } + }, + "m_Slots": [ + { + "m_Id": "289df4b795604ab7b97bc654a55c42a3" + }, + { + "m_Id": "e00b15aa165d4c61bdb6158d63020536" + }, + { + "m_Id": "7c00a084444f46e2bf1a188d3f4eb800" + }, + { + "m_Id": "195ab6ab771341b4bc0e6b3cba2be2b3" + }, + { + "m_Id": "6cf14c0ea7584308904120683f954382" + }, + { + "m_Id": "12fa3e39ff814c4ab115664fd00aea40" + }, + { + "m_Id": "605254ead2234370b5de5cdf849ca72b" + }, + { + "m_Id": "f3cb5b8cb9944d71a42fcfdb33f15596" + } + ], + "synonyms": [ + "position", + "direction", + "orthographic", + "near plane", + "far plane", + "width", + "height" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "3f508dc39ea847f7b900ba366badb294", + "m_Id": 2, + "m_DisplayName": "color", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "color", + "m_StageCapability": 3, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "3f5900b6dbad4f10a972758d7676197f", + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2781.0, + "y": 219.0, + "width": 56.0, + "height": 24.0 + } + }, + "m_Slots": [ + { + "m_Id": "b194855189fb474593ba5e0ec560500f" + }, + { + "m_Id": "ab94aa41b5164dbdabf3cebcb1fec181" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "401ff46c9a1641aea7a99cbd40d6e205", + "m_Title": "", + "m_Content": "For missing Varying Reference Types, the hint allows querying the input connection state.\n\nThis is similar to using BranchOnInputConnection in a Subgraph.\n\nFor instance, this allows to default to built-in variables such as unity_AmbientSky or UNITY_MATRIX_V[2]. ", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2906.0, + "y": 346.0, + "width": 321.0, + "height": 148.1634521484375 + }, + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "409b2b8a091d48d693c5d89cb4559fc5", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "fbb76735c8f541b790e2bd2f33a9ff16" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TimeNode", + "m_ObjectId": "410660cb18cf403d801ad9a36884937d", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Time", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -3203.999755859375, + "y": 958.0, + "width": 79.0, + "height": 76.0 + } + }, + "m_Slots": [ + { + "m_Id": "ae81bf7aaa284e8b88ee60b8bb566feb" + }, + { + "m_Id": "942b7d8c94864ce78dd6988eb0daf45a" + }, + { + "m_Id": "f95c92c3cb1348c388a423be137bb109" + }, + { + "m_Id": "aeceb72964e0446db41b7b120ab184d3" + }, + { + "m_Id": "214e0b8cec0746cfae4f8b1a5951d793" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "43c1b4bd3db64142a986e5d07ad6a35b", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "4403773f925142888d9ccefde293c62c", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitData", + "m_ObjectId": "44f2536efb364e8db6fafa129c0747bc", + "m_EnableShadowMatte": false, + "m_DistortionOnly": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "45d837fe36d5481d96d2af7ed2d45e80", + "m_Title": "Texture", + "m_Position": { + "x": -1821.00048828125, + "y": 90.99998474121094 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "45eeae7aab4d4c499805960f568e95fc", + "m_Group": { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + }, + "m_Name": "UV Swirl", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2865.999755859375, + "y": 1491.0, + "width": 207.999755859375, + "height": 376.999755859375 + } + }, + "m_Slots": [ + { + "m_Id": "73043648200344ce89d5e5a8ceb801ba" + }, + { + "m_Id": "08593919df534513b51507fb21a0abea" + }, + { + "m_Id": "08886ae2b3134582829ec420b2125b74" + }, + { + "m_Id": "8815eb2014e64e75866636c361aee390" + }, + { + "m_Id": "233042094a01446bb75f367bf5b09495" + }, + { + "m_Id": "e0d46824d7ba47c283ec8e96076e72be" + } + ], + "synonyms": [ + "UV", + "Distorion", + "Swirl" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.UV_Swirl.Example", + "m_sourceAssetId": "e5651e7a10dac2c47be6fbcdbc98b287" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "46d8a6e8124446e08f11ca6e0b9ed890", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "4403773f925142888d9ccefde293c62c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "4759905ff9d5423888b9d529002d90fe", + "m_Id": 1, + "m_DisplayName": "position", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "position", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "47af7d80f1564591843a688eefdbcec5", + "m_Id": 0, + "m_DisplayName": "Color/Sky", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Color/Sky", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "4852203eb268467b96a808cfec3baf1a", + "m_Id": 2, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "4a05246350b3431ba6c4febb146c9617", + "m_Id": 2, + "m_DisplayName": "cutoff", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "cutoff", + "m_StageCapability": 3, + "m_Value": 0.5, + "m_DefaultValue": 0.5, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "5090fb8e6f754c109fea9d0dd88f5cc7", + "m_Name": "", + "m_ChildObjectList": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "509f882f19c64b2f8077ca31cbad636c", + "m_Id": 2, + "m_DisplayName": "Y", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Y", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "Y" + ], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "50dbbcd6cd664d978ff4a4379d11d1f4", + "m_Id": 0, + "m_DisplayName": "Dot Product", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "516817136f5b427eb1b684c1f4eeae76", + "m_Group": { + "m_Id": "fb7001c484e442778b74cc94d1d09c4e" + }, + "m_Name": "Reference Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3168.000244140625, + "y": 150.00003051757813, + "width": 187.000244140625, + "height": 151.0 + } + }, + "m_Slots": [ + { + "m_Id": "85aad1f0b4f3488b97ecb57ada0bfd93" + }, + { + "m_Id": "2a86e53b5ad648958c79ebfde23d1e16" + }, + { + "m_Id": "384d3991b2d1423291930959f1c5a0a8" + }, + { + "m_Id": "e00af0a8a01b40cfb942717a7c580563" + }, + { + "m_Id": "ed843934fe1f4fc29e6833a9925ea644" + }, + { + "m_Id": "dc1dbefb11aa469c820ad6f9d29bafc0" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Reference.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "5468ac27d6574da593d00428fddce641", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "14a5c917c8ca4236a2338d2e39a7ae3d" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "54bb74188f1b4f1ebf5c6024d74e7325", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "95e6edf6bfa1454ca0673681bc8ac466" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 1, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_DisableTint": false, + "m_Sort3DAs2DCompatible": false, + "m_AdditionalMotionVectorMode": 0, + "m_AlembicMotionVectors": false, + "m_SupportsLODCrossFade": false, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "587f4a8a5290432a99a318c534102216", + "m_Title": "Static", + "m_Position": { + "x": -4445.0, + "y": 91.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "58b4b8e282dd40598cad4543960514be", + "m_Id": 2, + "m_DisplayName": "position", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "position", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5dc644db237749749af5f7ccb7661144", + "m_Id": 3, + "m_DisplayName": "Z", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Z", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "Z" + ], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "5f5665fa590447e1aaa2b57a1f3607fb", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "605254ead2234370b5de5cdf849ca72b", + "m_Id": 6, + "m_DisplayName": "Width", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Width", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "610d5e304adf439980668de3066f9e1d", + "m_Id": 2, + "m_DisplayName": "color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "color", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 1.0, + "y": 1.0, + "z": 1.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TimeNode", + "m_ObjectId": "643cc3d3f0544d9d8cf1fef5742d4c93", + "m_Group": { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + }, + "m_Name": "Time", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -3088.999755859375, + "y": 1510.9998779296875, + "width": 79.0, + "height": 76.0001220703125 + } + }, + "m_Slots": [ + { + "m_Id": "b7ce321a9e3e4712b6c75b236b75a80e" + }, + { + "m_Id": "1506e6162ae44a9ebd92c55e409dbfe6" + }, + { + "m_Id": "07b44f630450449da7b55e4e262a5835" + }, + { + "m_Id": "35731b4e41a54e7a994cb2857082e89c" + }, + { + "m_Id": "23d145713d9048c68b350d904fa6452a" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "6a1ea647d3b3489580d1fcdbfd444d2d", + "m_Id": 2, + "m_DisplayName": "uv", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "uv", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "6cf14c0ea7584308904120683f954382", + "m_Id": 4, + "m_DisplayName": "Far Plane", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Far Plane", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "6d5a767e443c4af8b0c0e45e35f56577", + "m_Id": 1, + "m_DisplayName": "Scale", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Scale", + "m_StageCapability": 3, + "m_Value": 3.0, + "m_DefaultValue": 10.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "711d5d9dbda24136832d8bc00e45d78e", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "72636737d68045df848d96f5349455ec", + "m_Title": "Linkage", + "m_Position": { + "x": -2941.999755859375, + "y": 90.99999237060547 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "72776a17d5bd475e85ae05594c4c9320", + "m_Id": 2, + "m_DisplayName": "normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "normal", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "73043648200344ce89d5e5a8ceb801ba", + "m_Id": 1, + "m_DisplayName": "uv", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "uv", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "73cda139335d419f9eff5bd730294baf", + "m_Id": 6, + "m_DisplayName": "mask", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "mask", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "757c17bba5e44b679138da67f0388ca8", + "m_Title": "", + "m_Content": "\"a\" is an 'inout' Dynamic Vector.\nIn the function body, it gets multiplied by \"b\".\n\n\"b\" is a 'in' Dynamic Vector.\n\n\"Dot Product\" is the function return value (float).\n\n\"sum\" is an 'out' Dynamic Vector.\n\n\"a\", \"b\" and \"sum\" all use the hint.\n\nTry connecting the vectors of different sizes to the inputs to see how Dynamic Vectors adapt.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -3914.0, + "y": 504.0, + "width": 287.0, + "height": 211.0 + }, + "m_Group": { + "m_Id": "0917fa34a2534125a5502fdaf5d26666" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "765c03230145400889a3e1fa426dd81a", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "768abad2b16c4f2591c42a4889b15c50", + "m_Id": 1, + "m_DisplayName": "uv", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "uv", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "770782c726d64429b5b4d2c1a5e1d912", + "m_Group": { + "m_Id": "45d837fe36d5481d96d2af7ed2d45e80" + }, + "m_Name": "Texture Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1796.000244140625, + "y": 150.0, + "width": 208.0, + "height": 335.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "94fc1037d21b46f08af0d9c3744ad252" + }, + { + "m_Id": "9b36d52cd4d44aef8067eaa93cd1f3dc" + }, + { + "m_Id": "6a1ea647d3b3489580d1fcdbfd444d2d" + }, + { + "m_Id": "0345bc9038b0476ca3b0188b617e26b9" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Texture.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "778cf013dd5e4e1690604d774e6dfe5b", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "78ef71280eda4c8e896e01724e21427b", + "m_Id": 2, + "m_DisplayName": "Ground", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Ground", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SliderNode", + "m_ObjectId": "7b376931c64f4a92b0449f05e3e5d1d4", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Slider", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2903.999755859375, + "y": 811.9999389648438, + "width": 232.0, + "height": 146.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "a38f58e49b7e45edbc363b0ddd24b817" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.36000001430511475, + "y": -1.0, + "z": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7bf1166be7484e618d1655ab47cc168b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "cabc1f6561334be2aba206fcc517a02c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "7c00a084444f46e2bf1a188d3f4eb800", + "m_Id": 2, + "m_DisplayName": "Orthographic", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Orthographic", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "7c22b6b5f7cf4b6790526693fa88445d", + "m_Id": 0, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "A", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "7da419ca74bb4e0eabfc89f91edc4fd2", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "7ed61c92ba364bd488875685187b6f58", + "m_Id": 3, + "m_DisplayName": "normal", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "normal", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "7ffa0a34c89840b897b9ed9ad5773797", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3124.999755859375, + "y": 958.0, + "width": 126.0, + "height": 117.9998779296875 + } + }, + "m_Slots": [ + { + "m_Id": "778cf013dd5e4e1690604d774e6dfe5b" + }, + { + "m_Id": "d0d6182a684f4cff8e227effceb778a0" + }, + { + "m_Id": "7da419ca74bb4e0eabfc89f91edc4fd2" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "8103ffdc531c40c1964c4712ea2b6f00", + "m_Group": { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + }, + "m_Name": "Grid", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2460.0, + "y": 1486.9998779296875, + "width": 208.000244140625, + "height": 377.0 + } + }, + "m_Slots": [ + { + "m_Id": "a037683eb22f46d0bc4f231c3fc42cdd" + }, + { + "m_Id": "768abad2b16c4f2591c42a4889b15c50" + }, + { + "m_Id": "c47ca82cbb954d8aba18a0583853b63f" + }, + { + "m_Id": "2d17a49a3483480bbb23ea244db26a63" + }, + { + "m_Id": "dd7d3ed40dd04cf7b41b19d0e69041b8" + }, + { + "m_Id": "ab9c71457ad04fb5b41843345c1586c8" + }, + { + "m_Id": "73cda139335d419f9eff5bd730294baf" + } + ], + "synonyms": [ + "Grid" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Grid.Example", + "m_sourceAssetId": "e5651e7a10dac2c47be6fbcdbc98b287" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialRangeSlot", + "m_ObjectId": "81d5e86f887a46bb99640921d71f34ae", + "m_Id": 3, + "m_DisplayName": "Multiplier", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": true, + "m_ShaderOutputName": "multiplier", + "m_StageCapability": 3, + "m_Value": 0.23999999463558197, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false, + "m_sliderRange": { + "x": 0.0, + "y": 1.0 + }, + "m_SliderType": 0, + "m_SliderPower": 3.0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "82547848cbc445c597d67f716f175fe4", + "m_Title": "", + "m_Content": "This function makes use of the local parameter hint.\n\nIt uses a Local parameter tied to Vertex Color to multiply the incoming color.\n\nThis is using ", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2195.0, + "y": 448.0, + "width": 200.0, + "height": 133.0 + }, + "m_Group": { + "m_Id": "a336489e22914f4a9470f05854e32387" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "8539c4d277004860a5e0b526273a4605", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "e00": 0.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 0.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 0.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 0.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVMaterialSlot", + "m_ObjectId": "85aad1f0b4f3488b97ecb57ada0bfd93", + "m_Id": 1, + "m_DisplayName": "uv", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "uv", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [], + "m_Channel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.AddNode", + "m_ObjectId": "866e8721665647028258218cf8168271", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Add", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2974.999755859375, + "y": 958.0, + "width": 130.0, + "height": 117.9998779296875 + } + }, + "m_Slots": [ + { + "m_Id": "7c22b6b5f7cf4b6790526693fa88445d" + }, + { + "m_Id": "bc771854b9e841daa7672bdaa35c5d42" + }, + { + "m_Id": "ac2512ec9aa54c39a05288e0e1a6a165" + } + ], + "synonyms": [ + "addition", + "sum", + "plus" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "8815eb2014e64e75866636c361aee390", + "m_Id": 4, + "m_DisplayName": "time", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4Node", + "m_ObjectId": "89d56a2f38124a56b9ef778824c610ec", + "m_Group": { + "m_Id": "0917fa34a2534125a5502fdaf5d26666" + }, + "m_Name": "Vector 4", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -4054.0, + "y": 375.99993896484375, + "width": 131.0, + "height": 149.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "e36c45c34dd346369d73ba1d2c3dfed7" + }, + { + "m_Id": "509f882f19c64b2f8077ca31cbad636c" + }, + { + "m_Id": "5dc644db237749749af5f7ccb7661144" + }, + { + "m_Id": "b67de59fa29c46c9ad46cc5a2604a667" + }, + { + "m_Id": "063e347714ad42d0b4b6f5d2bcbaa2ce" + } + ], + "synonyms": [ + "4", + "v4", + "vec4", + "float4" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "8aca4ab90860435ab4d36a2ceb986c01", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "8b0492e3d54e4a0fa6e486b7077e0e28", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "8dbc4d96191f4d03a1f3765d98729bb2", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Set Vertex", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2403.999755859375, + "y": 781.9998779296875, + "width": 206.0, + "height": 151.0 + } + }, + "m_Slots": [ + { + "m_Id": "4759905ff9d5423888b9d529002d90fe" + }, + { + "m_Id": "72776a17d5bd475e85ae05594c4c9320" + }, + { + "m_Id": "1994ae4644e24962b70c99779a6ff389" + }, + { + "m_Id": "ed4a9431a40c41538ee717bd94313762" + } + ], + "synonyms": [ + "Reference", + "Struct" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Struct.SetVertex.Example", + "m_sourceAssetId": "0882c87d582a0a04ba360b2e13db6129" + } + } + ] + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.GradientNoiseNode", + "m_ObjectId": "8e9e4a47bfb54f3c9a91a8068ba31bde", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Gradient Noise", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2820.999755859375, + "y": 958.0, + "width": 147.0, + "height": 151.9998779296875 + } + }, + "m_Slots": [ + { + "m_Id": "2fea7068c87f4d0c894bc0e64d2c33f8" + }, + { + "m_Id": "6d5a767e443c4af8b0c0e45e35f56577" + }, + { + "m_Id": "3192fd7038ae493d991ea487b6afc7ea" + } + ], + "synonyms": [ + "perlin noise" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_HashType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitSubTarget", + "m_ObjectId": "8f7ffd8c635b4de086a7fdd8a4bc2080" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "8fe8c3aac55d450ca3c8d3e6bc7c46bc", + "m_Title": "", + "m_Content": "This is an example of a UV distortion function.\n\nIt uses an inout float2 parameter, referencing the UV.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2863.0, + "y": 1904.0, + "width": 200.0, + "height": 100.0 + }, + "m_Group": { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "942b7d8c94864ce78dd6988eb0daf45a", + "m_Id": 1, + "m_DisplayName": "Sine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Sine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "9433dce918b948f8bb80d66f5b7817cf", + "m_Id": 3, + "m_DisplayName": "b", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "b", + "m_StageCapability": 3, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5, + "w": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "94fc1037d21b46f08af0d9c3744ad252", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "950c1f682d044de7895cef5db917a787", + "m_Group": { + "m_Id": "395e687c1c3844b5928a6c0f9b0db35d" + }, + "m_Name": "Precision Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3468.000244140625, + "y": 149.9999237060547, + "width": 150.0, + "height": 127.00007629394531 + } + }, + "m_Slots": [ + { + "m_Id": "5f5665fa590447e1aaa2b57a1f3607fb" + }, + { + "m_Id": "b6faa06cf94345e2920fef5346b45926" + }, + { + "m_Id": "4852203eb268467b96a808cfec3baf1a" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Precision.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalUnlitSubTarget", + "m_ObjectId": "95e6edf6bfa1454ca0673681bc8ac466", + "m_KeepLightingVariants": false, + "m_DefaultDecalBlending": true, + "m_DefaultSSAO": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SliderNode", + "m_ObjectId": "99d8a15ec91744c3a69805bc3be3d4df", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Slider", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3436.999755859375, + "y": 981.9998779296875, + "width": 232.0, + "height": 146.0 + } + }, + "m_Slots": [ + { + "m_Id": "9ca89f44a3694c15b3d55eb62eaa8b0b" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.30000001192092896, + "y": 0.0, + "z": 2.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Texture2DInputMaterialSlot", + "m_ObjectId": "9b36d52cd4d44aef8067eaa93cd1f3dc", + "m_Id": 1, + "m_DisplayName": "Tex", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Tex", + "m_StageCapability": 3, + "m_BareResource": false, + "m_Texture": { + "m_SerializedTexture": "{\"texture\":{\"fileID\":10309,\"guid\":\"0000000000000000f000000000000000\",\"type\":0}}", + "m_Guid": "" + }, + "m_DefaultType": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "9b9f653f857b4d3384c77c519736b158", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "9ca89f44a3694c15b3d55eb62eaa8b0b", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "9f0d45be4873482fa18f2c4cdb9b7359", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "a037683eb22f46d0bc4f231c3fc42cdd", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "__UNITY_SHADERGRAPH_UNUSED", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "a03c1c3b6b704f0c8c2e363a1327a37e", + "m_Id": 2, + "m_DisplayName": "a", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "a0cd74d6fe61452fa1a72093bbc050d3", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2253.999755859375, + "y": 932.9998779296875, + "width": 56.0, + "height": 24.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "e89ec6f60b3545fe9638263aed4e94b0" + }, + { + "m_Id": "f5659d0b00064a2c8ddd959f82596974" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "a252687d5f5c49da955fc66968eebac8", + "m_MaterialNeedsUpdateHash": 0, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_DebugSymbols": false, + "m_Version": 2, + "inspectorFoldoutMask": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "a300931a25914bdfb9693626948d22ca", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_TransparentPerPixelSorting": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "a336489e22914f4a9470f05854e32387", + "m_Title": "Local", + "m_Position": { + "x": -2223.00048828125, + "y": 90.99998474121094 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a33b4a6cf3e84ca982997d1d39afcd81", + "m_Id": 3, + "m_DisplayName": "amount", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "amount", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a38f58e49b7e45edbc363b0ddd24b817", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "a3bb0e41fac940948839fcbacdb233d2", + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2781.0, + "y": 195.0, + "width": 56.0, + "height": 24.0 + } + }, + "m_Slots": [ + { + "m_Id": "f7c9a62b53544ff69f1489a4d7f4896a" + }, + { + "m_Id": "ed833b052dfb4dcdace0eae473c3de18" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "a969794fd7694e05b735f5d87a7c5368", + "m_Title": "Reflected Function Node", + "m_Content": "Unlike Custom Function Nodes, Reflected Function Nodes do not have to, nor cannot, be created empty.\nInstead, they are 'reflected' from Shader Includes using the Shader Function Reflection API, and get automatically available in Shader Graph through Node Search.\n\nThis allows you to create your own node with any custom functionality inside Shader Graph.\n\nTo create a new Custom Function, you can create a new Empty HLSL file from Assets/Create/Shader/Empty HLSL.\n\nDouble click on a Node to open the source file.\nSelect a node and use F1 to read the documentation and learn more about the Shader Function Reflection API.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -3397.0, + "y": -297.0, + "width": 615.0, + "height": 200.0 + }, + "m_Group": { + "m_Id": "" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "a97cb84891ed488d9052726fb1333cd0", + "m_Id": 2, + "m_DisplayName": "Y", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Y", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "Y" + ], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "a9d5d744fb7b4a7e9ab4f9bfa0cdc1a7", + "m_Title": "", + "m_Content": "In this example, we're using a custom \"VertexData\" struct, with three nodes.\n\nThe first node initializes the data from vertex data.\nThe second processes the data, adding the normal multiplied by the amount to the position.\nThe last node splits the data again.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2283.0, + "y": 969.0, + "width": 319.0, + "height": 131.0 + }, + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ab94aa41b5164dbdabf3cebcb1fec181", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "ab9c71457ad04fb5b41843345c1586c8", + "m_Id": 5, + "m_DisplayName": "antialiased", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": true, + "m_ShaderOutputName": "antialiased", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ac2512ec9aa54c39a05288e0e1a6a165", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ae81bf7aaa284e8b88ee60b8bb566feb", + "m_Id": 0, + "m_DisplayName": "Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "aeceb72964e0446db41b7b120ab184d3", + "m_Id": 3, + "m_DisplayName": "Delta Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Delta Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "b09062b1082c4c689d82b4564f5b87c4", + "m_Id": 5, + "m_DisplayName": "groundColor", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "groundColor", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "b194855189fb474593ba5e0ec560500f", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "b4a91b3ea95347e4b05a5b83c9a7ebde", + "m_Id": 1, + "m_DisplayName": "Equator", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Equator", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b67de59fa29c46c9ad46cc5a2604a667", + "m_Id": 4, + "m_DisplayName": "W", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "W", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "W" + ], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "b6a07950c02c4a67a88ee4700e3e8cba", + "m_Id": 3, + "m_DisplayName": "cameraDirectionWS", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "cameraDirectionWS", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b6faa06cf94345e2920fef5346b45926", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b7ce321a9e3e4712b6c75b236b75a80e", + "m_Id": 0, + "m_DisplayName": "Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.AmbientNode", + "m_ObjectId": "b9450bb77d1a4e1f9db31b3c546072ed", + "m_Group": { + "m_Id": "72636737d68045df848d96f5349455ec" + }, + "m_Name": "Ambient", + "m_DrawState": { + "m_Expanded": false, + "m_Position": { + "serializedVersion": "2", + "x": -2917.0, + "y": 150.0, + "width": 106.0, + "height": 101.0 + } + }, + "m_Slots": [ + { + "m_Id": "47af7d80f1564591843a688eefdbcec5" + }, + { + "m_Id": "b4a91b3ea95347e4b05a5b83c9a7ebde" + }, + { + "m_Id": "78ef71280eda4c8e896e01724e21427b" + } + ], + "synonyms": [ + "scene color" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "ba25886e22e74bca9375b961c824d2b1", + "m_Id": 4, + "m_DisplayName": "tangent", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "tangent", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "bc771854b9e841daa7672bdaa35c5d42", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "bcc261bee5bd4d7180f8984d4ab9c52e", + "m_Group": { + "m_Id": "587f4a8a5290432a99a318c534102216" + }, + "m_Name": "Static Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -4420.0, + "y": 149.99996948242188, + "width": 208.0, + "height": 304.9999694824219 + } + }, + "m_Slots": [ + { + "m_Id": "107c85e296314b3daf89bcca3e90f884" + }, + { + "m_Id": "3f508dc39ea847f7b900ba366badb294" + }, + { + "m_Id": "81d5e86f887a46bb99640921d71f34ae" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Static.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "c14afcd87ebe46a8a770ba66c3b40cde", + "m_ActiveSubTarget": { + "m_Id": "8f7ffd8c635b4de086a7fdd8a4bc2080" + }, + "m_Datas": [ + { + "m_Id": "a300931a25914bdfb9693626948d22ca" + }, + { + "m_Id": "a252687d5f5c49da955fc66968eebac8" + }, + { + "m_Id": "44f2536efb364e8db6fafa129c0747bc" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false, + "m_SupportLineRendering": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "c3cbda0d119b42a88d793c492b05cc18", + "m_Id": 4, + "m_DisplayName": "overrideCameraDirectionWS", + "m_SlotType": 0, + "m_Hidden": true, + "m_HideConnector": false, + "m_ShaderOutputName": "overrideCameraDirectionWS", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "c47ca82cbb954d8aba18a0583853b63f", + "m_Id": 2, + "m_DisplayName": "spacing", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "spacing", + "m_StageCapability": 3, + "m_Value": { + "x": 5.0, + "y": 5.0 + }, + "m_DefaultValue": { + "x": 5.0, + "y": 5.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "cabc1f6561334be2aba206fcc517a02c", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "cb1e49334a344b4ab4a0f8f1dc4a4cf5", + "m_Group": { + "m_Id": "a336489e22914f4a9470f05854e32387" + }, + "m_Name": "Local Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2198.000244140625, + "y": 150.0, + "width": 207.9998779296875, + "height": 287.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "e995ee4bd554453291bf2cb73c041d69" + }, + { + "m_Id": "610d5e304adf439980668de3066f9e1d" + }, + { + "m_Id": "3695a57810344f91a2339471ef195f1e" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Local.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.MultiplyNode", + "m_ObjectId": "cbddd487454e49788cb3d119498dafd1", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Multiply", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2648.999755859375, + "y": 889.0, + "width": 126.0, + "height": 117.99993896484375 + } + }, + "m_Slots": [ + { + "m_Id": "042ff503b62843ca9b9f64445fbde212" + }, + { + "m_Id": "8aca4ab90860435ab4d36a2ceb986c01" + }, + { + "m_Id": "8539c4d277004860a5e0b526273a4605" + } + ], + "synonyms": [ + "multiplication", + "times", + "x" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "cc6264bba642465bbf1a3cc6d2059738", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.Alpha", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "3ab7645ebbd446e99acb782375852392" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.Alpha" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "cdf62f044cbf4ba188174fc245cf521e", + "m_Id": 4, + "m_DisplayName": "sum", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "sum", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "d05a945dd8ac46948092b564201d7546", + "m_Id": 1, + "m_DisplayName": "skyColor", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "skyColor", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicValueMaterialSlot", + "m_ObjectId": "d0d6182a684f4cff8e227effceb778a0", + "m_Id": 1, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "B", + "m_StageCapability": 3, + "m_Value": { + "e00": 2.0, + "e01": 2.0, + "e02": 2.0, + "e03": 2.0, + "e10": 2.0, + "e11": 2.0, + "e12": 2.0, + "e13": 2.0, + "e20": 2.0, + "e21": 2.0, + "e22": 2.0, + "e23": 2.0, + "e30": 2.0, + "e31": 2.0, + "e32": 2.0, + "e33": 2.0 + }, + "m_DefaultValue": { + "e00": 1.0, + "e01": 0.0, + "e02": 0.0, + "e03": 0.0, + "e10": 0.0, + "e11": 1.0, + "e12": 0.0, + "e13": 0.0, + "e20": 0.0, + "e21": 0.0, + "e22": 1.0, + "e23": 0.0, + "e30": 0.0, + "e31": 0.0, + "e32": 0.0, + "e33": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d1e3fd77ed5d4ae0965376d3737f41ab", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2Node", + "m_ObjectId": "d3d1c5f6c6fb4826876c7643db1bf7e9", + "m_Group": { + "m_Id": "0917fa34a2534125a5502fdaf5d26666" + }, + "m_Name": "Vector 2", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -4054.0, + "y": 149.99996948242188, + "width": 128.0, + "height": 101.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "e9ee89dcf0fe46deb98429091da34ad0" + }, + { + "m_Id": "a97cb84891ed488d9052726fb1333cd0" + }, + { + "m_Id": "9b9f653f857b4d3384c77c519736b158" + } + ], + "synonyms": [ + "2", + "v2", + "vec2", + "float2" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.0, + "y": 0.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SliderNode", + "m_ObjectId": "d76c45512a9b48aca250bb4ebbbd8aef", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Slider", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3076.999755859375, + "y": 1205.9998779296875, + "width": 232.0, + "height": 146.0 + } + }, + "m_Slots": [ + { + "m_Id": "d1e3fd77ed5d4ae0965376d3737f41ab" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 3.0, + "y": 0.0, + "z": 10.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "dc1dbefb11aa469c820ad6f9d29bafc0", + "m_Id": 6, + "m_DisplayName": "position", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "position", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "dce8a6099a7243e48d878215d429b0ef", + "m_Group": { + "m_Id": "0917fa34a2534125a5502fdaf5d26666" + }, + "m_Name": "Dynamic Example", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -3832.0, + "y": 149.99996948242188, + "width": 208.0, + "height": 335.0000305175781 + } + }, + "m_Slots": [ + { + "m_Id": "50dbbcd6cd664d978ff4a4379d11d1f4" + }, + { + "m_Id": "fb4ff9aa7f034879b4a4e166908d7a7e" + }, + { + "m_Id": "a03c1c3b6b704f0c8c2e363a1327a37e" + }, + { + "m_Id": "9433dce918b948f8bb80d66f5b7817cf" + }, + { + "m_Id": "cdf62f044cbf4ba188174fc245cf521e" + } + ], + "synonyms": [ + "Reference", + "Hint" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Dynamic.Example", + "m_sourceAssetId": "a9e2b4c78c7e11c4a98ae1e60be55112" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "dd7d3ed40dd04cf7b41b19d0e69041b8", + "m_Id": 4, + "m_DisplayName": "lineColor", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "lineColor", + "m_StageCapability": 3, + "m_Value": { + "x": 0.20000000298023224, + "y": 0.699999988079071, + "z": 0.800000011920929 + }, + "m_DefaultValue": { + "x": 0.20000000298023224, + "y": 0.699999988079071, + "z": 0.800000011920929 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.20000000298023224, + "g": 0.699999988079071, + "b": 0.800000011920929, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BooleanMaterialSlot", + "m_ObjectId": "df3caaef43f44d5cb5012e67911e5952", + "m_Id": 6, + "m_DisplayName": "overrideGroundColor", + "m_SlotType": 0, + "m_Hidden": true, + "m_HideConnector": false, + "m_ShaderOutputName": "overrideGroundColor", + "m_StageCapability": 3, + "m_Value": false, + "m_DefaultValue": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "dfb68d35b2db4a95873ed16d388b2e30", + "m_Title": "", + "m_Content": "This function features inout parameters with reference type and default hints, such as:\n\n\nUV0", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -3183.0, + "y": 310.0, + "width": 200.0, + "height": 108.0 + }, + "m_Group": { + "m_Id": "fb7001c484e442778b74cc94d1d09c4e" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "e00af0a8a01b40cfb942717a7c580563", + "m_Id": 4, + "m_DisplayName": "vc", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "vc", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3MaterialSlot", + "m_ObjectId": "e00b15aa165d4c61bdb6158d63020536", + "m_Id": 1, + "m_DisplayName": "Direction", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Direction", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e0d46824d7ba47c283ec8e96076e72be", + "m_Id": 6, + "m_DisplayName": "strength", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "strength", + "m_StageCapability": 3, + "m_Value": 4.03000020980835, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e36c45c34dd346369d73ba1d2c3dfed7", + "m_Id": 1, + "m_DisplayName": "X", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "X", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "e853b9e06a5e42c0bc752d6d77a80408", + "m_Group": { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + }, + "m_Name": "Antialias", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -2155.0, + "y": 1611.0001220703125, + "width": 207.9998779296875, + "height": 311.0 + } + }, + "m_Slots": [ + { + "m_Id": "43c1b4bd3db64142a986e5d07ad6a35b" + }, + { + "m_Id": "f5cd4b75aa5d4e9e9acdc80817160c4f" + }, + { + "m_Id": "4a05246350b3431ba6c4febb146c9617" + } + ], + "synonyms": [ + "Antialias" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Antialias.Example", + "m_sourceAssetId": "e5651e7a10dac2c47be6fbcdbc98b287" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "e89ec6f60b3545fe9638263aed4e94b0", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.VertexColorMaterialSlot", + "m_ObjectId": "e995ee4bd554453291bf2cb73c041d69", + "m_Id": 1, + "m_DisplayName": "vc", + "m_SlotType": 0, + "m_Hidden": true, + "m_HideConnector": false, + "m_ShaderOutputName": "vc", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "e9ee89dcf0fe46deb98429091da34ad0", + "m_Id": 1, + "m_DisplayName": "X", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "X", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ed22dfa0757b4d51827205dd5d5ac74a", + "m_Id": 3, + "m_DisplayName": "Z", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Z", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "Z" + ], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExternalMaterialSlot", + "m_ObjectId": "ed4a9431a40c41538ee717bd94313762", + "m_Id": 4, + "m_DisplayName": "Vertex Data", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "vertex", + "m_StageCapability": 3, + "m_typeName": "ShaderFunctionReflectionStructExample::VertexData", + "m_rawDefaultValueString": "0" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ed833b052dfb4dcdace0eae473c3de18", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "ed843934fe1f4fc29e6833a9925ea644", + "m_Id": 5, + "m_DisplayName": "position", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "position", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f028b117705147938d2dada0c98714b5", + "m_Id": 2, + "m_DisplayName": "Y", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Y", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [ + "Y" + ], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "f10027bf57de454cb3fb662a899d58b1", + "m_Title": "", + "m_Content": "This function provides an example of how to reference and sample a texture.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -1794.0, + "y": 502.0, + "width": 200.0, + "height": 100.0 + }, + "m_Group": { + "m_Id": "45d837fe36d5481d96d2af7ed2d45e80" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ExternalMaterialSlot", + "m_ObjectId": "f1b29fa0c7934661a912fd0f9c63332b", + "m_Id": 2, + "m_DisplayName": "Vertex Data", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "vertex", + "m_StageCapability": 3, + "m_typeName": "ShaderFunctionReflectionStructExample::VertexData", + "m_rawDefaultValueString": "0" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f3cb5b8cb9944d71a42fcfdb33f15596", + "m_Id": 7, + "m_DisplayName": "Height", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Height", + "m_StageCapability": 3, + "m_Value": 1.0, + "m_DefaultValue": 1.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ProviderSystem.ProviderNode", + "m_ObjectId": "f45b51da2803449c83859952e28e4b85", + "m_Group": { + "m_Id": "06668ed6c3894e69ba26c62e92cba30b" + }, + "m_Name": "Get Vertex", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1861.9998779296875, + "y": 781.9998779296875, + "width": 205.9998779296875, + "height": 151.0 + } + }, + "m_Slots": [ + { + "m_Id": "0c7d3b07884846638acc1879bf4bb0e3" + }, + { + "m_Id": "58b4b8e282dd40598cad4543960514be" + }, + { + "m_Id": "7ed61c92ba364bd488875685187b6f58" + }, + { + "m_Id": "ba25886e22e74bca9375b961c824d2b1" + } + ], + "synonyms": [ + "Reference", + "Struct" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_provider": { + "rid": 1000 + }, + "references": { + "version": 2, + "RefIds": [ + { + "rid": 1000, + "type": { + "class": "ReflectedFunctionProvider", + "ns": "UnityEditor.ShaderGraph.ProviderSystem", + "asm": "Unity.ShaderGraph.Editor" + }, + "data": { + "m_providerKey": "SG.NodeReference.Struct.GetVertex.Example", + "m_sourceAssetId": "0882c87d582a0a04ba360b2e13db6129" + } + } + ] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "f5659d0b00064a2c8ddd959f82596974", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f5cd4b75aa5d4e9e9acdc80817160c4f", + "m_Id": 1, + "m_DisplayName": "gradient", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "gradient", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "f6737123fbeb437b97d2046900252fe0", + "m_Title": "", + "m_Content": "This is an example of a pattern generator.\n\nIt uses a float2 referencing the UV, which can be overriden.\n\nIt also uses hint as to initialize other paremeters.\n\nThe antialiased parameter makes for built-in anti-aliasing, that can otherwise be added as another node. ", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -2456.0, + "y": 1899.0, + "width": 200.0, + "height": 211.0 + }, + "m_Group": { + "m_Id": "3215710ee5574d53b4f5115b4fa2ca3b" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "f7c9a62b53544ff69f1489a4d7f4896a", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "f95c92c3cb1348c388a423be137bb109", + "m_Id": 2, + "m_DisplayName": "Cosine Time", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Cosine Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "fb4ff9aa7f034879b4a4e166908d7a7e", + "m_Id": 1, + "m_DisplayName": "a", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "a", + "m_StageCapability": 3, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5, + "w": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "fb7001c484e442778b74cc94d1d09c4e", + "m_Title": "Reference Types", + "m_Position": { + "x": -3208.0, + "y": 91.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "fbb76735c8f541b790e2bd2f33a9ff16", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector3Node", + "m_ObjectId": "fbcd31f799f446459eb6e4427e6dd5b1", + "m_Group": { + "m_Id": "0917fa34a2534125a5502fdaf5d26666" + }, + "m_Name": "Vector 3", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -4054.0, + "y": 251.00003051757813, + "width": 128.0, + "height": 124.99990844726563 + } + }, + "m_Slots": [ + { + "m_Id": "14d5d8e93e484aea851e9ef4890a46e7" + }, + { + "m_Id": "f028b117705147938d2dada0c98714b5" + }, + { + "m_Id": "ed22dfa0757b4d51827205dd5d5ac74a" + }, + { + "m_Id": "711d5d9dbda24136832d8bc00e45d78e" + } + ], + "synonyms": [ + "3", + "v3", + "vec3", + "float3" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + } +} + diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ReflectedFunction.shadergraph.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ReflectedFunction.shadergraph.meta new file mode 100644 index 00000000000..6d838744c91 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ReflectedFunction.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: f7026d986bb292348b49a3500feeaf32 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionExamples.hlsl b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionExamples.hlsl new file mode 100644 index 00000000000..890ef3e6a22 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionExamples.hlsl @@ -0,0 +1,105 @@ +#include "ShaderApiReflectionSupport.hlsl" + +namespace ShaderFunctionReflectionExamples { + /// + /// SG.NodeReference.Antialias.Example + /// Antialias + /// Reference/Shader Functions + /// Antialias + /// Antialias + /// + /// + /// 0.5 + /// + UNITY_EXPORT_REFLECTION + float Antialias(float gradient, float cutoff) + { + float c = cutoff - gradient; + float d = length(float2(ddx(c), ddy(c))); + return saturate(0.5 - (c / d)); + } + + /// + /// SG.NodeReference.Grid.Example + /// Grid + /// Reference/Shader Functions + /// Grid + /// Grid + /// + /// + /// + /// UV0 + /// + /// + /// 5,5 + /// + /// + /// 0.01 + /// + /// + /// + /// 0.2,0.7,0.8 + /// + /// + /// + /// + UNITY_EXPORT_REFLECTION + float3 Grid( + float2 uv, + float2 spacing, + float thickness, + float3 lineColor, + bool antialiased, + out float mask) + { + float2 g = uv * spacing; + + float2 gridDist = abs(frac(g - 0.5) - 0.5) / fwidth(g); + + float l = min(gridDist.x, gridDist.y); + mask = 1.0 - saturate(l - thickness); + + if (antialiased) + mask = Antialias(mask, 0.5); + + return lineColor * mask; + } + + /// + /// SG.NodeReference.UV_Swirl.Example + /// UV Swirl + /// Reference/Shader Functions + /// UV Swirl + /// UV, Distorion, Swirl + /// + /// + /// + /// UV0 + /// + /// + /// 0.5,0.5 + /// + /// + /// + /// + UNITY_EXPORT_REFLECTION + void UV_Swirl( + inout float2 uv, + bool animated, + float time, + float2 center, + float strength) + { + float2 d = uv - center; + float r = length(d); + float a = atan2(d.y, d.x); + + a += strength * (1 - r); + + [branch] + if (animated) + a += time; + + uv = center + float2(cos(a), sin(a)) * r; + } +} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionExamples.hlsl.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionExamples.hlsl.meta new file mode 100644 index 00000000000..a24d6fcdfba --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionExamples.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e5651e7a10dac2c47be6fbcdbc98b287 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionReference.hlsl b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionReference.hlsl new file mode 100644 index 00000000000..939c43b96c4 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionReference.hlsl @@ -0,0 +1,177 @@ +#include "ShaderApiReflectionSupport.hlsl" + +namespace ShaderFunctionReflectionReference { + /// + /// SG.NodeReference.Static.Example + /// Static Example + /// Reference/Shader Functions + /// Static Example + /// Reference, Hint + /// + /// + /// + /// .5,.5,.5,1 + /// + /// + /// Multiplier + /// 1 + /// + /// 0, 1 + /// + UNITY_EXPORT_REFLECTION + void StaticExample(inout float3 color, float multiplier) + { + color *= multiplier; + } + + /// + /// SG.NodeReference.Dynamic.Example + /// Dynamic Example + /// Dot Product + /// Reference/Shader Functions + /// Dynamic Example + /// Reference, Hint + /// + /// + /// + /// 0, 1 + /// + /// + /// + /// 1, 0 + /// + /// + /// + /// + UNITY_EXPORT_REFLECTION + float DynamicExample(inout float a, float b, out float sum) + { + a *= b; + sum = a + b; + return dot(a, b); + } + + /// + /// SG.NodeReference.Precision.Example + /// Precision Example + /// Reference/Shader Functions + /// Precision Example + /// Reference, Hint + /// + /// + /// 1 + /// + /// + /// 1 + /// + UNITY_EXPORT_REFLECTION + float PrecisionExample(float a, float b) + { + return dot(a, b); + } + + /// + /// SG.NodeReference.Reference.Example + /// Reference Example + /// Reference/Shader Functions + /// Reference Example + /// Reference, Hint + /// + /// + /// + /// UV0 + /// + /// + /// + /// + /// + /// + /// ObjectSpace + /// + UNITY_EXPORT_REFLECTION + void ReferenceExample(inout float2 uv, inout float4 vc, inout float3 position) + { + + } + + /// + /// SG.NodeReference.Linkage.Example + /// Linkage Example + /// Reference/Shader Functions + /// Linkage Example + /// Reference, Hint + /// + /// + /// skyColor + /// + /// + /// groundColor + /// + /// + /// cameraDirectionWS + /// + UNITY_EXPORT_REFLECTION + float3 LinkageExample( + float3 skyColor, + float3 groundColor, + bool overrideSkyColor, + bool overrideGroundColor, + float3 cameraDirectionWS, + bool overrideCameraDirectionWS) + { + if (!overrideSkyColor) + skyColor = unity_AmbientSky.xyz; + + if (!overrideGroundColor) + groundColor = unity_AmbientGround.xyz; + + if (!overrideCameraDirectionWS) + cameraDirectionWS = - UNITY_MATRIX_V[2].xyz; + + float upFacing = dot(cameraDirectionWS, float3(0, 1, 0)) * 0.5 + 0.5; + + return lerp(groundColor, skyColor, upFacing); + } + + /// + /// SG.NodeReference.Local.Example + /// Local Example + /// Reference/Shader Functions + /// Local Example + /// Reference, Hint + /// + /// + /// + /// + /// + /// + /// + /// 1,1,1,1 + /// + UNITY_EXPORT_REFLECTION + void LocalExample(float4 vc, inout float3 color) + { + color *= vc; + } + + /// + /// SG.NodeReference.Texture.Example + /// Texture Example + /// Reference/Shader Functions + /// Texture Example + /// Reference, Hint + /// + /// + /// + /// UV0 + /// + /// + /// + /// 1,1,1,1 + /// + UNITY_EXPORT_REFLECTION + float4 TextureExample(UnityTexture2D Tex, float2 uv, float4 color) + { + return Tex.Sample( Tex.samplerstate, uv) * color; + } +} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionReference.hlsl.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionReference.hlsl.meta new file mode 100644 index 00000000000..0c96f02a844 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionReference.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a9e2b4c78c7e11c4a98ae1e60be55112 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionStructExample.hlsl b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionStructExample.hlsl new file mode 100644 index 00000000000..77b9f7a2231 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionStructExample.hlsl @@ -0,0 +1,80 @@ +#include "ShaderApiReflectionSupport.hlsl" + +namespace ShaderFunctionReflectionStructExample +{ + + struct VertexData + { + float3 position; + float3 normal; + float3 tangent; + }; + + /// + /// SG.NodeReference.Struct.SetVertex.Example + /// Set Vertex + /// Vertex + /// Node Reference/Struct + /// Set Vertex + /// Reference, Struct + /// + /// + /// + /// ObjectSpace + /// + /// + /// + /// ObjectSpace + /// + /// + /// + /// ObjectSpace + /// + /// + /// Vertex Data + /// ShaderFunctionReflectionStructExample + /// + UNITY_EXPORT_REFLECTION + void SetVertex(float3 position, float3 normal, float3 tangent, out VertexData vertex) + { + vertex.position = position; + vertex.normal = normal; + vertex.tangent = tangent; + } + + /// + /// SG.NodeReference.Struct.GetVertex.Example + /// Get Vertex + /// Node Reference/Struct + /// Get Vertex + /// Reference, Struct + /// + /// + /// Vertex Data + /// ShaderFunctionReflectionStructExample + /// + UNITY_EXPORT_REFLECTION + void GetVertex(VertexData vertex, out float3 position, out float3 normal, out float3 tangent) + { + position = vertex.position; + normal = vertex.normal; + tangent = vertex.tangent; + } + + /// + /// SG.NodeReference.Struct.PushVertex.Example + /// Push Vertex + /// Node Reference/Struct + /// Push Vertex + /// Reference, Struct + /// + /// + /// Vertex Data + /// ShaderFunctionReflectionStructExample + /// + UNITY_EXPORT_REFLECTION + void Push(inout VertexData vertex, float amount) + { + vertex.position += vertex.normal * amount; + } +} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionStructExample.hlsl.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionStructExample.hlsl.meta new file mode 100644 index 00000000000..fa31b0dc339 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/ShaderFunctionReflectionStructExample.hlsl.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0882c87d582a0a04ba360b2e13db6129 +ShaderIncludeImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Switch.shadergraph b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Switch.shadergraph new file mode 100644 index 00000000000..81b9a9a1658 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Switch.shadergraph @@ -0,0 +1,3082 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "6f3210655c2f4ef7a8bc6ef98872e6fe", + "m_Properties": [ + { + "m_Id": "a2db761472fb45bb805f40904c3a0250" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "f456104168cb4f25a378f7dbb1d98f41" + } + ], + "m_Nodes": [ + { + "m_Id": "137de8b1e4794cf9b87efd4f67bb9270" + }, + { + "m_Id": "d264465c5f5f4cafb4282e5c29fa0052" + }, + { + "m_Id": "02e5fcfe5fbe48a9b638ddbb7beaf6d3" + }, + { + "m_Id": "7ab64666a0a443faad1858d8a7c0661b" + }, + { + "m_Id": "6cb1056360c5415c83a5dc8e76aa21e7" + }, + { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + { + "m_Id": "58460393ec614e34bdbac4edf7ab5110" + }, + { + "m_Id": "00d477b795af49798a2cedef4680d4ce" + }, + { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + { + "m_Id": "5ce1e288c1824491aa440f49b88fc876" + }, + { + "m_Id": "44050c48d302466a80f65e11586907bf" + }, + { + "m_Id": "6d5dc37b5d6045f8a027615cd3fc848e" + }, + { + "m_Id": "31e61aee223041a7a0f83d0e396b0463" + }, + { + "m_Id": "a8b35eb6e35847958e10794e7251e5f2" + }, + { + "m_Id": "829c7b8d90c24fc29bee9b09ca2a813e" + }, + { + "m_Id": "b5021080fafc4e2c999541fa04952ad0" + }, + { + "m_Id": "b905d646c66b499086f99872bea6b643" + }, + { + "m_Id": "786a73d10fcc4617adf9a95b1360219c" + } + ], + "m_GroupDatas": [ + { + "m_Id": "fcd45624a2d142c88f3c301e8c742685" + }, + { + "m_Id": "fed2c2b7925a49029c0514aaebf31995" + }, + { + "m_Id": "54785739c3f44f0682783b7035865e27" + } + ], + "m_StickyNoteDatas": [ + { + "m_Id": "eaf10b588af74584971a91e776805cd5" + }, + { + "m_Id": "3d04a0325680447d998b8f4e129d1f38" + }, + { + "m_Id": "8a1a3212e26943d792174bd06b74faf4" + }, + { + "m_Id": "608fe67eb76f4eea94abf2df671b20b3" + } + ], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "00d477b795af49798a2cedef4680d4ce" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "5ce1e288c1824491aa440f49b88fc876" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "00d477b795af49798a2cedef4680d4ce" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "31e61aee223041a7a0f83d0e396b0463" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "7ab64666a0a443faad1858d8a7c0661b" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "44050c48d302466a80f65e11586907bf" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 4 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "44050c48d302466a80f65e11586907bf" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + "m_SlotId": 4 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "31e61aee223041a7a0f83d0e396b0463" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "58460393ec614e34bdbac4edf7ab5110" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5ce1e288c1824491aa440f49b88fc876" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 5 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5ce1e288c1824491aa440f49b88fc876" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "6d5dc37b5d6045f8a027615cd3fc848e" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "5ce1e288c1824491aa440f49b88fc876" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + "m_SlotId": 5 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "6d5dc37b5d6045f8a027615cd3fc848e" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 6 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "6d5dc37b5d6045f8a027615cd3fc848e" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + "m_SlotId": 6 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "786a73d10fcc4617adf9a95b1360219c" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b905d646c66b499086f99872bea6b643" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "829c7b8d90c24fc29bee9b09ca2a813e" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "b905d646c66b499086f99872bea6b643" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a8b35eb6e35847958e10794e7251e5f2" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b5021080fafc4e2c999541fa04952ad0" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "31e61aee223041a7a0f83d0e396b0463" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b5021080fafc4e2c999541fa04952ad0" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "786a73d10fcc4617adf9a95b1360219c" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "b5021080fafc4e2c999541fa04952ad0" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "a8b35eb6e35847958e10794e7251e5f2" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "44050c48d302466a80f65e11586907bf" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "51ce8263d591453c98abfe52d6d03b05" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fb195d2ff3244d8896960d2ba4788117" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "88db34002bd7426c8d263ada58987154" + }, + "m_SlotId": 3 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 662.0000610351563, + "y": 290.0000305175781 + }, + "m_Blocks": [ + { + "m_Id": "137de8b1e4794cf9b87efd4f67bb9270" + }, + { + "m_Id": "d264465c5f5f4cafb4282e5c29fa0052" + }, + { + "m_Id": "02e5fcfe5fbe48a9b638ddbb7beaf6d3" + } + ] + }, + "m_FragmentContext": { + "m_Position": { + "x": 662.0000610351563, + "y": 490.00006103515625 + }, + "m_Blocks": [ + { + "m_Id": "7ab64666a0a443faad1858d8a7c0661b" + } + ] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Shader Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 2, + "m_OutputNode": { + "m_Id": "" + }, + "m_SubDatas": [], + "m_ActiveTargets": [ + { + "m_Id": "9ea137df613a4e37a44ea08d07c5d60a" + }, + { + "m_Id": "b0ee8fd821e2468ba5e019735c2d4906" + }, + { + "m_Id": "45bede8555884d94b8e984262dc8d326" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVNode", + "m_ObjectId": "00d477b795af49798a2cedef4680d4ce", + "m_Group": { + "m_Id": "" + }, + "m_Name": "UV", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1300.0, + "y": 879.0, + "width": 145.0, + "height": 128.0 + } + }, + "m_Slots": [ + { + "m_Id": "90a1075c53884f4293af9a81824ada3b" + } + ], + "synonyms": [ + "texcoords", + "coords", + "coordinates" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_OutputChannel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "02e5fcfe5fbe48a9b638ddbb7beaf6d3", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Tangent", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "4995dc45b1924025a2b61ec698cb22fe" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Tangent" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.NormalMaterialSlot", + "m_ObjectId": "0500b8f2eb9b4cc8b0edc29c8d4c4de2", + "m_Id": 0, + "m_DisplayName": "Normal", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Normal", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PositionMaterialSlot", + "m_ObjectId": "0b8e9ce99e3a45afbfbb885bc79e765f", + "m_Id": 0, + "m_DisplayName": "Position", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Position", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "0be04c690d594ba78eb4b46775f02223", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "137de8b1e4794cf9b87efd4f67bb9270", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Position", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "0b8e9ce99e3a45afbfbb885bc79e765f" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Position" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "144f24d7fc774915a76c611652195b92", + "m_Id": 5, + "m_DisplayName": "C", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_C", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientMaterialSlot", + "m_ObjectId": "1a76923c5fbf4951977d90ae28c6f5c4", + "m_Id": 1, + "m_DisplayName": "", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "1c96ec8b86c0428882052d03b795826c", + "m_Id": 6, + "m_DisplayName": "D", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_D", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "1e1f96144b0d4424a64f24041d4648cf", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "265a360c19f748d4bdd8d6d9d709796f", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "2bcd7cbdeed942908b744af35d7a802d", + "m_Id": 1, + "m_DisplayName": "Time", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientInputMaterialSlot", + "m_ObjectId": "2d09686930884a749a3164171e0f719a", + "m_Id": 0, + "m_DisplayName": "Gradient", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Gradient", + "m_StageCapability": 3, + "m_Value": { + "serializedVersion": "2", + "key0": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key1": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key2": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key3": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key4": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key5": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key6": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key7": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "ctime0": 0, + "ctime1": 65535, + "ctime2": 0, + "ctime3": 0, + "ctime4": 0, + "ctime5": 0, + "ctime6": 0, + "ctime7": 0, + "atime0": 0, + "atime1": 65535, + "atime2": 0, + "atime3": 0, + "atime4": 0, + "atime5": 0, + "atime6": 0, + "atime7": 0, + "m_Mode": 0, + "m_ColorSpace": -1, + "m_NumColorKeys": 2, + "m_NumAlphaKeys": 2 + }, + "m_DefaultValue": { + "serializedVersion": "2", + "key0": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key1": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key2": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key3": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key4": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key5": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key6": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key7": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "ctime0": 0, + "ctime1": 65535, + "ctime2": 0, + "ctime3": 0, + "ctime4": 0, + "ctime5": 0, + "ctime6": 0, + "ctime7": 0, + "atime0": 0, + "atime1": 65535, + "atime2": 0, + "atime3": 0, + "atime4": 0, + "atime5": 0, + "atime6": 0, + "atime7": 0, + "m_Mode": 0, + "m_ColorSpace": -1, + "m_NumColorKeys": 2, + "m_NumAlphaKeys": 2 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientInputMaterialSlot", + "m_ObjectId": "2de7d325d5df416d93306e9882668d10", + "m_Id": 0, + "m_DisplayName": "Gradient", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Gradient", + "m_StageCapability": 3, + "m_Value": { + "serializedVersion": "2", + "key0": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key1": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key2": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key3": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key4": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key5": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key6": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key7": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "ctime0": 0, + "ctime1": 65535, + "ctime2": 0, + "ctime3": 0, + "ctime4": 0, + "ctime5": 0, + "ctime6": 0, + "ctime7": 0, + "atime0": 0, + "atime1": 65535, + "atime2": 0, + "atime3": 0, + "atime4": 0, + "atime5": 0, + "atime6": 0, + "atime7": 0, + "m_Mode": 0, + "m_ColorSpace": -1, + "m_NumColorKeys": 2, + "m_NumAlphaKeys": 2 + }, + "m_DefaultValue": { + "serializedVersion": "2", + "key0": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key1": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key2": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key3": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key4": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key5": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key6": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key7": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "ctime0": 0, + "ctime1": 65535, + "ctime2": 0, + "ctime3": 0, + "ctime4": 0, + "ctime5": 0, + "ctime6": 0, + "ctime7": 0, + "atime0": 0, + "atime1": 65535, + "atime2": 0, + "atime3": 0, + "atime4": 0, + "atime5": 0, + "atime6": 0, + "atime7": 0, + "m_Mode": 0, + "m_ColorSpace": -1, + "m_NumColorKeys": 2, + "m_NumAlphaKeys": 2 + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SampleGradient", + "m_ObjectId": "31e61aee223041a7a0f83d0e396b0463", + "m_Group": { + "m_Id": "fcd45624a2d142c88f3c301e8c742685" + }, + "m_Name": "Sample Gradient", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 47.99992370605469, + "y": 490.0000305175781, + "width": 208.00010681152344, + "height": 302.0000305175781 + } + }, + "m_Slots": [ + { + "m_Id": "2d09686930884a749a3164171e0f719a" + }, + { + "m_Id": "bf6bf86bbcfe4ca98df86761383b98c0" + }, + { + "m_Id": "8565765e60a04d65ab6b75df83c29206" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "3d04a0325680447d998b8f4e129d1f38", + "m_Title": "Switch node", + "m_Content": "Node's settings allow to floor the Predicate and set Conditions manually.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -195.0, + "y": 1484.0, + "width": 200.0, + "height": 123.0 + }, + "m_Group": { + "m_Id": "fed2c2b7925a49029c0514aaebf31995" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "3e706e5f66b14c68b19403b05652d7a3", + "m_Id": 5, + "m_DisplayName": "Up", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Up", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.OneMinusNode", + "m_ObjectId": "44050c48d302466a80f65e11586907bf", + "m_Group": { + "m_Id": "" + }, + "m_Name": "One Minus", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1132.0, + "y": 998.0, + "width": 128.0, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "f164fddb52af46e28a970b9a6e555b89" + }, + { + "m_Id": "b8d9371775a04f7f9ec8f57b26419fad" + } + ], + "synonyms": [ + "complement", + "invert", + "opposite" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalTarget", + "m_ObjectId": "45bede8555884d94b8e984262dc8d326", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "ac3f0044c20c43488dc9c80d8ea1b4d9" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZTestMode": 4, + "m_ZWriteControl": 0, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CastShadows": true, + "m_ReceiveShadows": true, + "m_DisableTint": false, + "m_Sort3DAs2DCompatible": false, + "m_AdditionalMotionVectorMode": 0, + "m_AlembicMotionVectors": false, + "m_SupportsLODCrossFade": false, + "m_CustomEditorGUI": "", + "m_SupportVFX": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.TangentMaterialSlot", + "m_ObjectId": "4995dc45b1924025a2b61ec698cb22fe", + "m_Id": 0, + "m_DisplayName": "Tangent", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Tangent", + "m_StageCapability": 1, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_Space": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.SystemData", + "m_ObjectId": "4f0cf95387cf47ca8a3b6776923bf646", + "m_MaterialNeedsUpdateHash": 0, + "m_SurfaceType": 0, + "m_RenderingPass": 1, + "m_BlendMode": 0, + "m_ZTest": 4, + "m_ZWrite": false, + "m_TransparentCullMode": 2, + "m_OpaqueCullMode": 2, + "m_SortPriority": 0, + "m_AlphaTest": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_SupportLodCrossFade": false, + "m_DoubleSidedMode": 0, + "m_DOTSInstancing": false, + "m_CustomVelocity": false, + "m_Tessellation": false, + "m_TessellationMode": 0, + "m_TessellationFactorMinDistance": 20.0, + "m_TessellationFactorMaxDistance": 50.0, + "m_TessellationFactorTriangleSize": 100.0, + "m_TessellationShapeFactor": 0.75, + "m_TessellationBackFaceCullEpsilon": -0.25, + "m_TessellationMaxDisplacement": 0.009999999776482582, + "m_DebugSymbols": false, + "m_Version": 2, + "inspectorFoldoutMask": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SwitchNode", + "m_ObjectId": "51ce8263d591453c98abfe52d6d03b05", + "m_Group": { + "m_Id": "fcd45624a2d142c88f3c301e8c742685" + }, + "m_Name": "Switch", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -441.0, + "y": 512.9999389648438, + "width": 168.0, + "height": 118.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "c095c741fdca48e88a13fadf47556f4a" + }, + { + "m_Id": "534c3d6f92d84e38a1d272363187f1df" + }, + { + "m_Id": "88ed63112fd5414f9c2a2edc62076770" + }, + { + "m_Id": "f804b1063271497284b3d701ecd098d8" + }, + { + "m_Id": "adb9b1b2cc1a4b82a3e100259d4c1776" + }, + { + "m_Id": "3e706e5f66b14c68b19403b05652d7a3" + }, + { + "m_Id": "835a53cf77e8496fa1d1f5b0895f4a5c" + } + ], + "synonyms": [ + "switch" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_floorPredicate": true, + "m_cases": [], + "m_useProperty": true, + "m_casesFromUpstreamEnumProperty": [ + { + "name": "Right", + "comparisonType": 0, + "threshold": 0.0 + }, + { + "name": "Left", + "comparisonType": 0, + "threshold": 1.0 + }, + { + "name": "Up", + "comparisonType": 0, + "threshold": 2.0 + }, + { + "name": "Down", + "comparisonType": 0, + "threshold": 3.0 + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "52a6d1fa9f964a579b2a44d23a25e2ec", + "m_Id": 3, + "m_DisplayName": "A", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_A", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "534c3d6f92d84e38a1d272363187f1df", + "m_Id": 1, + "m_DisplayName": "Fallback", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Fallback", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "54785739c3f44f0682783b7035865e27", + "m_Title": "Subgraph", + "m_Position": { + "x": 402.9999084472656, + "y": 1023.0001220703125 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "58460393ec614e34bdbac4edf7ab5110", + "m_Group": { + "m_Id": "fcd45624a2d142c88f3c301e8c742685" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -441.0, + "y": 479.0, + "width": 122.0, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "d46ddfcf7952480b870cda84f67fe35c" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "a2db761472fb45bb805f40904c3a0250" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitSubTarget", + "m_ObjectId": "5a83a7b3743d4d1cbbc07892539c9dae" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "5ce1e288c1824491aa440f49b88fc876", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1132.0001220703125, + "y": 1092.0001220703125, + "width": 129.0, + "height": 122.0 + } + }, + "m_Slots": [ + { + "m_Id": "c31d9699267e4a6188af2461669d842b" + }, + { + "m_Id": "d812f3403fcc47f89db995a964fcf197" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "y", + "convertedMask": "y" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "608fe67eb76f4eea94abf2df671b20b3", + "m_Title": "Switch node", + "m_Content": "The Node can also be used in a Subgraph with a Float Input set up as an Enum.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": 435.0, + "y": 1242.0, + "width": 200.0, + "height": 123.0 + }, + "m_Group": { + "m_Id": "54785739c3f44f0682783b7035865e27" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "60b349a8f20448748d81b7fece92c734", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "6342733b9a444ffd981fc1d8682b50d7", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SwitchNode", + "m_ObjectId": "6cb1056360c5415c83a5dc8e76aa21e7", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Switch", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -401.0, + "y": 195.0, + "width": 168.0, + "height": 118.0 + } + }, + "m_Slots": [ + { + "m_Id": "faebd47487f54224bc01167ad391828c" + }, + { + "m_Id": "e68de41d29ba4473bffd4eff3020de4c" + }, + { + "m_Id": "eb5971acd65a4cdea49f5419b4c71b53" + } + ], + "synonyms": [ + "switch" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_floorPredicate": true, + "m_cases": [], + "m_useProperty": false, + "m_casesFromUpstreamEnumProperty": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.OneMinusNode", + "m_ObjectId": "6d5dc37b5d6045f8a027615cd3fc848e", + "m_Group": { + "m_Id": "" + }, + "m_Name": "One Minus", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1131.0001220703125, + "y": 1214.0, + "width": 128.00006103515625, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "6342733b9a444ffd981fc1d8682b50d7" + }, + { + "m_Id": "60b349a8f20448748d81b7fece92c734" + } + ], + "synonyms": [ + "complement", + "invert", + "opposite" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.ColorRGBMaterialSlot", + "m_ObjectId": "6e63940ae3d44e4d956173a0c3bbdac8", + "m_Id": 0, + "m_DisplayName": "Base Color", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "BaseColor", + "m_StageCapability": 2, + "m_Value": { + "x": 0.5, + "y": 0.5, + "z": 0.5 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0 + }, + "m_Labels": [], + "m_ColorMode": 0, + "m_DefaultColor": { + "r": 0.5, + "g": 0.5, + "b": 0.5, + "a": 1.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "74f782d808aa4fa18ddf138ae151b4fd", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.RedirectNodeData", + "m_ObjectId": "786a73d10fcc4617adf9a95b1360219c", + "m_Group": { + "m_Id": "54785739c3f44f0682783b7035865e27" + }, + "m_Name": "Redirect Node", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 537.0, + "y": 1082.0, + "width": 56.0, + "height": 24.0 + } + }, + "m_Slots": [ + { + "m_Id": "d6cd482bbfd149928bd738a61530b418" + }, + { + "m_Id": "1a76923c5fbf4951977d90ae28c6f5c4" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "7ab64666a0a443faad1858d8a7c0661b", + "m_Group": { + "m_Id": "" + }, + "m_Name": "SurfaceDescription.BaseColor", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "6e63940ae3d44e4d956173a0c3bbdac8" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "SurfaceDescription.BaseColor" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SubGraphNode", + "m_ObjectId": "829c7b8d90c24fc29bee9b09ca2a813e", + "m_Group": { + "m_Id": "54785739c3f44f0682783b7035865e27" + }, + "m_Name": "Switch Subgraph", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 428.0, + "y": 1106.0, + "width": 165.0, + "height": 104.0 + } + }, + "m_Slots": [ + { + "m_Id": "9051d9533117463999dbe9951c691941" + }, + { + "m_Id": "c42133cc317c4a89abf34ab621bb58ff" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedSubGraph": "{\n \"subGraph\": {\n \"fileID\": -5475051401550479605,\n \"guid\": \"0546d5c2671cc184e8c4c2b2a21ce30c\",\n \"type\": 3\n }\n}", + "m_PropertyGuids": [ + "865ae136-ddb7-484f-b52f-8d1dcbb71815" + ], + "m_PropertyIds": [ + -964647681 + ], + "m_Dropdowns": [], + "m_DropdownSelectedEntries": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "835a53cf77e8496fa1d1f5b0895f4a5c", + "m_Id": 6, + "m_DisplayName": "Down", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Down", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "8565765e60a04d65ab6b75df83c29206", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.BuiltinData", + "m_ObjectId": "87f111498871432ba1442e6ffd024e39", + "m_Distortion": false, + "m_DistortionMode": 0, + "m_DistortionDepthTest": true, + "m_AddPrecomputedVelocity": false, + "m_TransparentWritesMotionVec": false, + "m_DepthOffset": false, + "m_ConservativeDepthOffset": false, + "m_TransparencyFog": true, + "m_AlphaTestShadow": false, + "m_BackThenFrontRendering": false, + "m_TransparentDepthPrepass": false, + "m_TransparentDepthPostpass": false, + "m_TransparentPerPixelSorting": false, + "m_SupportLodCrossFade": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SwitchNode", + "m_ObjectId": "88db34002bd7426c8d263ada58987154", + "m_Group": { + "m_Id": "fed2c2b7925a49029c0514aaebf31995" + }, + "m_Name": "Switch", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -441.0000305175781, + "y": 1353.9998779296875, + "width": 207.9999542236328, + "height": 398.0 + } + }, + "m_Slots": [ + { + "m_Id": "ee9c6f8c7ca245878ec31f3f39d134d8" + }, + { + "m_Id": "c314f37e724c4e4db856c1d4c77f1d3a" + }, + { + "m_Id": "74f782d808aa4fa18ddf138ae151b4fd" + }, + { + "m_Id": "52a6d1fa9f964a579b2a44d23a25e2ec" + }, + { + "m_Id": "9bdad34089574766a79e996e2dbe5b6d" + }, + { + "m_Id": "144f24d7fc774915a76c611652195b92" + }, + { + "m_Id": "1c96ec8b86c0428882052d03b795826c" + } + ], + "synonyms": [ + "switch" + ], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_floorPredicate": true, + "m_cases": [ + { + "name": "", + "comparisonType": 0, + "threshold": 0.0 + }, + { + "name": "", + "comparisonType": 0, + "threshold": 1.0 + }, + { + "name": "", + "comparisonType": 0, + "threshold": 2.0 + }, + { + "name": "", + "comparisonType": 0, + "threshold": 3.0 + } + ], + "m_useProperty": false, + "m_casesFromUpstreamEnumProperty": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "88ed63112fd5414f9c2a2edc62076770", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "8a1a3212e26943d792174bd06b74faf4", + "m_Title": "Switch node", + "m_Content": "The Node will automatically setup when connecting a Float Property setup as Enum to the Predicate Input.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -198.0, + "y": 635.0, + "width": 200.0, + "height": 123.0 + }, + "m_Group": { + "m_Id": "fcd45624a2d142c88f3c301e8c742685" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialEnumSlot", + "m_ObjectId": "9051d9533117463999dbe9951c691941", + "m_Id": -964647681, + "m_DisplayName": "Direction", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "_Direction", + "m_StageCapability": 3, + "m_Value": 2.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false, + "options": [ + "Right", + "Left", + "Up", + "Down" + ], + "values": [ + 0, + 1, + 2, + 3 + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "90a1075c53884f4293af9a81824ada3b", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "9bdad34089574766a79e996e2dbe5b6d", + "m_Id": 4, + "m_DisplayName": "B", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_B", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInTarget", + "m_ObjectId": "9ea137df613a4e37a44ea08d07c5d60a", + "m_Datas": [], + "m_ActiveSubTarget": { + "m_Id": "9faa5ad4f4fd489babfd2a0a2b396d9c" + }, + "m_AllowMaterialOverride": false, + "m_SurfaceType": 0, + "m_ZWriteControl": 0, + "m_ZTestMode": 4, + "m_AlphaMode": 0, + "m_RenderFace": 2, + "m_AlphaClip": false, + "m_CustomEditorGUI": "" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.BuiltIn.ShaderGraph.BuiltInUnlitSubTarget", + "m_ObjectId": "9faa5ad4f4fd489babfd2a0a2b396d9c" +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "a2db761472fb45bb805f40904c3a0250", + "m_Guid": { + "m_GuidSerialized": "9e3742e0-c70a-4892-ad44-ffe1aa4be194" + }, + "promotedFromAssetID": "", + "promotedFromCategoryName": "", + "promotedOrdering": -1, + "m_Name": "Direction", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Direction", + "m_DefaultReferenceName": "_Direction", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_DismissedVersion": 0, + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "hideConnector": false, + "m_Hidden": false, + "m_PerRendererData": false, + "m_customAttributes": [], + "m_Value": 0.0, + "m_FloatType": 3, + "m_LiteralFloatMode": false, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + }, + "m_SliderType": 0, + "m_SliderPower": 3.0, + "m_EnumType": 0, + "m_CSharpEnumString": "", + "m_EnumNames": [ + "Right", + "Left", + "Up", + "Down" + ], + "m_EnumValues": [ + 0, + 1, + 2, + 3 + ] +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SampleGradient", + "m_ObjectId": "a8b35eb6e35847958e10794e7251e5f2", + "m_Group": { + "m_Id": "fed2c2b7925a49029c0514aaebf31995" + }, + "m_Name": "Sample Gradient", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 47.9998779296875, + "y": 1329.9998779296875, + "width": 208.0000762939453, + "height": 302.0 + } + }, + "m_Slots": [ + { + "m_Id": "c86a10f3b3084ba0b87190d2a4c93a68" + }, + { + "m_Id": "fbb5b375a4304eca8a203fd4191bfa2f" + }, + { + "m_Id": "265a360c19f748d4bdd8d6d9d709796f" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 2, + "m_Type": "UnityEditor.Rendering.Universal.ShaderGraph.UniversalUnlitSubTarget", + "m_ObjectId": "ac3f0044c20c43488dc9c80d8ea1b4d9", + "m_KeepLightingVariants": false, + "m_DefaultDecalBlending": true, + "m_DefaultSSAO": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "adb9b1b2cc1a4b82a3e100259d4c1776", + "m_Id": 4, + "m_DisplayName": "Left", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Left", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDTarget", + "m_ObjectId": "b0ee8fd821e2468ba5e019735c2d4906", + "m_ActiveSubTarget": { + "m_Id": "5a83a7b3743d4d1cbbc07892539c9dae" + }, + "m_Datas": [ + { + "m_Id": "87f111498871432ba1442e6ffd024e39" + }, + { + "m_Id": "4f0cf95387cf47ca8a3b6776923bf646" + }, + { + "m_Id": "ba482ca446d84ad9938fc89adae4bc3d" + } + ], + "m_CustomEditorGUI": "", + "m_SupportVFX": false, + "m_SupportLineRendering": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientNode", + "m_ObjectId": "b5021080fafc4e2c999541fa04952ad0", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Gradient", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -185.0, + "y": 1039.9998779296875, + "width": 207.99993896484375, + "height": 104.0 + } + }, + "m_Slots": [ + { + "m_Id": "ff88c30f169542e285be49c776a5dfdf" + } + ], + "synonyms": [ + "ramp" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Value": 0.0, + "m_SerializableColorKeys": [ + { + "x": 0.046665094792842865, + "y": 0.23839765787124634, + "z": 0.24620139598846436, + "w": 0.16659800708293915 + }, + { + "x": 0.0036765069235116243, + "y": 0.08650046586990356, + "z": 0.17464745044708252, + "w": 0.330006867647171 + }, + { + "x": 0.003346535610035062, + "y": 0.002428215928375721, + "z": 0.03310477361083031, + "w": 0.5000076293945313 + }, + { + "x": 0.7304610013961792, + "y": 0.031896039843559265, + "z": 0.003346535610035062, + "w": 0.6599984765052795 + }, + { + "x": 0.8227859735488892, + "y": 0.23839765787124634, + "z": 0.004776953253895044, + "w": 0.8334019780158997 + }, + { + "x": 0.9301111698150635, + "y": 0.7454044818878174, + "z": 0.4735315442085266, + "w": 1.0 + } + ], + "m_SerializableAlphaKeys": [ + { + "x": 1.0, + "y": 0.0 + }, + { + "x": 1.0, + "y": 1.0 + } + ], + "m_SerializableMode": 1 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "b8d9371775a04f7f9ec8f57b26419fad", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SampleGradient", + "m_ObjectId": "b905d646c66b499086f99872bea6b643", + "m_Group": { + "m_Id": "54785739c3f44f0682783b7035865e27" + }, + "m_Name": "Sample Gradient", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 662.0000610351563, + "y": 1082.0, + "width": 168.0, + "height": 118.0 + } + }, + "m_Slots": [ + { + "m_Id": "2de7d325d5df416d93306e9882668d10" + }, + { + "m_Id": "2bcd7cbdeed942908b744af35d7a802d" + }, + { + "m_Id": "1e1f96144b0d4424a64f24041d4648cf" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.Rendering.HighDefinition.ShaderGraph.HDUnlitData", + "m_ObjectId": "ba482ca446d84ad9938fc89adae4bc3d", + "m_EnableShadowMatte": false, + "m_DistortionOnly": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "bf6bf86bbcfe4ca98df86761383b98c0", + "m_Id": 1, + "m_DisplayName": "Time", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "c0596ea6fd5d46adb66f81ccf6f47127", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "c095c741fdca48e88a13fadf47556f4a", + "m_Id": 0, + "m_DisplayName": "Predicate", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Predicate", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "c314f37e724c4e4db856c1d4c77f1d3a", + "m_Id": 1, + "m_DisplayName": "Fallback", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Fallback", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "c31d9699267e4a6188af2461669d842b", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "c42133cc317c4a89abf34ab621bb58ff", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientInputMaterialSlot", + "m_ObjectId": "c86a10f3b3084ba0b87190d2a4c93a68", + "m_Id": 0, + "m_DisplayName": "Gradient", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Gradient", + "m_StageCapability": 3, + "m_Value": { + "serializedVersion": "2", + "key0": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key1": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key2": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key3": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key4": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key5": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key6": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key7": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "ctime0": 0, + "ctime1": 65535, + "ctime2": 0, + "ctime3": 0, + "ctime4": 0, + "ctime5": 0, + "ctime6": 0, + "ctime7": 0, + "atime0": 0, + "atime1": 65535, + "atime2": 0, + "atime3": 0, + "atime4": 0, + "atime5": 0, + "atime6": 0, + "atime7": 0, + "m_Mode": 0, + "m_ColorSpace": -1, + "m_NumColorKeys": 2, + "m_NumAlphaKeys": 2 + }, + "m_DefaultValue": { + "serializedVersion": "2", + "key0": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key1": { + "r": 1.0, + "g": 1.0, + "b": 1.0, + "a": 1.0 + }, + "key2": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key3": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key4": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key5": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key6": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "key7": { + "r": 0.0, + "g": 0.0, + "b": 0.0, + "a": 0.0 + }, + "ctime0": 0, + "ctime1": 65535, + "ctime2": 0, + "ctime3": 0, + "ctime4": 0, + "ctime5": 0, + "ctime6": 0, + "ctime7": 0, + "atime0": 0, + "atime1": 65535, + "atime2": 0, + "atime3": 0, + "atime4": 0, + "atime5": 0, + "atime6": 0, + "atime7": 0, + "m_Mode": 0, + "m_ColorSpace": -1, + "m_NumColorKeys": 2, + "m_NumAlphaKeys": 2 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.BlockNode", + "m_ObjectId": "d264465c5f5f4cafb4282e5c29fa0052", + "m_Group": { + "m_Id": "" + }, + "m_Name": "VertexDescription.Normal", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": 0.0, + "y": 0.0, + "width": 0.0, + "height": 0.0 + } + }, + "m_Slots": [ + { + "m_Id": "0500b8f2eb9b4cc8b0edc29c8d4c4de2" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": true, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_SerializedDescriptor": "VertexDescription.Normal" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d46ddfcf7952480b870cda84f67fe35c", + "m_Id": 0, + "m_DisplayName": "Direction", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientMaterialSlot", + "m_ObjectId": "d6cd482bbfd149928bd738a61530b418", + "m_Id": 0, + "m_DisplayName": "", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "", + "m_StageCapability": 3 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "d812f3403fcc47f89db995a964fcf197", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "e68de41d29ba4473bffd4eff3020de4c", + "m_Id": 1, + "m_DisplayName": "Fallback", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Fallback", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.StickyNoteData", + "m_ObjectId": "eaf10b588af74584971a91e776805cd5", + "m_Title": "Switch node", + "m_Content": "The Switch Node selects between several inputs, based on the Predicate input value.", + "m_TextSize": 0, + "m_Theme": 0, + "m_Position": { + "serializedVersion": "2", + "x": -186.0, + "y": 195.0, + "width": 200.0, + "height": 123.0 + }, + "m_Group": { + "m_Id": "" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "eb5971acd65a4cdea49f5419b4c71b53", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": true +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "ee9c6f8c7ca245878ec31f3f39d134d8", + "m_Id": 0, + "m_DisplayName": "Predicate", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Predicate", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "f164fddb52af46e28a970b9a6e555b89", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "f456104168cb4f25a378f7dbb1d98f41", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "a2db761472fb45bb805f40904c3a0250" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "f804b1063271497284b3d701ecd098d8", + "m_Id": 3, + "m_DisplayName": "Right", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Right", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "faebd47487f54224bc01167ad391828c", + "m_Id": 0, + "m_DisplayName": "Predicate", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Predicate", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "fb195d2ff3244d8896960d2ba4788117", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -1132.0, + "y": 879.0, + "width": 128.0, + "height": 122.0 + } + }, + "m_Slots": [ + { + "m_Id": "c0596ea6fd5d46adb66f81ccf6f47127" + }, + { + "m_Id": "0be04c690d594ba78eb4b46775f02223" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "x", + "convertedMask": "x" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fbb5b375a4304eca8a203fd4191bfa2f", + "m_Id": 1, + "m_DisplayName": "Time", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Time", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "fcd45624a2d142c88f3c301e8c742685", + "m_Title": "Auto Setup", + "m_Position": { + "x": -466.0001220703125, + "y": 420.0000305175781 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GroupData", + "m_ObjectId": "fed2c2b7925a49029c0514aaebf31995", + "m_Title": "Manual Setup", + "m_Position": { + "x": -466.0001220703125, + "y": 1271.0 + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.GradientMaterialSlot", + "m_ObjectId": "ff88c30f169542e285be49c776a5dfdf", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3 +} + diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Switch.shadergraph.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Switch.shadergraph.meta new file mode 100644 index 00000000000..eeb919d3160 --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/Switch.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 393ffb657289a5d4190160db5657ffdd +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/SwitchSubgraph.shadersubgraph b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/SwitchSubgraph.shadersubgraph new file mode 100644 index 00000000000..e5d1e8f434f --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/SwitchSubgraph.shadersubgraph @@ -0,0 +1,1054 @@ +{ + "m_SGVersion": 3, + "m_Type": "UnityEditor.ShaderGraph.GraphData", + "m_ObjectId": "23fd47f284844ad0abc20ad50f31049f", + "m_Properties": [ + { + "m_Id": "474c2d5f12dd4b80bdee28db4e93a5ed" + } + ], + "m_Keywords": [], + "m_Dropdowns": [], + "m_CategoryData": [ + { + "m_Id": "d9bed99533f94c90b3c4307f869ef297" + } + ], + "m_Nodes": [ + { + "m_Id": "321fe86d13ee465c9b4cdc7d919e04ea" + }, + { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + { + "m_Id": "50dcf206025e429b9c550e1d67d630b1" + }, + { + "m_Id": "bf95c6113cf4455aa90315585093eb60" + }, + { + "m_Id": "9b47e21422b44e1687e7c2491fef7d43" + }, + { + "m_Id": "f4177537536f4411b1b745d3aba7ad39" + }, + { + "m_Id": "fda2b6cbd3ed4216b2eaad053505d3b5" + }, + { + "m_Id": "268b47ec8a884f5e99d916416257206a" + } + ], + "m_GroupDatas": [], + "m_StickyNoteDatas": [], + "m_Edges": [ + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "268b47ec8a884f5e99d916416257206a" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 6 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "50dcf206025e429b9c550e1d67d630b1" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "9b47e21422b44e1687e7c2491fef7d43" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "9b47e21422b44e1687e7c2491fef7d43" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 3 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "9b47e21422b44e1687e7c2491fef7d43" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "fda2b6cbd3ed4216b2eaad053505d3b5" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "bf95c6113cf4455aa90315585093eb60" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "9b47e21422b44e1687e7c2491fef7d43" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "bf95c6113cf4455aa90315585093eb60" + }, + "m_SlotId": 0 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "f4177537536f4411b1b745d3aba7ad39" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 2 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "321fe86d13ee465c9b4cdc7d919e04ea" + }, + "m_SlotId": 1 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f4177537536f4411b1b745d3aba7ad39" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "268b47ec8a884f5e99d916416257206a" + }, + "m_SlotId": 0 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "f4177537536f4411b1b745d3aba7ad39" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 5 + } + }, + { + "m_OutputSlot": { + "m_Node": { + "m_Id": "fda2b6cbd3ed4216b2eaad053505d3b5" + }, + "m_SlotId": 1 + }, + "m_InputSlot": { + "m_Node": { + "m_Id": "c01f7cb4afd2474f8499b34a5ac37838" + }, + "m_SlotId": 4 + } + } + ], + "m_VertexContext": { + "m_Position": { + "x": 0.0, + "y": 0.0 + }, + "m_Blocks": [] + }, + "m_FragmentContext": { + "m_Position": { + "x": 0.0, + "y": 0.0 + }, + "m_Blocks": [] + }, + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"instanceID\":0}}", + "m_Guid": "" + }, + "preventRotation": false + }, + "m_Path": "Sub Graphs", + "m_GraphPrecision": 1, + "m_PreviewMode": 1, + "m_OutputNode": { + "m_Id": "321fe86d13ee465c9b4cdc7d919e04ea" + }, + "m_SubDatas": [], + "m_ActiveTargets": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "051fd7a1c13d4869ac8c11b0e8d93882", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "0c98a278f0a340e2976a8d9362386382", + "m_Id": 3, + "m_DisplayName": "Right", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Right", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "11f54738831c4ee19dda63774b0ea9f7", + "m_Id": 5, + "m_DisplayName": "Up", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Up", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.OneMinusNode", + "m_ObjectId": "268b47ec8a884f5e99d916416257206a", + "m_Group": { + "m_Id": "" + }, + "m_Name": "One Minus", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -610.4286499023438, + "y": 321.14288330078127, + "width": 128.0, + "height": 94.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "9fc3f17a7d2f4b0189bae92801781ea4" + }, + { + "m_Id": "4e83036566f44821920c7d9dd5df4304" + } + ], + "synonyms": [ + "complement", + "invert", + "opposite" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector2MaterialSlot", + "m_ObjectId": "304e540288f847d8b79e2652e56f7fa5", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SubGraphOutputNode", + "m_ObjectId": "321fe86d13ee465c9b4cdc7d919e04ea", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Output", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -122.0, + "y": 193.0, + "width": 86.0, + "height": 77.0 + } + }, + "m_Slots": [ + { + "m_Id": "9e8c79f50abc4231a3923f70ac717a0b" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "IsFirstSlotValid": true +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.Internal.Vector1ShaderProperty", + "m_ObjectId": "474c2d5f12dd4b80bdee28db4e93a5ed", + "m_Guid": { + "m_GuidSerialized": "865ae136-ddb7-484f-b52f-8d1dcbb71815" + }, + "promotedFromAssetID": "", + "promotedFromCategoryName": "", + "promotedOrdering": -1, + "m_Name": "Direction", + "m_DefaultRefNameVersion": 1, + "m_RefNameGeneratedByDisplayName": "Direction", + "m_DefaultReferenceName": "_Direction", + "m_OverrideReferenceName": "", + "m_GeneratePropertyBlock": true, + "m_UseCustomSlotLabel": false, + "m_CustomSlotLabel": "", + "m_DismissedVersion": 0, + "m_Precision": 0, + "overrideHLSLDeclaration": false, + "hlslDeclarationOverride": 0, + "hideConnector": false, + "m_Hidden": false, + "m_PerRendererData": false, + "m_customAttributes": [], + "m_Value": 0.0, + "m_FloatType": 3, + "m_LiteralFloatMode": false, + "m_RangeValues": { + "x": 0.0, + "y": 1.0 + }, + "m_SliderType": 0, + "m_SliderPower": 3.0, + "m_EnumType": 0, + "m_CSharpEnumString": "", + "m_EnumNames": [ + "Right", + "Left", + "Up", + "Down" + ], + "m_EnumValues": [ + 0, + 1, + 2, + 3 + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "4e83036566f44821920c7d9dd5df4304", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.PropertyNode", + "m_ObjectId": "50dcf206025e429b9c550e1d67d630b1", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Property", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -290.0, + "y": 159.0, + "width": 122.0, + "height": 34.0 + } + }, + "m_Slots": [ + { + "m_Id": "8023705dd1d041f9b7b6888217908218" + } + ], + "synonyms": [], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_Property": { + "m_Id": "474c2d5f12dd4b80bdee28db4e93a5ed" + } +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "7cdf9005838942c297737b99174359b2", + "m_Id": 6, + "m_DisplayName": "Down", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Down", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "7e6b485ec7cd4f5ebaa0609df97d3cc9", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "8023705dd1d041f9b7b6888217908218", + "m_Id": 0, + "m_DisplayName": "Direction", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "9b47e21422b44e1687e7c2491fef7d43", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -780.4286499023438, + "y": 193.14288330078126, + "width": 128.0, + "height": 122.0 + } + }, + "m_Slots": [ + { + "m_Id": "c706a80d7ecb4efa9062e60a8eb6fa75" + }, + { + "m_Id": "051fd7a1c13d4869ac8c11b0e8d93882" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "x", + "convertedMask": "x" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "9e8c79f50abc4231a3923f70ac717a0b", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "9fc3f17a7d2f4b0189bae92801781ea4", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": { + "x": 1.0, + "y": 1.0, + "z": 1.0, + "w": 1.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector4MaterialSlot", + "m_ObjectId": "a64cf70e1c534ab484a31a16bf714801", + "m_Id": 0, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_Labels": [] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "b523a23b62b24eed9aacba0f92d36339", + "m_Id": 0, + "m_DisplayName": "Predicate", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Predicate", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.UVNode", + "m_ObjectId": "bf95c6113cf4455aa90315585093eb60", + "m_Group": { + "m_Id": "" + }, + "m_Name": "UV", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -957.4286499023438, + "y": 193.14288330078126, + "width": 145.0, + "height": 128.0 + } + }, + "m_Slots": [ + { + "m_Id": "a64cf70e1c534ab484a31a16bf714801" + } + ], + "synonyms": [ + "texcoords", + "coords", + "coordinates" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_OutputChannel": 0 +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.SwitchNode", + "m_ObjectId": "c01f7cb4afd2474f8499b34a5ac37838", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Switch", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -290.0, + "y": 193.0, + "width": 168.0, + "height": 214.0 + } + }, + "m_Slots": [ + { + "m_Id": "b523a23b62b24eed9aacba0f92d36339" + }, + { + "m_Id": "ee358b82f0f4420cb281d8ecf1e4bb5e" + }, + { + "m_Id": "e911ddd2470c4eb5906fbf3ade7db540" + }, + { + "m_Id": "0c98a278f0a340e2976a8d9362386382" + }, + { + "m_Id": "ddd6234fe5ed4f5c9c9806f84ce51194" + }, + { + "m_Id": "11f54738831c4ee19dda63774b0ea9f7" + }, + { + "m_Id": "7cdf9005838942c297737b99174359b2" + } + ], + "synonyms": [ + "switch" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "m_floorPredicate": true, + "m_cases": [], + "m_useProperty": true, + "m_casesFromUpstreamEnumProperty": [ + { + "name": "Right", + "comparisonType": 0, + "threshold": 0.0 + }, + { + "name": "Left", + "comparisonType": 0, + "threshold": 1.0 + }, + { + "name": "Up", + "comparisonType": 0, + "threshold": 2.0 + }, + { + "name": "Down", + "comparisonType": 0, + "threshold": 3.0 + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "c706a80d7ecb4efa9062e60a8eb6fa75", + "m_Id": 0, + "m_DisplayName": "In", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "In", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.CategoryData", + "m_ObjectId": "d9bed99533f94c90b3c4307f869ef297", + "m_Name": "", + "m_ChildObjectList": [ + { + "m_Id": "474c2d5f12dd4b80bdee28db4e93a5ed" + } + ] +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ddd6234fe5ed4f5c9c9806f84ce51194", + "m_Id": 4, + "m_DisplayName": "Left", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "case_Left", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "df2efcdb03ec4e7a88583af63fcd8a87", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "e911ddd2470c4eb5906fbf3ade7db540", + "m_Id": 2, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.DynamicVectorMaterialSlot", + "m_ObjectId": "ee358b82f0f4420cb281d8ecf1e4bb5e", + "m_Id": 1, + "m_DisplayName": "Fallback", + "m_SlotType": 0, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Fallback", + "m_StageCapability": 3, + "m_Value": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_DefaultValue": { + "x": 0.0, + "y": 0.0, + "z": 0.0, + "w": 0.0 + }, + "m_LiteralMode": false +} + +{ + "m_SGVersion": 1, + "m_Type": "UnityEditor.ShaderGraph.SwizzleNode", + "m_ObjectId": "f4177537536f4411b1b745d3aba7ad39", + "m_Group": { + "m_Id": "" + }, + "m_Name": "Swizzle", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -780.4286499023438, + "y": 321.14288330078127, + "width": 128.99993896484376, + "height": 122.00006103515625 + } + }, + "m_Slots": [ + { + "m_Id": "304e540288f847d8b79e2652e56f7fa5" + }, + { + "m_Id": "fa2a6db3217c46eda90e631e0e59c34e" + } + ], + "synonyms": [ + "swap", + "reorder", + "component mask" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + }, + "_maskInput": "y", + "convertedMask": "y" +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.Vector1MaterialSlot", + "m_ObjectId": "fa2a6db3217c46eda90e631e0e59c34e", + "m_Id": 1, + "m_DisplayName": "Out", + "m_SlotType": 1, + "m_Hidden": false, + "m_HideConnector": false, + "m_ShaderOutputName": "Out", + "m_StageCapability": 3, + "m_Value": 0.0, + "m_DefaultValue": 0.0, + "m_Labels": [], + "m_LiteralMode": false +} + +{ + "m_SGVersion": 0, + "m_Type": "UnityEditor.ShaderGraph.OneMinusNode", + "m_ObjectId": "fda2b6cbd3ed4216b2eaad053505d3b5", + "m_Group": { + "m_Id": "" + }, + "m_Name": "One Minus", + "m_DrawState": { + "m_Expanded": true, + "m_Position": { + "serializedVersion": "2", + "x": -610.4286499023438, + "y": 193.14288330078126, + "width": 128.0, + "height": 94.0 + } + }, + "m_Slots": [ + { + "m_Id": "7e6b485ec7cd4f5ebaa0609df97d3cc9" + }, + { + "m_Id": "df2efcdb03ec4e7a88583af63fcd8a87" + } + ], + "synonyms": [ + "complement", + "invert", + "opposite" + ], + "m_Precision": 0, + "m_PreviewExpanded": false, + "m_DismissedVersion": 0, + "m_PreviewMode": 0, + "m_CustomColors": { + "m_SerializableColors": [] + } +} + diff --git a/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/SwitchSubgraph.shadersubgraph.meta b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/SwitchSubgraph.shadersubgraph.meta new file mode 100644 index 00000000000..74adf997f8d --- /dev/null +++ b/Packages/com.unity.shadergraph/Samples~/NodeReference/Utility/SwitchSubgraph.shadersubgraph.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0546d5c2671cc184e8c4c2b2a21ce30c +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 60072b568d64c40a485e0fc55012dc9f, type: 3} + documentationPath: diff --git a/Packages/com.unity.shadergraph/Tests/Editor/ProviderTests/StrongHintTests.cs b/Packages/com.unity.shadergraph/Tests/Editor/ProviderTests/StrongHintTests.cs new file mode 100644 index 00000000000..08d016e1e19 --- /dev/null +++ b/Packages/com.unity.shadergraph/Tests/Editor/ProviderTests/StrongHintTests.cs @@ -0,0 +1,306 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace UnityEditor.ShaderGraph.ProviderSystem.Tests +{ + class TestProvider : IProvider + { + public string ProviderKey { get; private set; } + public GUID AssetID { get; private set; } + public IShaderFunction Definition { get; private set; } + + internal TestProvider(string testName, IShaderFunction func) + { + ProviderKey = testName; + Definition = func; + } + + internal TestProvider(string testName, string path = null, IEnumerable namespaces = null) + { + ProviderKey = testName; + AssetID = path == null ? default : AssetDatabase.GUIDFromAssetPath(path); + Definition = new ShaderFunction(testName, namespaces, null, new ShaderType("void"), null, null); + } + + internal TestProvider(string testName, string hintKey, string hintValue, string path = null, IEnumerable namespaces = null) + { + ProviderKey = testName; + AssetID = path == null ? default : AssetDatabase.GUIDFromAssetPath(path); + Definition = new ShaderFunction(testName, namespaces, null, new ShaderType("void"), null, new Dictionary { { hintKey, hintValue } }); + } + + public IProvider Clone() + { + throw new NotImplementedException(); + } + } + + [TestFixture] + class StrongHintTests + { + private static void DoConflictTest(HintRegistry reg, string testName, IEnumerable hintSet, int expectSuccess, bool expectMessage, Dictionary values, List messages) + { + values.Clear(); + messages.Clear(); + + var obj = new TestObject(testName, hintSet); + + reg.ProcessObject(obj, null, out values, out messages); + + Assert.AreEqual(expectSuccess, values.Count, $"{testName} successes expected"); + Assert.AreEqual(expectMessage, messages.Count > 0, $"{testName} conflicts expected"); + } + + private static void DoDisplayNameTest(HintRegistry reg, string referenceName, string displayName, Dictionary values, List messages) + { + + + if (displayName == null) + displayName = referenceName; + + var hints = new Dictionary(); + if (displayName != null) + hints.Add(Hints.Common.kDisplayName, displayName); + + var obj = new TestObject(referenceName, hints); + + DoOneHintTest(reg, obj, true, displayName, false, values, messages, Hints.Common.kDisplayName); + } + + private static IShaderField Param(string testName, IShaderType shaderType, string hintKey, string hintValueRaw) + { + var hints = new Dictionary() { { hintKey, hintValueRaw } }; + return new ShaderField(testName, true, false, shaderType, hints); + } + + private static void DoOneHintTest(HintRegistry reg, IProvider provider, bool expectsValue, V expectedValue, bool expectsMessage, Dictionary values, List messages, string hintKey = null) where T : IShaderObject + { + DoOneHintTest(reg, provider.Definition, expectsValue, expectedValue, expectsMessage, values, messages, hintKey, provider); + } + + private static void DoOneHintTest(HintRegistry reg, T obj, bool expectsValue, V expectedValue, bool expectsMessage, Dictionary values, List messages, string hintKey = null, IProvider provider = null) where T : IShaderObject + { + values.Clear(); + messages.Clear(); + + string testName = obj.Name; + if (hintKey == null) + foreach (var hint in obj.Hints.Keys) + hintKey = hint; + + Assert.NotNull(hintKey, $"ShaderObject {obj.Name} must have a hint to test."); + + reg.ProcessObject((T)obj, provider, out values, out messages); + + Assert.AreEqual(expectsValue, values.Count > 0, $"{testName} for {hintKey}, value expected"); + Assert.AreEqual(expectsMessage, messages.Count > 0, $"{testName} for {hintKey}, message expected"); + if (expectsValue) + Assert.AreEqual(expectedValue, values[hintKey], $"{testName} for {hintKey}, expected value"); + } + + struct TestObject : IShaderObject + { + public string Name { get; private set; } + public IReadOnlyDictionary Hints { get; private set; } + public bool IsValid => true; + + internal TestObject(string name, IEnumerable flagHints) + { + Name = name; + Dictionary hints = new(); + foreach (var hint in flagHints) + hints.Add(hint, ""); + Hints = hints; + } + + internal TestObject(string name, Dictionary hints) + { + Name = name; + Hints = hints; + } + } + + [Test] + public void ConflictClasses() + { + HintRegistry reg = new(); + + var ha = new Hints.Flag("hA", "cA"); + var hb = new Hints.Flag("hB", "cA"); + var hc = new Hints.Flag("hC", "cB"); + var hd = new Hints.Flag("hD", "cB"); + + reg.RegisterStrongHint(ha); + reg.RegisterStrongHint(hb); + reg.RegisterStrongHint(hc); + reg.RegisterStrongHint(hd); + + Dictionary values = new(); + List messages = new(); + + DoConflictTest(reg, "BaseNoResults", new string[] { }, 0, false, values, messages); + DoConflictTest(reg, "OneConflict", new string[] { "hA", "hB" }, 0, true, values, messages); + DoConflictTest(reg, "TwoConflicts", new string[] { "hA", "hB", "hC", "hD" }, 0, true, values, messages); + DoConflictTest(reg, "OneConflictOneSafe", new string[] { "hA", "hC", "hD" }, 1, true, values, messages); + DoConflictTest(reg, "Safe2Results", new string[] { "hA", "hC" }, 2, false, values, messages); + } + + [Test] + public void DisplayName() + { + HintRegistry reg = new(); + reg.RegisterStrongHint(new Hints.DisplayName()); + + Dictionary values = new(); + List messages = new(); + + DoDisplayNameTest(reg, "TestObject", null, values, messages); // default to reference name + DoDisplayNameTest(reg, "TestObject", "Test Object DisplayName", values, messages); + } + + + [Test] + public void TestRange() + { + // Most hints are _very simple_. + HintRegistry reg = new(); + reg.RegisterStrongHint(new Hints.Range()); + + Dictionary values = new(); + List messages = new(); + + var floatType = new ShaderType("float"); + var halfType = new ShaderType("half"); + var float2Type = new ShaderType("float2"); + + // regularly supported use-cases + DoOneHintTest(reg, Param("RangeNone", floatType, Hints.Param.kRange, null), true, new float[2] { 0, 1 }, false, values, messages); + DoOneHintTest(reg, Param("RangeMin", floatType, Hints.Param.kRange, "-5"), true, new float[2] { -5, 0 }, false, values, messages); + DoOneHintTest(reg, Param("RangeMax", floatType, Hints.Param.kRange, "5"), true, new float[2] { 0, 5 }, false, values, messages); + DoOneHintTest(reg, Param("RangeMinMax", floatType, Hints.Param.kRange, "-5, 5"), true, new float[2] { -5, 5 }, false, values, messages); + DoOneHintTest(reg, Param("RangeMaxMin", floatType, Hints.Param.kRange, "5, -5"), true, new float[2] { -5, 5 }, false, values, messages); + DoOneHintTest(reg, Param("RangeHalfType", halfType, Hints.Param.kRange, null), true, new float[2] { 0, 1 }, false, values, messages); + + // invalid cases + DoOneHintTest(reg, Param("RangeTooManyArgs", floatType, Hints.Param.kRange, "5, -10, 10, -5"), false, new float[2] { 0, 0 }, true, values, messages); + DoOneHintTest(reg, Param("RangeTypeUnsupported", float2Type, Hints.Param.kRange, "-5, 5"), false, new float[2] { 0, 0 }, true, values, messages); + DoOneHintTest(reg, Param("RangeInvalidString", floatType, Hints.Param.kRange, "blah blah blah"), false, new float[2] { 0, 1 }, true, values, messages); + } + + [Test] + public void TestCategory() + { + var reg = new HintRegistry(); + reg.RegisterStrongHint(new Hints.SearchCategory()); + + Dictionary values = new(); + List messages = new(); + + var searchBase = new TestProvider("base", Hints.Func.kSearchCategory, "This/Is/A/Category"); + DoOneHintTest(reg, searchBase, true, "This/Is/A/Category", false, values, messages, Hints.Func.kSearchCategory); + + // Doesn't work on Mac; probably due to ADB warmup issues; TODO: determine why and correct this. + //var searchPath = new TestProvider("path", kAllHintsPath, null); + //DoOneHintTest(reg, searchPath, true, $"Reflected by Path/{kAllHintsPath}", false, values, messages, Hints.Func.kSearchCategory); + + // namespace should trump the file path fallback + var searchNamespace = new TestProvider("namespace", kAllHintsPath, new string[] { "NamespaceA", "NamespaceB" }); + DoOneHintTest(reg, searchNamespace, true, "Reflected by Namespace/NamespaceA/NamespaceB", false, values, messages, Hints.Func.kSearchCategory); + + var searchUncategorized = new TestProvider("nocategory"); + DoOneHintTest(reg, searchUncategorized, true, "Uncategorized", false, values, messages, Hints.Func.kSearchCategory); + } + + [Test] + public void SummaryAndSynonyms() + { + // Most hints are _very simple_. + HintRegistry reg = new(); + reg.RegisterStrongHint(new Hints.Tooltip()); + + Dictionary values = new(); + List messages = new(); + + string tooltipValue = "this is a tooltip"; + var noHint = new TestObject("NoHint", new Dictionary()); + var matchHint = new TestObject("WithCorrectHintName", new Dictionary() { { Hints.Common.kTooltip, tooltipValue } }); + var disqHint = new TestObject("WithDisqualifiedName", new Dictionary() { { "Tooltip", tooltipValue } }); + var altHint = new TestObject("WithAlternateSynonym", new Dictionary() { { "summary", tooltipValue } }); + + DoOneHintTest(reg, noHint, false, "", false, values, messages, Hints.Common.kTooltip); + DoOneHintTest(reg, matchHint, true, tooltipValue, false, values, messages, Hints.Common.kTooltip); + DoOneHintTest(reg, disqHint, true, tooltipValue, false, values, messages, Hints.Common.kTooltip); + DoOneHintTest(reg, altHint, true, tooltipValue, false, values, messages, Hints.Common.kTooltip); + } + + readonly string kAllHintsPath = "Assets/Testing/IntegrationTests/Graphs/ProviderSystem/AllHints.hlsl"; + readonly string kAllHintsGraphPath = "Assets/Testing/IntegrationTests/Graphs/ProviderSystem/ShouldCompileProperlyOnImport.shadergraph"; + + [Test] + public void CheckAllHints() + { + // 'AllHints.hlsl' is used by 'ShouldCompileOnImport.shadergraph' + // This reflected function covers most of our expected hint usage, so as a broad coverage integration test we can + // ask it to reimport, which will populate error messages and fail the test if anything is awry. + AssetDatabase.ImportAsset(kAllHintsPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); + AssetDatabase.ImportAsset(kAllHintsGraphPath, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate); + } + + [Test] + public void LegacyPrecisionAndDynamics() + { + Dictionary DynamicHint = new() { { Hints.Param.kDynamic, "" } }; + Dictionary PrecisionHint = new() { { Hints.Func.kPrecision, "" } }; + List generated = new() { "unity_sg_generated" }; + + ShaderType f = new("float"); + ShaderType h = new("half"); + ShaderType f2 = new("float2"); + ShaderType h2 = new("half2"); + ShaderType f3 = new("float3"); + ShaderType h3 = new("half3"); + ShaderType f4 = new("float4"); + ShaderType h4 = new("half4"); + + ShaderFunction testFunc = new("TestFunc", null, new IShaderField[] { + new ShaderField("A", true, true, f, DynamicHint), + new ShaderField("B", true, true, h3, DynamicHint), + new ShaderField("C", true, true, h2, null), + new ShaderField("D", true, true, f2, null) + }, f, "", PrecisionHint); + + var provider = new TestProvider("TestProvider", testFunc); + + var funcHeader = new FunctionHeader(); + var paramHeaders = new Dictionary(); + + funcHeader.Process(provider.Definition, provider); + foreach(var param in provider.Definition.Parameters) + paramHeaders.Add(param.Name, new ParameterHeader(param, provider)); + + + ShaderFunction expectedFunc = new("TestFunc_half4", generated, new IShaderField[] { + new ShaderField("A", true, true, h4, DynamicHint), + new ShaderField("B", true, true, h4, DynamicHint), + new ShaderField("C", true, true, h2, null), + new ShaderField("D", true, true, h2, null) + }, h, "", PrecisionHint); + + HeaderUtils.TryApplyLegacy(provider.Definition, funcHeader, paramHeaders, "half", 4, out var resultFunc); + Assert.IsTrue(TestUtils.CompareFunction(expectedFunc, resultFunc)); + + expectedFunc = new("TestFunc_float1", generated, new IShaderField[] { + new ShaderField("A", true, true, f, DynamicHint), + new ShaderField("B", true, true, f, DynamicHint), + new ShaderField("C", true, true, f2, null), + new ShaderField("D", true, true, f2, null) + }, f, "", PrecisionHint); + + HeaderUtils.TryApplyLegacy(provider.Definition, funcHeader, paramHeaders, "float", 1, out resultFunc); + Assert.IsTrue(TestUtils.CompareFunction(expectedFunc, resultFunc)); + } + } +} diff --git a/Packages/com.unity.shadergraph/Tests/Editor/ProviderTests/StrongHintTests.cs.meta b/Packages/com.unity.shadergraph/Tests/Editor/ProviderTests/StrongHintTests.cs.meta new file mode 100644 index 00000000000..ade4327b2b0 --- /dev/null +++ b/Packages/com.unity.shadergraph/Tests/Editor/ProviderTests/StrongHintTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: db6a00897eebf2349af1c113d527b270 \ No newline at end of file diff --git a/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs b/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs index 9ff8a425902..98d777c11a5 100644 --- a/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs +++ b/Packages/com.unity.shadergraph/Tests/Editor/UnitTests/MessageManagerTests.cs @@ -320,6 +320,27 @@ public void ReportAnyErrors_EmptyManager_ErrorOneProvider() var ret = m_EmptyMgr.HasSeverity(); Assert.IsTrue(ret); } + + [Test] + public void ClearNodesFromOtherProvider() + { + m_ComplexMgr.ClearNodeFromOtherProvider(p0, new List { node1 }); + + // Verify node1 is still in provider0 + Assert.IsTrue(m_ComplexMgr.Messages.ContainsKey(p0)); + Assert.IsTrue(m_ComplexMgr.Messages[p0].ContainsKey(node1.objectId)); + Assert.AreEqual(1, m_ComplexMgr.Messages[p0][node1.objectId].Count); + Assert.AreEqual(e2, m_ComplexMgr.Messages[p0][node1.objectId][0]); + + // Verify node1 is cleared from provider1 + Assert.IsTrue(m_ComplexMgr.Messages.ContainsKey(p1)); + Assert.IsTrue(m_ComplexMgr.Messages[p1].ContainsKey(node1.objectId)); + Assert.AreEqual(0, m_ComplexMgr.Messages[p1][node1.objectId].Count); + + // Verify other nodes in provider1 are unchanged + Assert.AreEqual(1, m_ComplexMgr.Messages[p1][node0.objectId].Count); + Assert.AreEqual(1, m_ComplexMgr.Messages[p1][node2.objectId].Count); + } } } diff --git a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs index c04a23fa08d..776a2f7d64c 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionAbstractValues.cs @@ -270,7 +270,6 @@ public override T Get() { if (typeof(T) == typeof(EntityId)) return (T)(object)base.Get(); - Debug.Assert(UnsafeUtility.SizeOf() == sizeof(int), "EntityId size is not equal to int size, this will cause issues, update to VFXValue instead"); return (T)(object)EditorUtility.EntityIdToObject(base.Get()); } diff --git a/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs b/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs index ae59a71cf0b..62c60e1e3b5 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/FilterPopup/VFXFilterWindow.cs @@ -7,7 +7,6 @@ using Unity.UI.Builder; using UnityEditor.UIElements; using UnityEngine; -using UnityEngine.Rendering; using UnityEngine.UIElements; namespace UnityEditor.VFX.UI diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXDataAnchorController.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXDataAnchorController.cs index 6ef268cc1ec..83561015b99 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXDataAnchorController.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/Controllers/VFXDataAnchorController.cs @@ -303,7 +303,6 @@ public virtual object value { if (typeof(UnityObject).IsAssignableFrom(storageType)) { - Debug.Assert(UnsafeUtility.SizeOf()==sizeof(int), "EntityId size is not the same as int, this will cause issues in VFXDataAnchorController"); EntityId entityId = (EntityId)evaluatedValue; return VFXConverter.ConvertTo(EditorUtility.EntityIdToObject(entityId), storageType); } diff --git a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXContextUI.cs b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXContextUI.cs index f43f3e476b2..47b43ebe2c3 100644 --- a/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXContextUI.cs +++ b/Packages/com.unity.visualeffectgraph/Editor/GraphView/Elements/VFXContextUI.cs @@ -284,7 +284,7 @@ public VFXContextUI() : base("uxml/VFXContext") m_FlowOutputConnectorContainer = this.Q("flow-outputs"); m_HeaderIcon = titleContainer.Q("icon"); - m_HeaderSpace = titleContainer.Q