You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
308 lines
12 KiB
308 lines
12 KiB
using System; |
|
using System.Collections.Generic; |
|
using UnityEngine; |
|
using UnityEngine.Rendering; |
|
using UnityEngine.Rendering.Universal; |
|
using ShadowQuality = UnityEngine.ShadowQuality; |
|
using ShadowResolution = UnityEngine.ShadowResolution; |
|
|
|
namespace UnityEditor.Rendering.Universal.Converters |
|
{ |
|
internal class RenderSettingsConverter : RenderPipelineConverter |
|
{ |
|
public override int priority => -9000; |
|
public override string name => "Rendering Settings"; |
|
|
|
public override string info => |
|
"This converter will look at creating Universal Render Pipeline assets and respective Renderer Assets and configure" + |
|
" their settings based on equivalent settings from builtin renderer."; |
|
|
|
public override Type container => typeof(BuiltInToURPConverterContainer); |
|
|
|
// Used to store settings specific to Graphics Tiers |
|
GraphicsTierSettings m_GraphicsTierSettings; |
|
|
|
// Settings items, currently tracks Quality settings only |
|
List<SettingsItem> m_SettingsItems; |
|
|
|
// List of the rendering modes required |
|
List<RenderingMode> m_RenderingModes; |
|
|
|
const string k_PipelineAssetPath = "Settings"; |
|
|
|
public override void OnInitialize(InitializeConverterContext context, Action callback) |
|
{ |
|
m_SettingsItems = new List<SettingsItem>(); |
|
m_RenderingModes = new List<RenderingMode>(); |
|
|
|
// check graphics tiers |
|
GatherGraphicsTiers(); |
|
|
|
// check quality levels |
|
GatherQualityLevels(ref context); |
|
|
|
callback?.Invoke(); |
|
} |
|
|
|
/// <summary> |
|
/// Grabs the 3rd tier from the Graphics Tier Settings based off the current build platform |
|
/// </summary> |
|
private void GatherGraphicsTiers() |
|
{ |
|
var targetGrp = BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget); |
|
var tier = EditorGraphicsSettings.GetTierSettings(targetGrp, GraphicsTier.Tier3); |
|
|
|
// Add the Graphic Tier Render Path settings as the first rendering mode |
|
m_RenderingModes.Add(GetEquivalentRenderMode(tier.renderingPath)); |
|
|
|
m_GraphicsTierSettings.RenderingPath = tier.renderingPath; |
|
m_GraphicsTierSettings.ReflectionProbeBlending = tier.reflectionProbeBlending; |
|
m_GraphicsTierSettings.ReflectionProbeBoxProjection = tier.reflectionProbeBoxProjection; |
|
m_GraphicsTierSettings.CascadeShadows = tier.cascadedShadowMaps; |
|
m_GraphicsTierSettings.HDR = tier.hdr; |
|
} |
|
|
|
/// <summary> |
|
/// Iterates over all Quality Settings and saves relevant settings to a RenderSettingsItem. |
|
/// This will also create the required information for the Render Pipeline Converter UI. |
|
/// </summary> |
|
/// <param name="context">Converter context to add elements to.</param> |
|
private void GatherQualityLevels(ref InitializeConverterContext context) |
|
{ |
|
var currentQuality = QualitySettings.GetQualityLevel(); |
|
var id = 0; |
|
foreach (var levelName in QualitySettings.names) |
|
{ |
|
QualitySettings.SetQualityLevel(id); |
|
|
|
var projectSettings = new RenderSettingItem |
|
{ |
|
Index = id, |
|
LevelName = levelName, |
|
PixelLightCount = QualitySettings.pixelLightCount, |
|
MSAA = QualitySettings.antiAliasing, |
|
Shadows = QualitySettings.shadows, |
|
ShadowResolution = QualitySettings.shadowResolution, |
|
ShadowDistance = QualitySettings.shadowDistance, |
|
ShadowCascadeCount = QualitySettings.shadowCascades, |
|
CascadeSplit2 = QualitySettings.shadowCascade2Split, |
|
CascadeSplit4 = QualitySettings.shadowCascade4Split, |
|
SoftParticles = QualitySettings.softParticles, |
|
}; |
|
m_SettingsItems.Add(projectSettings); |
|
|
|
var setting = QualitySettings.GetRenderPipelineAssetAt(id); |
|
var item = new ConverterItemDescriptor { name = $"Quality Level {id}: {levelName}" }; |
|
|
|
if (setting != null) |
|
{ |
|
item.warningMessage = setting.GetType() == typeof(UniversalRenderPipelineAsset) |
|
? "Contains URP Asset, will override existing asset." |
|
: "Contains SRP Asset, will override existing asset with URP asset."; |
|
} |
|
|
|
context.AddAssetToConvert(item); |
|
id++; |
|
} |
|
|
|
QualitySettings.SetQualityLevel(currentQuality); |
|
} |
|
|
|
public override void OnRun(ref RunItemContext context) |
|
{ |
|
var item = context.item; |
|
// is quality item |
|
if (m_SettingsItems[item.index].GetType() == typeof(RenderSettingItem)) |
|
{ |
|
GeneratePipelineAsset(m_SettingsItems[item.index] as RenderSettingItem); |
|
} |
|
} |
|
|
|
private void GeneratePipelineAsset(RenderSettingItem settings) |
|
{ |
|
// store current quality level |
|
var currentQualityLevel = QualitySettings.GetQualityLevel(); |
|
|
|
//creating pipeline asset |
|
var asset = |
|
ScriptableObject.CreateInstance(typeof(UniversalRenderPipelineAsset)) as UniversalRenderPipelineAsset; |
|
if (!AssetDatabase.IsValidFolder($"Assets/{k_PipelineAssetPath}")) |
|
AssetDatabase.CreateFolder("Assets", k_PipelineAssetPath); |
|
var path = $"Assets/{k_PipelineAssetPath}/{settings.LevelName}_PipelineAsset.asset"; |
|
|
|
// Setting Pipeline Asset settings |
|
SetPipelineSettings(asset, settings); |
|
|
|
// Create Renderers |
|
var defaultIndex = 0; |
|
var renderers = new List<ScriptableRendererData>(); |
|
if (m_RenderingModes.Contains(RenderingMode.Forward)) |
|
{ |
|
renderers.Add(CreateRendererDataAsset(path, RenderingPath.Forward, "ForwardRenderer")); |
|
if (GetEquivalentRenderMode(m_GraphicsTierSettings.RenderingPath) == RenderingMode.Forward) |
|
defaultIndex = m_RenderingModes.IndexOf(RenderingMode.Forward); |
|
} |
|
|
|
if (m_RenderingModes.Contains(RenderingMode.Deferred)) |
|
{ |
|
renderers.Add(CreateRendererDataAsset(path, RenderingPath.DeferredShading, "DeferredRenderer")); |
|
if (GetEquivalentRenderMode(m_GraphicsTierSettings.RenderingPath) == RenderingMode.Deferred) |
|
defaultIndex = m_RenderingModes.IndexOf(RenderingMode.Deferred); |
|
} |
|
|
|
asset.m_RendererDataList = renderers.ToArray(); |
|
asset.m_DefaultRendererIndex = defaultIndex; |
|
|
|
// Create Pipeline asset on disk |
|
AssetDatabase.CreateAsset(asset, path); |
|
// Assign asset |
|
QualitySettings.SetQualityLevel(settings.Index); |
|
QualitySettings.renderPipeline = asset; |
|
|
|
// return to original quality level |
|
QualitySettings.SetQualityLevel(currentQualityLevel); |
|
// Set graphics settings |
|
if (currentQualityLevel == settings.Index || GraphicsSettings.defaultRenderPipeline == null || GraphicsSettings.defaultRenderPipeline.GetType() != |
|
typeof(UniversalRenderPipelineAsset)) |
|
{ |
|
GraphicsSettings.defaultRenderPipeline = asset; |
|
} |
|
} |
|
|
|
private ScriptableRendererData CreateRendererDataAsset(string assetPath, RenderingPath renderingPath, |
|
string fileName) |
|
{ |
|
var rendererAsset = |
|
UniversalRenderPipelineAsset.CreateRendererAsset(assetPath, RendererType.UniversalRenderer, true, fileName) |
|
as UniversalRendererData; |
|
//Missing API to set deferred or forward |
|
rendererAsset.renderingMode = |
|
renderingPath == RenderingPath.Forward ? RenderingMode.Forward : RenderingMode.Deferred; |
|
//missing API to assign to pipeline asset |
|
return rendererAsset; |
|
} |
|
|
|
/// <summary> |
|
/// Sets all relevant RP settings in order they appear in URP |
|
/// </summary> |
|
/// <param name="asset">Pipeline asset to set</param> |
|
/// <param name="settings">The ProjectSettingItem with stored settings</param> |
|
private void SetPipelineSettings(UniversalRenderPipelineAsset asset, RenderSettingItem settings) |
|
{ |
|
// General |
|
asset.supportsCameraDepthTexture = settings.SoftParticles; |
|
|
|
// Quality |
|
asset.supportsHDR = m_GraphicsTierSettings.HDR; |
|
asset.msaaSampleCount = settings.MSAA == 0 ? 1 : settings.MSAA; |
|
|
|
// Main Light |
|
asset.mainLightRenderingMode = settings.PixelLightCount == 0 |
|
? LightRenderingMode.Disabled |
|
: LightRenderingMode.PerPixel; |
|
asset.supportsMainLightShadows = settings.Shadows != ShadowQuality.Disable; |
|
asset.mainLightShadowmapResolution = |
|
GetEquivalentMainlightShadowResolution((int)settings.ShadowResolution); |
|
|
|
// Additional Lights |
|
asset.additionalLightsRenderingMode = settings.PixelLightCount == 0 |
|
? LightRenderingMode.PerVertex |
|
: LightRenderingMode.PerPixel; |
|
asset.maxAdditionalLightsCount = settings.PixelLightCount != 0 ? Mathf.Max(0, settings.PixelLightCount) : 4; |
|
asset.supportsAdditionalLightShadows = settings.Shadows != ShadowQuality.Disable; |
|
asset.additionalLightsShadowmapResolution = |
|
GetEquivalentAdditionalLightAtlasShadowResolution((int)settings.ShadowResolution); |
|
|
|
// Reflection Probes |
|
asset.reflectionProbeBlending = m_GraphicsTierSettings.ReflectionProbeBlending; |
|
asset.reflectionProbeBoxProjection = m_GraphicsTierSettings.ReflectionProbeBoxProjection; |
|
|
|
// Shadows |
|
asset.shadowDistance = settings.ShadowDistance; |
|
asset.shadowCascadeCount = m_GraphicsTierSettings.CascadeShadows ? settings.ShadowCascadeCount : 1; |
|
asset.cascade2Split = settings.CascadeSplit2; |
|
asset.cascade4Split = settings.CascadeSplit4; |
|
asset.supportsSoftShadows = settings.Shadows == ShadowQuality.All; |
|
} |
|
|
|
#region HelperFunctions |
|
|
|
private static int GetEquivalentMainlightShadowResolution(int value) |
|
{ |
|
return GetEquivalentShadowResolution(value); |
|
} |
|
|
|
private static int GetEquivalentAdditionalLightAtlasShadowResolution(int value) |
|
{ |
|
return GetEquivalentShadowResolution(value); |
|
} |
|
|
|
private static int GetEquivalentShadowResolution(int value) |
|
{ |
|
switch (value) |
|
{ |
|
case 0: // low |
|
return 1024; |
|
case 1: // med |
|
return 2048; |
|
case 2: // high |
|
return 4096; |
|
case 3: // very high |
|
return 4096; |
|
default: // backup |
|
return 1024; |
|
} |
|
} |
|
|
|
private RenderingMode GetEquivalentRenderMode(RenderingPath path) |
|
{ |
|
switch (path) |
|
{ |
|
case RenderingPath.VertexLit: |
|
case RenderingPath.Forward: |
|
return RenderingMode.Forward; |
|
case RenderingPath.DeferredLighting: |
|
case RenderingPath.DeferredShading: |
|
return RenderingMode.Deferred; |
|
default: |
|
return RenderingMode.Forward; |
|
} |
|
} |
|
|
|
#endregion |
|
|
|
#region Data |
|
|
|
private struct GraphicsTierSettings |
|
{ |
|
public bool ReflectionProbeBoxProjection; |
|
public bool ReflectionProbeBlending; |
|
public bool CascadeShadows; |
|
public bool HDR; |
|
public RenderingPath RenderingPath; |
|
} |
|
|
|
private class SettingsItem { } |
|
|
|
private class RenderSettingItem : SettingsItem |
|
{ |
|
// General |
|
public int Index; |
|
|
|
public string LevelName; |
|
|
|
// Settings |
|
public int PixelLightCount; |
|
public int MSAA; |
|
public ShadowQuality Shadows; |
|
public ShadowResolution ShadowResolution; |
|
public float ShadowDistance; |
|
public int ShadowCascadeCount; |
|
public float CascadeSplit2; |
|
public Vector3 CascadeSplit4; |
|
public bool SoftParticles; |
|
} |
|
|
|
#endregion |
|
} |
|
}
|
|
|