261 lines
11 KiB
C#
261 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine.Rendering.LookDev;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
public partial class HDRenderPipeline : IDataProvider
|
|
{
|
|
struct LookDevDataForHDRP
|
|
{
|
|
public HDAdditionalCameraData additionalCameraData;
|
|
public HDAdditionalLightData additionalLightData;
|
|
public VisualEnvironment visualEnvironment;
|
|
public HDRISky sky;
|
|
public Volume volume;
|
|
#if UNITY_EDITOR
|
|
public int currentVolumeProfileHash;
|
|
#endif
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
bool UpdateVolumeProfile(Volume volume, out VisualEnvironment visualEnvironment, out HDRISky sky, ref int volumeProfileHash)
|
|
{
|
|
var lookDevVolumeSettings = GraphicsSettings.GetRenderPipelineSettings<LookDevVolumeProfileSettings>();
|
|
if (lookDevVolumeSettings.volumeProfile == null)
|
|
{
|
|
lookDevVolumeSettings.volumeProfile = VolumeUtils.CopyVolumeProfileFromResourcesToAssets(GraphicsSettings
|
|
.GetRenderPipelineSettings<HDRenderPipelineEditorAssets>().lookDevVolumeProfile);
|
|
}
|
|
|
|
var lookDevVolumeProfile = lookDevVolumeSettings.volumeProfile;
|
|
int newHashCode = lookDevVolumeProfile.GetHashCode();
|
|
if (newHashCode != volumeProfileHash)
|
|
{
|
|
VolumeProfile oldProfile = volume.sharedProfile;
|
|
|
|
volumeProfileHash = newHashCode;
|
|
|
|
VolumeProfile profile = ScriptableObject.Instantiate(lookDevVolumeProfile);
|
|
profile.hideFlags = HideFlags.HideAndDontSave;
|
|
volume.sharedProfile = profile;
|
|
|
|
// Remove potentially existing components in the user profile.
|
|
if (profile.TryGet(out visualEnvironment))
|
|
profile.Remove<VisualEnvironment>();
|
|
|
|
if (profile.TryGet(out sky))
|
|
profile.Remove<HDRISky>();
|
|
|
|
// If there was a profile before we needed to re-instantiate the new profile, we need to copy the data over for sky settings.
|
|
if (oldProfile != null)
|
|
{
|
|
if (oldProfile.TryGet(out HDRISky oldSky))
|
|
{
|
|
sky = Object.Instantiate(oldSky);
|
|
profile.components.Add(sky);
|
|
}
|
|
if (oldProfile.TryGet(out VisualEnvironment oldVisualEnv))
|
|
{
|
|
visualEnvironment = Object.Instantiate(oldVisualEnv);
|
|
profile.components.Add(visualEnvironment);
|
|
}
|
|
|
|
CoreUtils.Destroy(oldProfile);
|
|
}
|
|
else
|
|
{
|
|
visualEnvironment = profile.Add<VisualEnvironment>();
|
|
visualEnvironment.skyType.Override((int)SkyType.HDRI);
|
|
visualEnvironment.skyAmbientMode.Override(SkyAmbientMode.Dynamic);
|
|
sky = profile.Add<HDRISky>();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
visualEnvironment = null;
|
|
sky = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to init the scene when creating the view
|
|
/// </summary>
|
|
/// <param name="SRI">The StageRuntimeInterface allowing to communicate with the LookDev</param>
|
|
void IDataProvider.FirstInitScene(StageRuntimeInterface SRI)
|
|
{
|
|
Camera camera = SRI.camera;
|
|
camera.allowHDR = true;
|
|
|
|
var additionalCameraData = camera.gameObject.AddComponent<HDAdditionalCameraData>();
|
|
additionalCameraData.clearColorMode = HDAdditionalCameraData.ClearColorMode.Color;
|
|
additionalCameraData.clearDepth = true;
|
|
additionalCameraData.backgroundColorHDR = camera.backgroundColor;
|
|
additionalCameraData.volumeAnchorOverride = camera.transform;
|
|
additionalCameraData.volumeLayerMask = 1 << 31; //31 is the culling layer used in LookDev
|
|
|
|
additionalCameraData.customRenderingSettings = true;
|
|
additionalCameraData.renderingPathCustomFrameSettings.SetEnabled(FrameSettingsField.SSR, false);
|
|
// LookDev cameras are enabled/disabled all the time so history is destroyed each frame.
|
|
// In this case we know we want to keep history alive as long as the camera is.
|
|
additionalCameraData.hasPersistentHistory = true;
|
|
|
|
Light light = SRI.sunLight;
|
|
HDAdditionalLightData additionalLightData = light.gameObject.AddComponent<HDAdditionalLightData>();
|
|
#if UNITY_EDITOR
|
|
HDAdditionalLightData.InitDefaultHDAdditionalLightData(additionalLightData);
|
|
#endif
|
|
light.intensity = 0f;
|
|
additionalLightData.SetShadowResolution(2048);
|
|
|
|
GameObject volumeGO = SRI.AddGameObject(persistent: true);
|
|
volumeGO.name = "StageVolume";
|
|
Volume volume = volumeGO.AddComponent<Volume>();
|
|
volume.isGlobal = true;
|
|
volume.priority = float.MaxValue;
|
|
volume.enabled = false;
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
// Make sure we invalidate the current volume when first loading a scene.
|
|
int volumeProfileHash = -1;
|
|
UpdateVolumeProfile(volume, out var visualEnvironment, out var sky, ref volumeProfileHash);
|
|
|
|
SRI.SRPData = new LookDevDataForHDRP()
|
|
{
|
|
additionalCameraData = additionalCameraData,
|
|
additionalLightData = additionalLightData,
|
|
visualEnvironment = visualEnvironment,
|
|
sky = sky,
|
|
volume = volume,
|
|
currentVolumeProfileHash = volumeProfileHash
|
|
};
|
|
#else
|
|
//remove unassigned warnings when building
|
|
SRI.SRPData = new LookDevDataForHDRP()
|
|
{
|
|
additionalCameraData = null,
|
|
additionalLightData = null,
|
|
visualEnvironment = null,
|
|
sky = null,
|
|
volume = null
|
|
};
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to apply the sky as it is requested by the LookDev
|
|
/// </summary>
|
|
/// <param name="camera">The Camera rendering in the LookDev</param>
|
|
/// <param name="sky">The requested Sky to use</param>
|
|
/// <param name="SRI">The StageRuntimeInterface allowing to communicate with the LookDev</param>
|
|
void IDataProvider.UpdateSky(Camera camera, Sky sky, StageRuntimeInterface SRI)
|
|
{
|
|
LookDevDataForHDRP data = (LookDevDataForHDRP)SRI.SRPData;
|
|
if (sky.cubemap == null)
|
|
{
|
|
data.visualEnvironment.skyType.Override((int)0); //Skytype.None do not really exist
|
|
data.additionalCameraData.clearColorMode = HDAdditionalCameraData.ClearColorMode.Color;
|
|
}
|
|
else
|
|
{
|
|
data.visualEnvironment.skyType.Override((int)SkyType.HDRI);
|
|
data.sky.hdriSky.Override(sky.cubemap);
|
|
data.sky.rotation.Override(sky.longitudeOffset);
|
|
data.additionalCameraData.clearColorMode = HDAdditionalCameraData.ClearColorMode.Sky;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to apply some changes before the LookDev's Camera render.
|
|
/// Should mainly be used for view isolation.
|
|
/// </summary>
|
|
/// <param name="SRI">The StageRuntimeInterface allowing to communicate with the LookDev</param>
|
|
void IDataProvider.OnBeginRendering(StageRuntimeInterface SRI)
|
|
{
|
|
LookDevDataForHDRP data = (LookDevDataForHDRP)SRI.SRPData;
|
|
#if UNITY_EDITOR
|
|
int currentHash = data.currentVolumeProfileHash;
|
|
// The default volume can change in the HDRP asset so if it does we need to re-instantiate it.
|
|
if (UpdateVolumeProfile(data.volume, out var visualEnv, out var sky, ref currentHash))
|
|
{
|
|
data.sky = sky;
|
|
data.visualEnvironment = visualEnv;
|
|
data.currentVolumeProfileHash = currentHash;
|
|
SRI.SRPData = data;
|
|
}
|
|
#endif
|
|
data.volume.enabled = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to apply some changes after the LookDev's Camera render.
|
|
/// Should mainly be used for view isolation.
|
|
/// </summary>
|
|
/// <param name="SRI">The StageRuntimeInterface allowing to communicate with the LookDev</param>
|
|
void IDataProvider.OnEndRendering(StageRuntimeInterface SRI)
|
|
{
|
|
LookDevDataForHDRP data = (LookDevDataForHDRP)SRI.SRPData;
|
|
data.volume.enabled = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to give to LookDev what debug mode it can support.
|
|
/// </summary>
|
|
IEnumerable<string> IDataProvider.supportedDebugModes
|
|
=> new[]
|
|
{
|
|
"Albedo",
|
|
"Normal",
|
|
"Smoothness",
|
|
"AmbientOcclusion",
|
|
"Metal",
|
|
"Specular",
|
|
"Alpha"
|
|
};
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to update the debug mode used while requested in the LookDev.
|
|
/// </summary>
|
|
/// <param name="debugIndex">The index corresponding to the debug view, -1 = none, other have same index than iven by IDataProvider.supportedDebugModes</param>
|
|
void IDataProvider.UpdateDebugMode(int debugIndex)
|
|
=> debugDisplaySettings.SetDebugViewCommonMaterialProperty((Attributes.MaterialSharedProperty)(debugIndex + 1));
|
|
|
|
/// <summary>
|
|
/// This hook allows HDRP to provide a shadow mask in order for LookDev to perform a self shadow composition.
|
|
/// </summary>
|
|
/// <param name="output">The created shadow mask</param>
|
|
/// <param name="SRI">The StageRuntimeInterface allowing to communicate with the LookDev</param>
|
|
void IDataProvider.GetShadowMask(ref RenderTexture output, StageRuntimeInterface SRI)
|
|
{
|
|
LookDevDataForHDRP data = (LookDevDataForHDRP)SRI.SRPData;
|
|
Color oldBackgroundColor = data.additionalCameraData.backgroundColorHDR;
|
|
var oldClearMode = data.additionalCameraData.clearColorMode;
|
|
data.additionalCameraData.backgroundColorHDR = Color.white;
|
|
data.additionalCameraData.clearColorMode = HDAdditionalCameraData.ClearColorMode.Color;
|
|
SRI.sunLight.intensity = 1f;
|
|
debugDisplaySettings.SetShadowDebugMode(ShadowMapDebugMode.SingleShadow);
|
|
SRI.camera.targetTexture = output;
|
|
SRI.camera.Render();
|
|
debugDisplaySettings.SetShadowDebugMode(ShadowMapDebugMode.None);
|
|
SRI.sunLight.intensity = 0f;
|
|
data.additionalCameraData.backgroundColorHDR = oldBackgroundColor;
|
|
data.additionalCameraData.clearColorMode = oldClearMode;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The HDRP implementation for the callback that the look dev raises to process any necessary cleanup.
|
|
/// </summary>
|
|
/// <param name="SRI">Access element of the LookDev's scene</param>
|
|
void IDataProvider.Cleanup(StageRuntimeInterface SRI)
|
|
{
|
|
LookDevDataForHDRP data = (LookDevDataForHDRP)SRI.SRPData;
|
|
CoreUtils.Destroy(data.volume.sharedProfile);
|
|
}
|
|
}
|
|
}
|