Search Unity

Change HDRP settings (Shadows, realtime lights) at runtime

Discussion in 'High Definition Render Pipeline' started by dgoyette, Jan 9, 2020.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I'm trying to add some functionality where major rendering functionality is toggled dynamically at runtime. Two examples of this are rendering shadows, and rendering realtime lighting.

    I've found some working examples of how to override the settings in individual camera to enable or disable shadows, but so far I haven't found a way to turn on/off shadows in HDRP as a whole. I would have imagined it would be something like this:

    Code (CSharp):
    1. var renderPipelineAsset = Instantiate(GraphicsSettings.renderPipelineAsset) as HDRenderPipelineAsset;
    2. var renderPipelineFrameSettings = renderPipelineAsset.GetDefaultFrameSettings(FrameSettingsRenderType.Camera);
    3. renderPipelineFrameSettings.SetEnabled(FrameSettingsField.Shadow, false);
    4. GraphicsSettings.renderPipelineAsset = renderPipelineAsset;
    That just produces an error in UnityEngine.Experimental.Rendering.HDPipeline.FrameSettingsHistory.AggregateFrameSettings.

    Is it possible to turn shadows on/off as a whole, at runtime? Ideally I could do this in order to improve performance by not having shadows running in HDRP at all under certain conditions.


    The other question is whether it's possible to instruct HDRP not to render realtime lighting? There are cases where I only want the baked lighting contribution to be applied, without any realtime lighting being rendered. It's pretty cumbersome to have to find all lights in a scene, and turn then on/off depending on whether I want realtime lights rendering, as it means I need to keep track of whether the light was turned on/off by something else in the process. I was hoping there was just some setting/override to disable realtime lighting entirely runtime.

    Thanks.
     
    brainwipe likes this.
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    I didn't get anywhere trying to change the HDRP settings themselves, but it seems that overriding the settings on each camera is simple enough, and has the same performance characteristics.

    As for turning off realtime lights at runtime, I tried that setting their Light Layer to Nothing, to see if it was similar in performance to actually turning off the light. But it's still much more performant to turn off the light itself. So, unless I find some way to disable realtime lights globally, I'll probably end up going with some process where I manually enable/disable all lights.
     
    Last edited: Jan 9, 2020
    brainwipe and chap-unity like this.
  3. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    ever work this out? i just want to turn on and off effects during runtime
     
  4. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,196
    Yeah. I'm still on HDRP 7, so not sure how different it is in newer versions. But I change all sorts of HDRP settings at runtime based on user options.

    There are two main parameters: a VolumeProfile (which contains all of the post-processing and effects) and the HDAdditionalCameraData from the camera you're using (probably Camera.main), as some settings are applied to the camera itself. Hopefully this gives you a general sense of how you can do this kind of stuff.

    All the references you see to "GraphicsPlayerOptions" in this code is just the class I save all the player's graphics choices into.

    Code (CSharp):
    1.         public void ApplyGraphicsSettings(VolumeProfile sceneSettingsProfile, HDAdditionalCameraData hdCameraData, bool shouldAdjustHDCameraOverrides = true)
    2.         {
    3.             // Used for diagnostics.
    4.             var startTime = DateTime.Now;
    5.  
    6.             // Apply screen resolution change
    7.             if (Screen.currentResolution.height != GraphicsPlayerOptions.ScreenResolutionHeight
    8.                 || Screen.currentResolution.width != GraphicsPlayerOptions.ScreenResolutionWidth
    9.                 || Screen.currentResolution.refreshRate != GraphicsPlayerOptions.ScreenRefreshRate
    10.                 || Screen.fullScreenMode != GraphicsPlayerOptions.FullScreenMode)
    11.             {
    12.                 //Debug.Log($"Changing Screen Resolution to {GraphicsSettings.ScreenResolution.Width} x {GraphicsSettings.ScreenResolution.Height} {(GraphicsPlayerOptions.FullScreen ? "FullScreen" : "Windowed")}");
    13.                 ScreenUtil.SetScreenResolution(GameSettingsDirector.Instance.GraphicsPlayerOptions);
    14.             }
    15.  
    16.  
    17.             // Apply quality change
    18.             if (QualitySettings.GetQualityLevel() != GraphicsPlayerOptions.GraphicsQualityIndex)
    19.             {
    20.                 // Use the lower of the two. This is done in case the quality is set to a very high number
    21.                 // that isn't available on the target system.
    22.                 var qualityIndex = Mathf.Min(GraphicsPlayerOptions.GraphicsQualityIndex, QualitySettings.names.Length - 1);
    23.  
    24.                 //Debug.Log($"Changing quality level to {GraphicsSettings.GraphicsQualityIndex}");
    25.                 QualitySettings.SetQualityLevel(qualityIndex, true);
    26.             }
    27.  
    28.             // V-Sync.
    29.             QualitySettings.vSyncCount = GraphicsPlayerOptions.EnableVSync ? 1 : 0;
    30.  
    31.             // When not using VSync, set target framerate to 60 to avoid inefficient rendering.
    32.             Application.targetFrameRate = GraphicsPlayerOptions.TargetFrameRate == 0 ? -1 : GraphicsPlayerOptions.TargetFrameRate;
    33.  
    34.             if (hdCameraData != null && hdCameraData.gameObject.GetComponent<SupportsCustomFOV>() != null)
    35.             {
    36.                 hdCameraData.gameObject.GetComponent<Camera>().fieldOfView = Mathf.Clamp(GraphicsPlayerOptions.FieldOfView, GraphicsConstants.MinFOV, GraphicsConstants.MaxFOV);
    37.             }
    38.  
    39.             // SRP Batching
    40.             GraphicsSettings.useScriptableRenderPipelineBatching = GraphicsPlayerOptions.EnableSRPBatching;
    41.  
    42.             if (sceneSettingsProfile != null)
    43.             {
    44.                 var ambientOcclusionComponent = sceneSettingsProfile.GetComponent<AmbientOcclusion>();
    45.                 if (ambientOcclusionComponent != null)
    46.                 {
    47.                     //Debug.Log($"Setting Use Ambient Occlusion to {GraphicsSettings.UsePostProcessingAmbientOcclusion}");
    48.                     if (GraphicsPlayerOptions.AmbientOcclusionQuality == LowMediumHighOff.Off)
    49.                     {
    50.                         ambientOcclusionComponent.active = false;
    51.                     }
    52.                     else
    53.                     {
    54.                         ambientOcclusionComponent.active = true;
    55.                         // Accepted values are 0, 1, 2, but our enum's values are 1, 2, 3 respectively.
    56.                         ambientOcclusionComponent.quality.Override((int)GraphicsPlayerOptions.AmbientOcclusionQuality - 1);
    57.                     }
    58.  
    59.                 }
    60.  
    61.                 var bloomComponent = sceneSettingsProfile.GetComponent<Bloom>();
    62.                 if (bloomComponent != null)
    63.                 {
    64.                     //Debug.Log($"Setting Use Ambient Occlusion to {GraphicsSettings.UsePostProcessingAmbientOcclusion}");
    65.                     bloomComponent.active = GraphicsPlayerOptions.EnableBloom;
    66.                 }
    67.  
    68.                 var motionBlurComponent = sceneSettingsProfile.GetComponent<MotionBlur>();
    69.                 if (motionBlurComponent != null)
    70.                 {
    71.                     if (GraphicsPlayerOptions.MotionBlurQuality == LowMediumHighOff.Off)
    72.                     {
    73.                         motionBlurComponent.active = false;
    74.                     }
    75.                     else
    76.                     {
    77.                         motionBlurComponent.active = true;
    78.                         // Accepted values are 0, 1, 2, but our enum's values are 1, 2, 3 respectively.
    79.                         motionBlurComponent.quality.Override((int)GraphicsPlayerOptions.MotionBlurQuality - 1);
    80.                     }
    81.  
    82.                 }
    83.  
    84.                 var tonemappingComponent = sceneSettingsProfile.GetComponent<Tonemapping>();
    85.                 if (tonemappingComponent != null)
    86.                 {
    87.                     tonemappingComponent.active = GraphicsPlayerOptions.EnableTonemappping;
    88.                 }
    89.  
    90.                 var liftGammaGainComponent = sceneSettingsProfile.GetComponent<LiftGammaGain>();
    91.                 if (liftGammaGainComponent != null)
    92.                 {
    93.                     // The gamma value we receive is normalized, where 0 represents darkest and 1 is brightest.
    94.                     // 0.5 represents "normal", or a value of "1" in PPS2. So, we denormalize the value here
    95.                     // to give it a suitable range.
    96.                     //Debug.Log(liftGammaGainComponent.gamma.value);
    97.                     liftGammaGainComponent.gamma.Override(new Vector4(1, 1, 1, DenormalizedGamma(Mathf.Clamp(GraphicsPlayerOptions.NormalizedGamma, 0, 1))));
    98.                 }
    99.  
    100.  
    101.                 SetShadowDistance(sceneSettingsProfile, GraphicsPlayerOptions.ShadowDistance);
    102.  
    103.  
    104.                 //Debug.Log($"AO: {ambientOcclusionComponent.quality.value}; MB: {motionBlurComponent.quality.value}");
    105.             }
    106.             else
    107.             {
    108.                 // This is the case where no settings have been provided, which means we should look in the
    109.                 // scene for volume profiles to adjust settings
    110.                 // foreach (var volumeKeeper in GameObject.FindObjectsOfType<VolumeKeeper>())
    111.                 // {
    112.                 //     var volumeProfile = volumeKeeper.Volume.profile;
    113.                 //
    114.                 //     var exposure = volumeProfile.GetComponent<Exposure>();
    115.                 //     if (exposure != null)
    116.                 //     {
    117.                 //         exposure.mode.Override(GraphicsPlayerOptions.EnableDynamicExposure ? ExposureMode.Automatic : ExposureMode.Fixed);
    118.                 //     }
    119.                 // }
    120.             }
    121.  
    122.  
    123.  
    124.             if (hdCameraData != null && shouldAdjustHDCameraOverrides)
    125.             {
    126.                 if (hdCameraData.antialiasing != GraphicsPlayerOptions.Antialiasing)
    127.                 {
    128.                     //Debug.Log($"Setting Anti-aliasing to to {GraphicsSettings.Antialiasing}");
    129.                     hdCameraData.antialiasing = GraphicsPlayerOptions.Antialiasing;
    130.  
    131.                     // If using SMAA, make sure quality is set to High.
    132.                     if (GraphicsPlayerOptions.Antialiasing == HDAdditionalCameraData.AntialiasingMode.SubpixelMorphologicalAntiAliasing)
    133.                     {
    134.                         hdCameraData.SMAAQuality = HDAdditionalCameraData.SMAAQualityLevel.High;
    135.                     }
    136.                 }
    137.  
    138.  
    139.  
    140.                 // This should probably already be enabled, but just to be safe. This is the "left" checkbox in the
    141.                 // camera settings, which controls whether to consider the override value. This is always true, even
    142.                 // when disable shadows, as it controls whether we're allowed to enable/disable shadows.
    143.                 var frameSettingsOverrideMask = hdCameraData.renderingPathCustomFrameSettingsOverrideMask;
    144.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.ShadowMaps] = true;
    145.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.Distortion] = true;
    146.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.AtmosphericScattering] = true;
    147.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.Volumetrics] = true;
    148.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.LightLayers] = true;
    149.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.ReflectionProbe] = true;
    150.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.SSAO] = true;
    151.                 frameSettingsOverrideMask.mask[(uint)FrameSettingsField.ReplaceDiffuseForIndirect] = true; // See below
    152.  
    153.  
    154.                 // It's in the frame settings that we actually enable or disable the shadows.
    155.                 var frameSettings = hdCameraData.renderingPathCustomFrameSettings;
    156.                 frameSettings.SetEnabled(FrameSettingsField.ShadowMaps, CamerasShouldRenderShadows());
    157.                 frameSettings.SetEnabled(FrameSettingsField.Distortion, GraphicsPlayerOptions.EnableDistortion);
    158.                 // Atmospheric Scatter (Fog) and Volumetrics are controlled by the same option.
    159.                 frameSettings.SetEnabled(FrameSettingsField.AtmosphericScattering, GraphicsPlayerOptions.EnableVolumetrics);
    160.                 frameSettings.SetEnabled(FrameSettingsField.Volumetrics, GraphicsPlayerOptions.EnableVolumetrics);
    161.                 frameSettings.SetEnabled(FrameSettingsField.LightLayers, GraphicsPlayerOptions.EnableLightLayers);
    162.                 frameSettings.SetEnabled(FrameSettingsField.ReflectionProbe, GraphicsPlayerOptions.EnableReflectionProbes);
    163.                 frameSettings.SetEnabled(FrameSettingsField.SSAO, GraphicsPlayerOptions.AmbientOcclusionQuality != LowMediumHighOff.Off);
    164.                 frameSettings.SetEnabled(FrameSettingsField.MotionBlur, GraphicsPlayerOptions.MotionBlurQuality != LowMediumHighOff.Off);
    165.                 // This setting causes metal objects to look less black when reflections are disabled. It looks much better.
    166.                 frameSettings.SetEnabled(FrameSettingsField.ReplaceDiffuseForIndirect, !GraphicsPlayerOptions.EnableReflectionProbes);
    167.  
    168.  
    169.                 // Applying the frame setting mask back to the camera
    170.                 hdCameraData.renderingPathCustomFrameSettingsOverrideMask = frameSettingsOverrideMask;
    171.                 hdCameraData.renderingPathCustomFrameSettings = frameSettings;
    172.  
    173.             }
    174.         }
     
    _geo__ and radiantboy like this.
  5. radiantboy

    radiantboy

    Joined:
    Nov 21, 2012
    Posts:
    1,633
    thank you!! I could turn them on but not change their variables. I needed "Override()" as shown in your code, rather than just setting the variable. AWESOME.
     
    dgoyette likes this.