public void DoGUI(string searchContext) { // When the asset being serialized has been deleted before its reconstruction if (serializedSettings != null && serializedSettings.serializedObject.targetObject == null) { serializedSettings = null; settingsSerialized = null; } if (serializedSettings == null || settingsSerialized != HDRenderPipelineGlobalSettings.instance) { if (HDRenderPipeline.currentAsset != null || HDRenderPipelineGlobalSettings.instance != null) { settingsSerialized = HDRenderPipelineGlobalSettings.Ensure(); var serializedObject = new SerializedObject(settingsSerialized); serializedSettings = new SerializedHDRenderPipelineGlobalSettings(serializedObject); } } else if (settingsSerialized != null && serializedSettings != null) { serializedSettings.serializedObject.Update(); } DrawAssetSelection(ref serializedSettings, null); DrawWarnings(ref serializedSettings, null); if (settingsSerialized != null && serializedSettings != null) { EditorGUILayout.Space(); Inspector.Draw(serializedSettings, null); serializedSettings.serializedObject?.ApplyModifiedProperties(); } }
public void DoGUI(string searchContext) { if (HDRenderPipeline.currentPipeline == null) { EditorGUILayout.HelpBox("No HDRP pipeline currently active (see Quality Settings active level).", MessageType.Warning); } if ((serializedSettings == null) || (settingsSerialized != HDRenderPipelineGlobalSettings.instance)) { settingsSerialized = HDRenderPipelineGlobalSettings.Ensure(); var serializedObject = new SerializedObject(settingsSerialized); serializedSettings = new SerializedHDRenderPipelineGlobalSettings(serializedObject); } else { serializedSettings.serializedObject.Update(); } Draw_AssetSelection(ref serializedSettings, null); if (settingsSerialized != null && serializedSettings != null) { EditorGUILayout.Space(); Inspector.Draw(serializedSettings, null); } serializedSettings.serializedObject.ApplyModifiedProperties(); }
void DrawAssetSelection(ref SerializedHDRenderPipelineGlobalSettings serialized, Editor owner) { var oldWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = Styles.labelWidth; using (new EditorGUILayout.HorizontalScope()) { EditorGUI.BeginChangeCheck(); var newAsset = (HDRenderPipelineGlobalSettings)EditorGUILayout.ObjectField(settingsSerialized, typeof(HDRenderPipelineGlobalSettings), false); if (EditorGUI.EndChangeCheck()) { HDRenderPipelineGlobalSettings.UpdateGraphicsSettings(newAsset); Debug.Assert(newAsset == HDRenderPipelineGlobalSettings.instance); if (settingsSerialized != null && !settingsSerialized.Equals(null)) { EditorUtility.SetDirty(settingsSerialized); } } if (GUILayout.Button(Styles.newAssetButtonLabel, GUILayout.Width(45), GUILayout.Height(18))) { HDAssetFactory.HDRenderPipelineGlobalSettingsCreator.Create(useProjectSettingsFolder: true, assignToActiveAsset: true); } bool guiEnabled = GUI.enabled; GUI.enabled = guiEnabled && (settingsSerialized != null); if (GUILayout.Button(Styles.cloneAssetButtonLabel, GUILayout.Width(45), GUILayout.Height(18))) { HDAssetFactory.HDRenderPipelineGlobalSettingsCreator.Clone(settingsSerialized, assignToActiveAsset: true); } GUI.enabled = guiEnabled; } EditorGUIUtility.labelWidth = oldWidth; EditorGUILayout.Space(); }
void Draw_AssetSelection(ref SerializedHDRenderPipelineGlobalSettings serialized, Editor owner) { var oldWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = Styles.labelWidth; if (settingsSerialized == null) { EditorGUILayout.HelpBox("No active settings for HDRP. Rendering may be broken until a new one is assigned.", MessageType.Warning); } using (new EditorGUILayout.HorizontalScope()) { EditorGUI.BeginChangeCheck(); var newAsset = (HDRenderPipelineGlobalSettings)EditorGUILayout.ObjectField(settingsSerialized, typeof(HDRenderPipelineGlobalSettings), false); if (EditorGUI.EndChangeCheck()) { HDRenderPipelineGlobalSettings.UpdateGraphicsSettings(newAsset); EditorUtility.SetDirty(settingsSerialized); } if (GUILayout.Button(EditorGUIUtility.TrTextContent("New", "Create a HD Global Settings Asset in your default resource folder (defined in Wizard)"), GUILayout.Width(45), GUILayout.Height(18))) { HDAssetFactory.HDRenderPipelineGlobalSettingsCreator.Create(useProjectSettingsFolder: true, activateAsset: true); } bool guiEnabled = GUI.enabled; GUI.enabled = guiEnabled && (settingsSerialized != null); if (GUILayout.Button(EditorGUIUtility.TrTextContent("Clone", "Clone a HD Global Settings Asset in your default resource folder (defined in Wizard)"), GUILayout.Width(45), GUILayout.Height(18))) { HDAssetFactory.HDRenderPipelineGlobalSettingsCreator.Clone(settingsSerialized, activateAsset: true); } GUI.enabled = guiEnabled; } EditorGUIUtility.labelWidth = oldWidth; EditorGUILayout.Space(); }
public static void BuilRaytracingComputeList() { if (s_ComputeShaderCache != null) { s_ComputeShaderCache.Clear(); } else { s_ComputeShaderCache = new Dictionary <int, ComputeShader>(); } if (HDRenderPipelineGlobalSettings.Ensure(canCreateNewAsset: false) == null) { return; } if (HDRenderPipelineGlobalSettings.instance.renderPipelineRayTracingResources == null) { return; } foreach (var fieldInfo in HDRenderPipelineGlobalSettings.instance.renderPipelineRayTracingResources.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)) { ComputeShader computeshader; computeshader = fieldInfo.GetValue(HDRenderPipelineGlobalSettings.instance.renderPipelineRayTracingResources) as ComputeShader; if (computeshader != null) { s_ComputeShaderCache.Add(computeshader.GetInstanceID(), computeshader); } } }
public void Undo_HDRPActive_UnregisterGlobalSettings() { EnsureHDRPIsActivePipeline(); Undo.IncrementCurrentGroup(); HDRenderPipelineGlobalSettings.UpdateGraphicsSettings(null); Assert.IsNull(HDRenderPipelineGlobalSettings.instance); Undo.PerformUndo(); Assert.AreEqual(initialGlobalSettings, HDRenderPipelineGlobalSettings.instance); }
public override void Action(int instanceId, string pathName, string resourceFile) { var newAsset = HDRenderPipelineGlobalSettings.Create(pathName, settings); if (updateGraphicsSettings) { HDRenderPipelineGlobalSettings.UpdateGraphicsSettings(newAsset); } ProjectWindowUtil.ShowCreatedAsset(newAsset); }
public void HDRPFrameRendered_EnsureGlobalSettingsIfNullAssigned() { EnsureHDRPIsActivePipeline(); HDRenderPipelineGlobalSettings.UpdateGraphicsSettings(null); Assert.IsNull(HDRenderPipelineGlobalSettings.instance); Camera.main.Render(); Assert.IsNotNull(HDRenderPipelineGlobalSettings.instance); }
public static void Clone(HDRenderPipelineGlobalSettings src, bool assignToActiveAsset) { settings = src; updateGraphicsSettings = assignToActiveAsset; var assetCreator = ScriptableObject.CreateInstance <HDRenderPipelineGlobalSettingsCreator>(); string path = $"Assets/{HDProjectSettings.projectSettingsFolderPath}/{src.name}.asset"; CoreUtils.EnsureFolderTreeInAssetFilePath(path); ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, path, CoreEditorStyles.globalSettingsIcon, null); }
void ShowMessageWithFixButton(string helpBoxLabel, MessageType type) { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.HelpBox(helpBoxLabel, type); if (GUILayout.Button(Styles.fixAssetButtonLabel, GUILayout.Width(45))) { HDRenderPipelineGlobalSettings.Ensure(); } } }
public static void Create(bool useProjectSettingsFolder, bool assignToActiveAsset) { settings = null; updateGraphicsSettings = assignToActiveAsset; var path = "HDRenderPipelineGlobalSettings.asset"; if (useProjectSettingsFolder) { path = $"Assets/{HDProjectSettings.projectSettingsFolderPath}/HDRenderPipelineGlobalSettings.asset"; CoreUtils.EnsureFolderTreeInAssetFilePath(path); } ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance <HDRenderPipelineGlobalSettingsCreator>(), path, CoreEditorStyles.globalSettingsIcon, null); }
void EnsureHDRPIsActivePipeline() { Camera.main.Render(); // Skip test if project is not configured to be SRP project if (RenderPipelineManager.currentPipeline == null) { Assert.Ignore("Test project has no SRP configured, skipping test"); } initialGlobalSettings = HDRenderPipelineGlobalSettings.instance; Assert.IsInstanceOf <HDRenderPipeline>(RenderPipelineManager.currentPipeline); Assert.IsNotNull(initialGlobalSettings); }
public static void Clone(HDRenderPipelineGlobalSettings src, bool activateAsset) { settings = src; updateGraphicsSettings = activateAsset; var assetCreator = ScriptableObject.CreateInstance <HDRenderPipelineGlobalSettingsCreator>(); if (!AssetDatabase.IsValidFolder("Assets/" + HDProjectSettings.projectSettingsFolderPath)) { AssetDatabase.CreateFolder("Assets", HDProjectSettings.projectSettingsFolderPath); } var path = "Assets/" + HDProjectSettings.projectSettingsFolderPath + "/" + src.name + ".asset"; ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, path, CoreEditorStyles.globalSettingsIcon, null); }
static internal void Drawer_SectionLightingSettings(SerializedFrameSettings serialized, Editor owner, bool withOverride) { bool isGUIenabled = GUI.enabled; FrameSettings? defaultFrameSettings = GetDefaultFrameSettingsFor(owner); var hdrpAsset = GetHDRPAssetFor(owner); RenderPipelineSettings qualityLevelSettings = hdrpAsset?.currentPlatformRenderPipelineSettings ?? default; var area = OverridableFrameSettingsArea.GetGroupContent(1, defaultFrameSettings, serialized); area.AmmendInfo(FrameSettingsField.Volumetrics, ignoreDependencies: true); area.AmmendInfo(FrameSettingsField.ReprojectionForVolumetrics, ignoreDependencies: true); area.AmmendInfo(FrameSettingsField.TransparentSSR, ignoreDependencies: true); //TODO: Remove hideUI when out of experimental. I don't like hideUI it make things more difficult to add a FrameSettings at a given position. // This should not be used except for experimental stuff (it is not compliant with the remaining of UX flows anyway) area.AmmendInfo(FrameSettingsField.ProbeVolume, hideInUI: !HDRenderPipelineGlobalSettings.Ensure().supportProbeVolumes); area.AmmendInfo(FrameSettingsField.NormalizeReflectionProbeWithProbeVolume, hideInUI: !HDRenderPipelineGlobalSettings.Ensure().supportProbeVolumes); area.AmmendInfo( FrameSettingsField.SssQualityMode, overridedDefaultValue: SssQualityMode.FromQualitySettings, customGetter: () => serialized.sssQualityMode.GetEnumValue <SssQualityMode>(), customSetter: v => serialized.sssQualityMode.SetEnumValue((SssQualityMode)v), overrideable: () => serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false, ignoreDependencies: true, hasMixedValues: serialized.sssQualityMode.hasMultipleDifferentValues ); area.AmmendInfo(FrameSettingsField.SssQualityLevel, overridedDefaultValue: ScalableLevel3ForFrameSettingsUIOnly.Low, customGetter: () => (ScalableLevel3ForFrameSettingsUIOnly)serialized.sssQualityLevel.intValue, // 3 levels customSetter: v => serialized.sssQualityLevel.intValue = Math.Max(0, Math.Min((int)v, 2)), // Levels 0-2 overrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && (serialized.sssQualityMode.GetEnumValue <SssQualityMode>() == SssQualityMode.FromQualitySettings), ignoreDependencies: true, hasMixedValues: serialized.sssQualityLevel.hasMultipleDifferentValues ); area.AmmendInfo(FrameSettingsField.SssCustomSampleBudget, overridedDefaultValue: (int)DefaultSssSampleBudgetForQualityLevel.Low, customGetter: () => serialized.sssCustomSampleBudget.intValue, customSetter: v => serialized.sssCustomSampleBudget.intValue = Math.Max(1, Math.Min((int)v, (int)DefaultSssSampleBudgetForQualityLevel.Max)), overrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && (serialized.sssQualityMode.GetEnumValue <SssQualityMode>() != SssQualityMode.FromQualitySettings), ignoreDependencies: true, hasMixedValues: serialized.sssCustomSampleBudget.hasMultipleDifferentValues ); area.Draw(withOverride); GUI.enabled = isGUIenabled; }
static internal void Drawer_SectionLightingSettings(SerializedFrameSettings serialized, Editor owner, bool withOverride) { bool isGUIenabled = GUI.enabled; FrameSettings? defaultFrameSettings = GetDefaultFrameSettingsFor(owner); var hdrpAsset = GetHDRPAssetFor(owner); RenderPipelineSettings qualityLevelSettings = hdrpAsset?.currentPlatformRenderPipelineSettings ?? default; var area = OverridableFrameSettingsArea.GetGroupContent(1, defaultFrameSettings, serialized); area.AmmendInfo(FrameSettingsField.Volumetrics, ignoreDependencies: true); area.AmmendInfo(FrameSettingsField.ReprojectionForVolumetrics, ignoreDependencies: true); area.AmmendInfo(FrameSettingsField.TransparentSSR, ignoreDependencies: true); area.AmmendInfo(FrameSettingsField.ProbeVolume, hideInUI: !HDRenderPipelineGlobalSettings.Ensure().supportProbeVolumes); area.AmmendInfo( FrameSettingsField.SssQualityMode, overridedDefaultValue: SssQualityMode.FromQualitySettings, customGetter: () => serialized.sssQualityMode.GetEnumValue <SssQualityMode>(), customSetter: v => serialized.sssQualityMode.SetEnumValue((SssQualityMode)v), overrideable: () => serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false, ignoreDependencies: true, hasMixedValues: serialized.sssQualityMode.hasMultipleDifferentValues ); area.AmmendInfo(FrameSettingsField.SssQualityLevel, overridedDefaultValue: ScalableLevel3ForFrameSettingsUIOnly.Low, customGetter: () => (ScalableLevel3ForFrameSettingsUIOnly)serialized.sssQualityLevel.intValue, // 3 levels customSetter: v => serialized.sssQualityLevel.intValue = Math.Max(0, Math.Min((int)v, 2)), // Levels 0-2 overrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && (serialized.sssQualityMode.GetEnumValue <SssQualityMode>() == SssQualityMode.FromQualitySettings), ignoreDependencies: true, hasMixedValues: serialized.sssQualityLevel.hasMultipleDifferentValues ); area.AmmendInfo(FrameSettingsField.SssCustomSampleBudget, overridedDefaultValue: (int)DefaultSssSampleBudgetForQualityLevel.Low, customGetter: () => serialized.sssCustomSampleBudget.intValue, customSetter: v => serialized.sssCustomSampleBudget.intValue = Math.Max(1, Math.Min((int)v, (int)DefaultSssSampleBudgetForQualityLevel.Max)), overrideable: () => (serialized.IsEnabled(FrameSettingsField.SubsurfaceScattering) ?? false) && (serialized.sssQualityMode.GetEnumValue <SssQualityMode>() != SssQualityMode.FromQualitySettings), ignoreDependencies: true, hasMixedValues: serialized.sssCustomSampleBudget.hasMultipleDifferentValues ); area.Draw(withOverride); GUI.enabled = isGUIenabled; }
protected override bool DoShadersStripper(HDRenderPipelineAsset hdrpAsset, Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData) { var globalSettings = HDRenderPipelineGlobalSettings.Ensure(); // If ray tracing is disabled, strip all ray tracing shaders if (hdrpAsset.currentPlatformRenderPipelineSettings.supportRayTracing == false) { // If transparent we don't need the depth only pass if (snippet.passName == "IndirectDXR" || snippet.passName == "ForwardDXR" || snippet.passName == "VisibilityDXR" || snippet.passName == "PathTracingDXR" || snippet.passName == "GBufferDXR" || snippet.passName == "SubSurfaceDXR" || snippet.passName == "DebugDXR") { return(true); } } else { // If we only support Performance mode, we do not want the indirectDXR shader if (hdrpAsset.currentPlatformRenderPipelineSettings.supportedRayTracingMode == RenderPipelineSettings.SupportedRayTracingMode.Performance && snippet.passName == "IndirectDXR") { return(true); } // If we only support Quality mode, we do not want the indirectDXR shader if (hdrpAsset.currentPlatformRenderPipelineSettings.supportedRayTracingMode == RenderPipelineSettings.SupportedRayTracingMode.Quality && snippet.passName == "GBufferDXR") { return(true); } // If requested by the render pipeline settings, or if we are in a release build // don't compile the DXR debug pass bool isDebugDXR = snippet.passName == "DebugDXR"; if (isDebugDXR && (!Debug.isDebugBuild || !globalSettings.supportRuntimeDebugDisplay)) { return(true); } } return(false); }
public static void Create(bool useProjectSettingsFolder, bool activateAsset) { settings = null; updateGraphicsSettings = activateAsset; var path = "HDRenderPipelineGlobalSettings.asset"; if (useProjectSettingsFolder) { if (!AssetDatabase.IsValidFolder("Assets/" + HDProjectSettings.projectSettingsFolderPath)) { AssetDatabase.CreateFolder("Assets", HDProjectSettings.projectSettingsFolderPath); } path = "Assets/" + HDProjectSettings.projectSettingsFolderPath + "/HDRenderPipelineGlobalSettings.asset"; } ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, ScriptableObject.CreateInstance <HDRenderPipelineGlobalSettingsCreator>(), path, CoreEditorStyles.globalSettingsIcon, null); }
public static void CreateAndAssign(Kind kind, HDRenderPipelineGlobalSettings globalSettings) { settings = globalSettings; if (settings == null) { Debug.LogError("Trying to create a Volume Profile for a null HDRP Global Settings. Operation aborted."); return; } var assetCreator = ScriptableObject.CreateInstance <VolumeProfileCreator>(); assetCreator.SetKind(kind); if (!AssetDatabase.IsValidFolder("Assets/" + HDProjectSettings.projectSettingsFolderPath)) { AssetDatabase.CreateFolder("Assets", HDProjectSettings.projectSettingsFolderPath); } ProjectWindowUtil.StartNameEditingIfProjectWindowExists(assetCreator.GetInstanceID(), assetCreator, $"Assets/{HDProjectSettings.projectSettingsFolderPath}/{globalSettings.name}_{GetDefaultName(kind)}.asset", null, null); }
void FixHdrpGlobalSettingsUsed(bool fromAsync) => HDRenderPipelineGlobalSettings.Ensure(folderPath: HDProjectSettings.projectSettingsFolderPath);
public void OnProcessComputeShader(ComputeShader shader, string kernelName, IList <ShaderCompilerData> inputData) { if (HDRenderPipeline.currentAsset == null) { return; } if (HDRenderPipelineGlobalSettings.Ensure(canCreateNewAsset: false) == null) { return; } // Discard any compute shader use for raytracing if none of the RP asset required it ComputeShader unused; if (!ShaderBuildPreprocessor.playerNeedRaytracing && ShaderBuildPreprocessor.computeShaderCache.TryGetValue(shader.GetInstanceID(), out unused)) { return; } using (new ExportComputeShaderStrip("Temp/compute-shader-strip.json", shader, kernelName, inputData, this)) { var inputShaderVariantCount = inputData.Count; var hdPipelineAssets = ShaderBuildPreprocessor.hdrpAssets; if (hdPipelineAssets.Count == 0) { return; } uint preStrippingCount = (uint)inputData.Count; double stripTimeMs = 0; using (TimedScope.FromRef(ref stripTimeMs)) { for (int i = 0; i < inputShaderVariantCount;) { ShaderCompilerData input = inputData[i]; bool removeInput = true; foreach (var hdAsset in hdPipelineAssets) { if (!StripShader(hdAsset, shader, kernelName, input)) { removeInput = false; break; } } if (removeInput) { inputData[i] = inputData[--inputShaderVariantCount]; } else { ++i; } } if (inputData is List <ShaderCompilerData> inputDataList) { inputDataList.RemoveRange(inputShaderVariantCount, inputDataList.Count - inputShaderVariantCount); } else { for (int i = inputData.Count - 1; i >= inputShaderVariantCount; --i) { inputData.RemoveAt(i); } } } LogShaderVariants(shader, kernelName, preStrippingCount, (uint)inputData.Count, stripTimeMs); } }
public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList <ShaderCompilerData> inputData) { if (HDRenderPipeline.currentAsset == null) { return; } if (HDRenderPipelineGlobalSettings.Ensure(canCreateNewAsset: false) == null) { return; } var exportLog = ShaderBuildPreprocessor.hdrpAssets.Count > 0 && (HDRenderPipelineGlobalSettings.instance.shaderVariantLogLevel != ShaderVariantLogLevel.Disabled); Stopwatch shaderStripingWatch = new Stopwatch(); shaderStripingWatch.Start(); using (new ExportShaderStrip(exportLog, "Temp/shader-strip.json", shader, snippet, inputData, this)) { // TODO: Grab correct configuration/quality asset. var hdPipelineAssets = ShaderBuildPreprocessor.hdrpAssets; if (hdPipelineAssets.Count == 0) { return; } uint preStrippingCount = (uint)inputData.Count; // Test if striping is enabled in any of the found HDRP assets. if (hdPipelineAssets.Count == 0 || !hdPipelineAssets.Any(a => a.allowShaderVariantStripping)) { return; } var inputShaderVariantCount = inputData.Count; for (int i = 0; i < inputShaderVariantCount;) { ShaderCompilerData input = inputData[i]; // Remove the input by default, until we find a HDRP Asset in the list that needs it. bool removeInput = true; foreach (var hdAsset in hdPipelineAssets) { var strippedByPreprocessor = false; // Call list of strippers // Note that all strippers cumulate each other, so be aware of any conflict here foreach (BaseShaderPreprocessor shaderPreprocessor in shaderProcessorsList) { if (shaderPreprocessor.ShadersStripper(hdAsset, shader, snippet, input)) { strippedByPreprocessor = true; break; } } if (!strippedByPreprocessor) { removeInput = false; break; } } if (removeInput) { inputData[i] = inputData[--inputShaderVariantCount]; } else { ++i; } } if (inputData is List <ShaderCompilerData> inputDataList) { inputDataList.RemoveRange(inputShaderVariantCount, inputDataList.Count - inputShaderVariantCount); } else { for (int i = inputData.Count - 1; i >= inputShaderVariantCount; --i) { inputData.RemoveAt(i); } } if (HDRenderPipelineGlobalSettings.instance.shaderVariantLogLevel != ShaderVariantLogLevel.Disabled) { foreach (var hdAsset in hdPipelineAssets) { m_TotalVariantsInputCount += preStrippingCount; m_TotalVariantsOutputCount += (uint)inputData.Count; LogShaderVariants(shader, snippet, HDRenderPipelineGlobalSettings.instance.shaderVariantLogLevel, preStrippingCount, (uint)inputData.Count); } } } shaderStripingWatch.Stop(); shaderPreprocessed?.Invoke(shader, snippet, inputData.Count, shaderStripingWatch.Elapsed.TotalMilliseconds); }
public void OnProcessComputeShader(ComputeShader shader, string kernelName, IList <ShaderCompilerData> inputData) { if (HDRenderPipeline.currentAsset == null) { return; } if (HDRenderPipelineGlobalSettings.Ensure(canCreateNewAsset: false) == null) { return; } // Discard any compute shader use for raytracing if none of the RP asset required it ComputeShader unused; if (!ShaderBuildPreprocessor.playerNeedRaytracing && ShaderBuildPreprocessor.computeShaderCache.TryGetValue(shader.GetInstanceID(), out unused)) { return; } var exportLog = ShaderBuildPreprocessor.hdrpAssets.Count > 0 && (HDRenderPipelineGlobalSettings.instance.shaderVariantLogLevel != ShaderVariantLogLevel.Disabled); Stopwatch shaderStripingWatch = new Stopwatch(); shaderStripingWatch.Start(); using (new ExportComputeShaderStrip(exportLog, "Temp/compute-shader-strip.json", shader, kernelName, inputData, this)) { var inputShaderVariantCount = inputData.Count; var hdPipelineAssets = ShaderBuildPreprocessor.hdrpAssets; if (hdPipelineAssets.Count == 0) { return; } uint preStrippingCount = (uint)inputData.Count; for (int i = 0; i < inputShaderVariantCount;) { ShaderCompilerData input = inputData[i]; bool removeInput = true; foreach (var hdAsset in hdPipelineAssets) { if (!StripShader(hdAsset, shader, kernelName, input)) { removeInput = false; break; } } if (removeInput) { inputData[i] = inputData[--inputShaderVariantCount]; } else { ++i; } } if (inputData is List <ShaderCompilerData> inputDataList) { inputDataList.RemoveRange(inputShaderVariantCount, inputDataList.Count - inputShaderVariantCount); } else { for (int i = inputData.Count - 1; i >= inputShaderVariantCount; --i) { inputData.RemoveAt(i); } } if (HDRenderPipelineGlobalSettings.instance.shaderVariantLogLevel != ShaderVariantLogLevel.Disabled) { foreach (var hdAsset in hdPipelineAssets) { m_TotalVariantsInputCount += preStrippingCount; m_TotalVariantsOutputCount += (uint)inputData.Count; LogShaderVariants(shader, kernelName, HDRenderPipelineGlobalSettings.instance.shaderVariantLogLevel, preStrippingCount, (uint)inputData.Count); } } } }
protected override bool DoShadersStripper(HDRenderPipelineAsset hdrpAsset, Shader shader, ShaderSnippetData snippet, ShaderCompilerData inputData) { // CAUTION: Pass Name and Lightmode name must match in master node and .shader. // HDRP use LightMode to do drawRenderer and pass name is use here for stripping! var globalSettings = HDRenderPipelineGlobalSettings.Ensure(); // Remove editor only pass bool isSceneSelectionPass = snippet.passName == "SceneSelectionPass"; bool isScenePickingPass = snippet.passName == "ScenePickingPass"; bool metaPassUnused = (snippet.passName == "META") && (SupportedRenderingFeatures.active.enlighten == false || ((int)SupportedRenderingFeatures.active.lightmapBakeTypes | (int)LightmapBakeType.Realtime) == 0); bool editorVisualization = inputData.shaderKeywordSet.IsEnabled(m_EditorVisualization); if (isSceneSelectionPass || isScenePickingPass || metaPassUnused || editorVisualization) { return(true); } // CAUTION: We can't identify transparent material in the stripped in a general way. // Shader Graph don't produce any keyword - However it will only generate the pass that are required, so it already handle transparent (Note that shader Graph still define _SURFACE_TYPE_TRANSPARENT but as a #define) // For inspector version of shader, we identify transparent with a shader feature _SURFACE_TYPE_TRANSPARENT. // Only our Lit (and inherited) shader use _SURFACE_TYPE_TRANSPARENT, so the specific stripping based on this keyword is in LitShadePreprocessor. // Here we can't strip based on opaque or transparent but we will strip based on HDRP Asset configuration. bool isMotionPass = snippet.passName == "MotionVectors"; if (isMotionPass && !hdrpAsset.currentPlatformRenderPipelineSettings.supportMotionVectors) { return(true); } bool isDistortionPass = snippet.passName == "DistortionVectors"; if (isDistortionPass && !hdrpAsset.currentPlatformRenderPipelineSettings.supportDistortion) { return(true); } bool isTransparentBackface = snippet.passName == "TransparentBackface"; if (isTransparentBackface && !hdrpAsset.currentPlatformRenderPipelineSettings.supportTransparentBackface) { return(true); } bool isTransparentPrepass = snippet.passName == "TransparentDepthPrepass"; if (isTransparentPrepass && !hdrpAsset.currentPlatformRenderPipelineSettings.supportTransparentDepthPrepass) { return(true); } bool isTransparentPostpass = snippet.passName == "TransparentDepthPostpass"; if (isTransparentPostpass && !hdrpAsset.currentPlatformRenderPipelineSettings.supportTransparentDepthPostpass) { return(true); } bool isRayTracingPrepass = snippet.passName == "RayTracingPrepass"; if (isRayTracingPrepass && !hdrpAsset.currentPlatformRenderPipelineSettings.supportRayTracing) { return(true); } // If requested by the render pipeline settings, or if we are in a release build, // don't compile fullscreen debug display variant bool isFullScreenDebugPass = snippet.passName == "FullScreenDebug"; if (isFullScreenDebugPass && (!Debug.isDebugBuild || !globalSettings.supportRuntimeDebugDisplay)) { return(true); } // Debug Display shader is currently the longest shader to compile, so we allow users to disable it at runtime. // We also don't want it in release build. // However our AOV API rely on several debug display shader. In case AOV API is requested at runtime (like for the Graphics Compositor) // we allow user to make explicit request for it and it bypass other request if (!hdrpAsset.currentPlatformRenderPipelineSettings.supportRuntimeAOVAPI) { if ((!Debug.isDebugBuild || !globalSettings.supportRuntimeDebugDisplay) && inputData.shaderKeywordSet.IsEnabled(m_DebugDisplay)) { return(true); } } if (inputData.shaderKeywordSet.IsEnabled(m_LodFadeCrossFade) && !hdrpAsset.currentPlatformRenderPipelineSettings.supportDitheringCrossFade) { return(true); } if (inputData.shaderKeywordSet.IsEnabled(m_WriteMSAADepth) && (hdrpAsset.currentPlatformRenderPipelineSettings.supportedLitShaderMode == RenderPipelineSettings.SupportedLitShaderMode.DeferredOnly)) { return(true); } // Note that this is only going to affect the deferred shader and for a debug case, so it won't save much. if (inputData.shaderKeywordSet.IsEnabled(m_SubsurfaceScattering) && !hdrpAsset.currentPlatformRenderPipelineSettings.supportSubsurfaceScattering) { return(true); } if (inputData.shaderKeywordSet.IsEnabled(m_Transparent)) { // If transparent we don't need the depth only pass bool isDepthOnlyPass = snippet.passName == "DepthForwardOnly"; if (isDepthOnlyPass) { return(true); } // If transparent we don't need the motion vector pass if (isMotionPass) { return(true); } // If we are transparent we use cluster lighting and not tile lighting if (inputData.shaderKeywordSet.IsEnabled(m_TileLighting)) { return(true); } } else // Opaque { // If opaque, we never need transparent specific passes (even in forward only mode) bool isTransparentForwardPass = isTransparentPostpass || isTransparentBackface || isTransparentPrepass || isDistortionPass; if (isTransparentForwardPass) { return(true); } // TODO: Should we remove Cluster version if we know MSAA is disabled ? This prevent to manipulate LightLoop Settings (useFPTL option) // For now comment following code // if (inputData.shaderKeywordSet.IsEnabled(m_ClusterLighting) && !hdrpAsset.currentPlatformRenderPipelineSettings.supportMSAA) // return true; } // SHADOW // Strip every useless shadow configs var shadowInitParams = hdrpAsset.currentPlatformRenderPipelineSettings.hdShadowInitParams; foreach (var shadowVariant in m_ShadowKeywords.ShadowVariants) { if (shadowVariant.Key != shadowInitParams.shadowFilteringQuality) { if (inputData.shaderKeywordSet.IsEnabled(shadowVariant.Value)) { return(true); } } } // Screen space shadow variant is exclusive, either we have a variant with dynamic if that support screen space shadow or not // either we have a variant that don't support at all. We can't have both at the same time. if (inputData.shaderKeywordSet.IsEnabled(m_ScreenSpaceShadowOFFKeywords) && shadowInitParams.supportScreenSpaceShadows) { return(true); } if (inputData.shaderKeywordSet.IsEnabled(m_ScreenSpaceShadowONKeywords) && !shadowInitParams.supportScreenSpaceShadows) { return(true); } // DECAL // Strip the decal prepass variant when decals are disabled if (inputData.shaderKeywordSet.IsEnabled(m_WriteDecalBuffer) && !(hdrpAsset.currentPlatformRenderPipelineSettings.supportDecals && hdrpAsset.currentPlatformRenderPipelineSettings.supportDecalLayers)) { return(true); } // If decal support, remove unused variant if (hdrpAsset.currentPlatformRenderPipelineSettings.supportDecals) { // Remove the no decal case if (inputData.shaderKeywordSet.IsEnabled(m_DecalsOFF)) { return(true); } // If decal but with 4RT remove 3RT variant and vice versa for both Material and Decal Material if (inputData.shaderKeywordSet.IsEnabled(m_Decals3RT) && hdrpAsset.currentPlatformRenderPipelineSettings.decalSettings.perChannelMask) { return(true); } if (inputData.shaderKeywordSet.IsEnabled(m_Decals4RT) && !hdrpAsset.currentPlatformRenderPipelineSettings.decalSettings.perChannelMask) { return(true); } // Remove the surface gradient blending if not enabled if (inputData.shaderKeywordSet.IsEnabled(m_DecalSurfaceGradient) && !hdrpAsset.currentPlatformRenderPipelineSettings.supportSurfaceGradient) { return(true); } } else { // Strip if it is a decal pass bool isDBufferMesh = snippet.passName == "DBufferMesh"; bool isDecalMeshForwardEmissive = snippet.passName == "DecalMeshForwardEmissive"; bool isDBufferProjector = snippet.passName == "DBufferProjector"; bool isDecalProjectorForwardEmissive = snippet.passName == "DecalProjectorForwardEmissive"; if (isDBufferMesh || isDecalMeshForwardEmissive || isDBufferProjector || isDecalProjectorForwardEmissive) { return(true); } // If no decal support, remove decal variant if (inputData.shaderKeywordSet.IsEnabled(m_Decals3RT) || inputData.shaderKeywordSet.IsEnabled(m_Decals4RT)) { return(true); } // Remove the surface gradient blending if (inputData.shaderKeywordSet.IsEnabled(m_DecalSurfaceGradient)) { return(true); } } // Global Illumination if (inputData.shaderKeywordSet.IsEnabled(m_ProbeVolumesL1) && (!hdrpAsset.currentPlatformRenderPipelineSettings.supportProbeVolume || !globalSettings.supportProbeVolumes || hdrpAsset.currentPlatformRenderPipelineSettings.probeVolumeSHBands != ProbeVolumeSHBands.SphericalHarmonicsL1)) { return(true); } if (inputData.shaderKeywordSet.IsEnabled(m_ProbeVolumesL2) && (!hdrpAsset.currentPlatformRenderPipelineSettings.supportProbeVolume || !globalSettings.supportProbeVolumes || hdrpAsset.currentPlatformRenderPipelineSettings.probeVolumeSHBands != ProbeVolumeSHBands.SphericalHarmonicsL2)) { return(true); } return(false); }
static void Drawer_VolumeSection(SerializedHDRenderPipelineGlobalSettings serialized, Editor owner) { using (new EditorGUI.IndentLevelScope()) { var oldWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = Styles.labelWidth; HDRenderPipelineGlobalSettings globalSettings = serialized.serializedObject.targetObject as HDRenderPipelineGlobalSettings; VolumeProfile asset = null; using (new EditorGUILayout.HorizontalScope()) { var oldAssetValue = serialized.volumeProfileDefault.objectReferenceValue; EditorGUILayout.PropertyField(serialized.volumeProfileDefault, Styles.defaultVolumeProfileLabel); asset = serialized.volumeProfileDefault.objectReferenceValue as VolumeProfile; if (asset == null && oldAssetValue != null) { Debug.Log("Default Volume Profile Asset cannot be null. Rolling back to previous value."); serialized.volumeProfileDefault.objectReferenceValue = oldAssetValue; } if (GUILayout.Button(EditorGUIUtility.TrTextContent("New", "Create a new Volume Profile for default in your default resource folder (defined in Wizard)"), GUILayout.Width(38), GUILayout.Height(18))) { HDAssetFactory.VolumeProfileCreator.CreateAndAssign(HDAssetFactory.VolumeProfileCreator.Kind.Default, globalSettings); } } if (asset != null) { // The state of the profile can change without the asset reference changing so in this case we need to reset the editor. if (m_CurrentVolumeProfileInstanceID != asset.GetInstanceID() && m_CachedDefaultVolumeProfileEditor != null) { m_CurrentVolumeProfileInstanceID = asset.GetInstanceID(); m_CachedDefaultVolumeProfileEditor = null; } Editor.CreateCachedEditor(asset, Type.GetType("UnityEditor.Rendering.VolumeProfileEditor"), ref m_CachedDefaultVolumeProfileEditor); bool oldEnabled = GUI.enabled; GUI.enabled = AssetDatabase.IsOpenForEdit(asset); m_CachedDefaultVolumeProfileEditor.OnInspectorGUI(); GUI.enabled = oldEnabled; } EditorGUILayout.Space(); VolumeProfile lookDevAsset = null; using (new EditorGUILayout.HorizontalScope()) { var oldAssetValue = serialized.volumeProfileLookDev.objectReferenceValue; EditorGUILayout.PropertyField(serialized.volumeProfileLookDev, Styles.lookDevVolumeProfileLabel); lookDevAsset = serialized.volumeProfileLookDev.objectReferenceValue as VolumeProfile; if (lookDevAsset == null && oldAssetValue != null) { Debug.Log("LookDev Volume Profile Asset cannot be null. Rolling back to previous value."); serialized.volumeProfileLookDev.objectReferenceValue = oldAssetValue; } if (GUILayout.Button(EditorGUIUtility.TrTextContent("New", "Create a new Volume Profile for default in your default resource folder (defined in Wizard)"), GUILayout.Width(38), GUILayout.Height(18))) { HDAssetFactory.VolumeProfileCreator.CreateAndAssign(HDAssetFactory.VolumeProfileCreator.Kind.LookDev, globalSettings); } } if (lookDevAsset != null) { Editor.CreateCachedEditor(lookDevAsset, Type.GetType("UnityEditor.Rendering.VolumeProfileEditor"), ref m_CachedLookDevVolumeProfileEditor); bool oldEnabled = GUI.enabled; GUI.enabled = AssetDatabase.IsOpenForEdit(lookDevAsset); m_CachedLookDevVolumeProfileEditor.OnInspectorGUI(); GUI.enabled = oldEnabled; if (lookDevAsset.Has <VisualEnvironment>()) { EditorGUILayout.HelpBox("VisualEnvironment is not modifiable and will be overridden by the LookDev", MessageType.Warning); } if (lookDevAsset.Has <HDRISky>()) { EditorGUILayout.HelpBox("HDRISky is not modifiable and will be overridden by the LookDev", MessageType.Warning); } } EditorGUIUtility.labelWidth = oldWidth; } }
void FixHdrpGlobalSettingsUsed(bool fromAsync) => HDRenderPipelineGlobalSettings.Ensure();
public void SetUp() { UnityEditor.SceneManagement.EditorSceneManager.NewScene(UnityEditor.SceneManagement.NewSceneSetup.DefaultGameObjects); otherGlobalSettings = ScriptableObject.CreateInstance <HDRenderPipelineGlobalSettings>(); }