394 lines
18 KiB
C#
394 lines
18 KiB
C#
using System;
|
|
using UnityEngine.Serialization;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
/// <summary>
|
|
/// A bit flag for each camera settings.
|
|
/// </summary>
|
|
[Flags]
|
|
public enum CameraSettingsFields
|
|
{
|
|
/// <summary>No field</summary>
|
|
none = 0,
|
|
/// <summary>BufferClear.clearColorMode</summary>
|
|
bufferClearColorMode = 1 << 1,
|
|
/// <summary>BufferClear.backgroundColorHDR</summary>
|
|
bufferClearBackgroundColorHDR = 1 << 2,
|
|
/// <summary>BufferClear.clearDepth</summary>
|
|
bufferClearClearDepth = 1 << 3,
|
|
/// <summary>volumes.layerMask</summary>
|
|
volumesLayerMask = 1 << 4,
|
|
/// <summary>volumes.anchorOverride</summary>
|
|
volumesAnchorOverride = 1 << 5,
|
|
/// <summary>frustum.mode</summary>
|
|
frustumMode = 1 << 6,
|
|
/// <summary>frustum.aspect</summary>
|
|
frustumAspect = 1 << 7,
|
|
/// <summary>frustum.farClipPlane</summary>
|
|
frustumFarClipPlane = 1 << 8,
|
|
/// <summary>frustum.nearClipPlane</summary>
|
|
frustumNearClipPlane = 1 << 9,
|
|
/// <summary>frustum.fieldOfView</summary>
|
|
frustumFieldOfView = 1 << 10,
|
|
/// <summary>frustum.projectionMatrix</summary>
|
|
frustumProjectionMatrix = 1 << 11,
|
|
/// <summary>culling.useOcclusionCulling</summary>
|
|
cullingUseOcclusionCulling = 1 << 12,
|
|
/// <summary>culling.cullingMask</summary>
|
|
cullingCullingMask = 1 << 13,
|
|
/// <summary>culling.invertFaceCulling</summary>
|
|
cullingInvertFaceCulling = 1 << 14,
|
|
/// <summary>culling.renderingSettings</summary>
|
|
customRenderingSettings = 1 << 15,
|
|
/// <summary>flipYMode</summary>
|
|
flipYMode = 1 << 16,
|
|
/// <summary>frameSettings</summary>
|
|
frameSettings = 1 << 17,
|
|
/// <summary>probeLayerMask</summary>
|
|
probeLayerMask = 1 << 18
|
|
}
|
|
|
|
/// <summary>The overriden fields of a camera settings.</summary>
|
|
[Serializable]
|
|
public struct CameraSettingsOverride
|
|
{
|
|
/// <summary>
|
|
/// Backed value.
|
|
/// </summary>
|
|
public CameraSettingsFields camera;
|
|
}
|
|
|
|
/// <summary>Contains all settings required to setup a camera in HDRP.</summary>
|
|
[Serializable]
|
|
public struct CameraSettings
|
|
{
|
|
/// <summary>Defines how color and depth buffers are cleared.</summary>
|
|
[Serializable]
|
|
public struct BufferClearing
|
|
{
|
|
/// <summary>Default value.</summary>
|
|
[Obsolete("Since 2019.3, use BufferClearing.NewDefault() instead.")]
|
|
public static readonly BufferClearing @default = default;
|
|
/// <summary>Default value.</summary>
|
|
/// <returns>The default value.</returns>
|
|
public static BufferClearing NewDefault() => new BufferClearing
|
|
{
|
|
clearColorMode = HDAdditionalCameraData.ClearColorMode.Sky,
|
|
backgroundColorHDR = new Color32(6, 18, 48, 0),
|
|
clearDepth = true
|
|
};
|
|
|
|
/// <summary>Define the source for the clear color.</summary>
|
|
public HDAdditionalCameraData.ClearColorMode clearColorMode;
|
|
/// <summary>
|
|
/// The color to use when
|
|
/// <c><see cref="clearColorMode"/> == <see cref="HDAdditionalCameraData.ClearColorMode.Color"/></c>.
|
|
/// </summary>
|
|
[ColorUsage(true, true)]
|
|
public Color backgroundColorHDR;
|
|
/// <summary>True to clear the depth.</summary>
|
|
public bool clearDepth;
|
|
}
|
|
|
|
/// <summary>Defines how the volume framework is queried.</summary>
|
|
[Serializable]
|
|
public struct Volumes
|
|
{
|
|
/// <summary>Default value.</summary>
|
|
[Obsolete("Since 2019.3, use Volumes.NewDefault() instead.")]
|
|
public static readonly Volumes @default = default;
|
|
/// <summary>Default value.</summary>
|
|
/// <returns>The default value.</returns>
|
|
public static Volumes NewDefault() => new Volumes
|
|
{
|
|
layerMask = -1,
|
|
anchorOverride = null
|
|
};
|
|
|
|
/// <summary>The <see cref="LayerMask"/> to use for the volumes.</summary>
|
|
public LayerMask layerMask;
|
|
/// <summary>If not null, define the location of the evaluation of the volume framework.</summary>
|
|
public Transform anchorOverride;
|
|
}
|
|
|
|
|
|
/// <summary>Defines the projection matrix of the camera.</summary>
|
|
[Serializable]
|
|
public struct Frustum
|
|
{
|
|
// Below 1e-5, it causes errors
|
|
// in `ScriptableShadowsUtility::GetPSSMSplitMatricesAndCulling`: "Expanding invalid MinMaxAABB"
|
|
// So we use 1e-5 as the minimum value.
|
|
/// <summary>The near clip plane value will be above this value.</summary>
|
|
public const float MinNearClipPlane = 1e-5f;
|
|
/// <summary> The far clip plane value will be at least above <c><see cref="nearClipPlane"/> + <see cref="MinFarClipPlane"/></c></summary>
|
|
public const float MinFarClipPlane = 1e-4f;
|
|
|
|
/// <summary>Default value.</summary>
|
|
[Obsolete("Since 2019.3, use Frustum.NewDefault() instead.")]
|
|
public static readonly Frustum @default = default;
|
|
/// <summary>Default value.</summary>
|
|
/// <returns>The default value.</returns>
|
|
public static Frustum NewDefault() => new Frustum
|
|
{
|
|
mode = Mode.ComputeProjectionMatrix,
|
|
aspect = 1.0f,
|
|
farClipPlaneRaw = 1000.0f,
|
|
nearClipPlaneRaw = 0.1f,
|
|
fieldOfView = 90.0f,
|
|
projectionMatrix = Matrix4x4.identity
|
|
};
|
|
|
|
/// <summary>Defines how the projection matrix is computed.</summary>
|
|
public enum Mode
|
|
{
|
|
/// <summary>
|
|
/// For perspective projection, the matrix is computed from <see cref="aspect"/>,
|
|
/// <see cref="farClipPlane"/>, <see cref="nearClipPlane"/> and <see cref="fieldOfView"/> parameters.
|
|
///
|
|
/// Orthographic projection is not currently supported.
|
|
/// </summary>
|
|
ComputeProjectionMatrix,
|
|
/// <summary>The projection matrix provided is assigned.</summary>
|
|
UseProjectionMatrixField
|
|
}
|
|
|
|
/// <summary>Which mode will be used for the projection matrix.</summary>
|
|
public Mode mode;
|
|
/// <summary>Aspect ratio of the frustum (width/height).</summary>
|
|
public float aspect;
|
|
|
|
/// <summary>
|
|
/// Far clip plane distance.
|
|
///
|
|
/// Value that will be stored for the far clip plane distance.
|
|
/// IF you need the effective far clip plane distance, use <see cref="farClipPlane"/>.
|
|
/// </summary>
|
|
[FormerlySerializedAs("farClipPlane")]
|
|
public float farClipPlaneRaw;
|
|
/// <summary>
|
|
/// Near clip plane distance.
|
|
///
|
|
/// Value that will be stored for the near clip plane distance.
|
|
/// IF you need the effective near clip plane distance, use <see cref="nearClipPlane"/>.
|
|
/// </summary>
|
|
[FormerlySerializedAs("nearClipPlane")]
|
|
public float nearClipPlaneRaw;
|
|
|
|
/// <summary>
|
|
/// Effective far clip plane distance.
|
|
///
|
|
/// Use this value to compute the projection matrix.
|
|
///
|
|
/// This value is valid to compute a projection matrix.
|
|
/// If you need the raw stored value, see <see cref="farClipPlaneRaw"/> instead.
|
|
/// </summary>
|
|
public float farClipPlane => Mathf.Max(nearClipPlaneRaw + MinFarClipPlane, farClipPlaneRaw);
|
|
|
|
/// <summary>
|
|
/// Effective near clip plane distance.
|
|
///
|
|
/// Use this value to compute the projection matrix.
|
|
///
|
|
/// This value is valid to compute a projection matrix.
|
|
/// If you need the raw stored value, see <see cref="nearClipPlaneRaw"/> instead.
|
|
/// </summary>
|
|
public float nearClipPlane => Mathf.Max(MinNearClipPlane, nearClipPlaneRaw);
|
|
|
|
/// <summary>Field of view for perspective matrix (for y axis, in degree).</summary>
|
|
[Range(1, 179.0f)]
|
|
public float fieldOfView;
|
|
|
|
/// <summary>Projection matrix used for <see cref="Mode.UseProjectionMatrixField"/> mode.</summary>
|
|
public Matrix4x4 projectionMatrix;
|
|
|
|
/// <summary>Compute the projection matrix based on the mode and settings provided.</summary>
|
|
/// <returns>The projection matrix.</returns>
|
|
public Matrix4x4 ComputeProjectionMatrix()
|
|
{
|
|
return Matrix4x4.Perspective(HDUtils.ClampFOV(fieldOfView), aspect, nearClipPlane, farClipPlane);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the projection matrix used depending on the projection mode.
|
|
/// </summary>
|
|
/// <returns>The projection matrix</returns>
|
|
public Matrix4x4 GetUsedProjectionMatrix()
|
|
{
|
|
switch (mode)
|
|
{
|
|
case Mode.ComputeProjectionMatrix: return ComputeProjectionMatrix();
|
|
case Mode.UseProjectionMatrixField: return projectionMatrix;
|
|
default: throw new ArgumentException();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Defines the culling settings of the camera.</summary>
|
|
[Serializable]
|
|
public struct Culling
|
|
{
|
|
/// <summary>Default value.</summary>
|
|
[Obsolete("Since 2019.3, use Culling.NewDefault() instead.")]
|
|
public static readonly Culling @default = default;
|
|
/// <summary>Default value.</summary>
|
|
/// <returns>The default value.</returns>
|
|
public static Culling NewDefault() => new Culling
|
|
{
|
|
cullingMask = -1,
|
|
useOcclusionCulling = true,
|
|
sceneCullingMaskOverride = 0
|
|
};
|
|
|
|
/// <summary>True when occlusion culling will be performed during rendering, false otherwise.</summary>
|
|
public bool useOcclusionCulling;
|
|
/// <summary>The mask for visible objects.</summary>
|
|
public LayerMask cullingMask;
|
|
/// <summary>Scene culling mask override.</summary>
|
|
public ulong sceneCullingMaskOverride;
|
|
}
|
|
|
|
/// <summary>Default value.</summary>
|
|
[Obsolete("Since 2019.3, use CameraSettings.defaultCameraSettingsNonAlloc instead.")]
|
|
public static readonly CameraSettings @default = default;
|
|
/// <summary>Default value.</summary>
|
|
/// <returns>The default value and allocate ~250B of garbage.</returns>
|
|
public static CameraSettings NewDefault() => new CameraSettings
|
|
{
|
|
bufferClearing = BufferClearing.NewDefault(),
|
|
culling = Culling.NewDefault(),
|
|
renderingPathCustomFrameSettings = FrameSettings.NewDefaultCamera(),
|
|
frustum = Frustum.NewDefault(),
|
|
customRenderingSettings = false,
|
|
volumes = Volumes.NewDefault(),
|
|
flipYMode = HDAdditionalCameraData.FlipYMode.Automatic,
|
|
invertFaceCulling = false,
|
|
probeLayerMask = ~0,
|
|
probeRangeCompressionFactor = 1.0f
|
|
};
|
|
|
|
/// <summary>Default camera settings.</summary>
|
|
public static readonly CameraSettings defaultCameraSettingsNonAlloc = NewDefault();
|
|
|
|
/// <summary>
|
|
/// Extract the CameraSettings from an HDCamera
|
|
/// </summary>
|
|
/// <param name="hdCamera">The camera to extract from</param>
|
|
/// <returns>The CameraSettings</returns>
|
|
public static CameraSettings From(HDCamera hdCamera)
|
|
{
|
|
var settings = defaultCameraSettingsNonAlloc;
|
|
settings.culling.cullingMask = hdCamera.camera.cullingMask;
|
|
settings.culling.useOcclusionCulling = hdCamera.camera.useOcclusionCulling;
|
|
settings.culling.sceneCullingMaskOverride = HDUtils.GetSceneCullingMaskFromCamera(hdCamera.camera);
|
|
settings.frustum.aspect = hdCamera.camera.aspect;
|
|
settings.frustum.farClipPlaneRaw = hdCamera.camera.farClipPlane;
|
|
settings.frustum.nearClipPlaneRaw = hdCamera.camera.nearClipPlane;
|
|
settings.frustum.fieldOfView = hdCamera.camera.fieldOfView;
|
|
settings.frustum.mode = Frustum.Mode.UseProjectionMatrixField;
|
|
settings.frustum.projectionMatrix = hdCamera.camera.projectionMatrix;
|
|
settings.invertFaceCulling = false;
|
|
|
|
HDAdditionalCameraData add;
|
|
if (hdCamera.camera.TryGetComponent<HDAdditionalCameraData>(out add))
|
|
{
|
|
settings.customRenderingSettings = add.customRenderingSettings;
|
|
settings.bufferClearing.backgroundColorHDR = add.backgroundColorHDR;
|
|
settings.bufferClearing.clearColorMode = add.clearColorMode;
|
|
settings.bufferClearing.clearDepth = add.clearDepth;
|
|
settings.flipYMode = add.flipYMode;
|
|
settings.renderingPathCustomFrameSettings = add.renderingPathCustomFrameSettings;
|
|
settings.renderingPathCustomFrameSettingsOverrideMask = add.renderingPathCustomFrameSettingsOverrideMask;
|
|
settings.volumes = new Volumes
|
|
{
|
|
anchorOverride = add.volumeAnchorOverride,
|
|
layerMask = add.volumeLayerMask
|
|
};
|
|
settings.probeLayerMask = add.probeLayerMask;
|
|
settings.invertFaceCulling = add.invertFaceCulling;
|
|
}
|
|
|
|
// (case 1131731) Camera.RenderToCubemap inverts faces
|
|
// Unity's API is using LHS standard when rendering cubemaps, so we need to invert the face culling
|
|
// in that specific case.
|
|
// We try to guess with a lot of constraints when this is the case.
|
|
var isLHSViewMatrix = hdCamera.camera.worldToCameraMatrix.determinant > 0;
|
|
var isPerspectiveMatrix = Mathf.Approximately(hdCamera.camera.projectionMatrix.m32, -1);
|
|
var isFOV45Degrees = Mathf.Approximately(hdCamera.camera.projectionMatrix.m00, 1)
|
|
&& Mathf.Approximately(hdCamera.camera.projectionMatrix.m11, 1);
|
|
|
|
if (isLHSViewMatrix && isPerspectiveMatrix && isFOV45Degrees)
|
|
settings.invertFaceCulling = true;
|
|
|
|
return settings;
|
|
}
|
|
|
|
/// <summary>Override rendering settings if true.</summary>
|
|
public bool customRenderingSettings;
|
|
/// <summary>Frame settings to use.</summary>
|
|
public FrameSettings renderingPathCustomFrameSettings;
|
|
/// <summary>Frame settings mask to use.</summary>
|
|
public FrameSettingsOverrideMask renderingPathCustomFrameSettingsOverrideMask;
|
|
/// <summary>Buffer clearing settings to use.</summary>
|
|
public BufferClearing bufferClearing;
|
|
/// <summary>Volumes settings to use.</summary>
|
|
public Volumes volumes;
|
|
/// <summary>Frustum settings to use.</summary>
|
|
public Frustum frustum;
|
|
/// <summary>Culling settings to use.</summary>
|
|
public Culling culling;
|
|
/// <summary>True to invert face culling, false otherwise.</summary>
|
|
public bool invertFaceCulling;
|
|
/// <summary>The mode to use when we want to flip the Y axis.</summary>
|
|
public HDAdditionalCameraData.FlipYMode flipYMode;
|
|
/// <summary>The layer mask to use to filter probes that can influence this camera.</summary>
|
|
public LayerMask probeLayerMask;
|
|
/// <summary>Which default FrameSettings should be used when rendering with these parameters.</summary>
|
|
public FrameSettingsRenderType defaultFrameSettings;
|
|
|
|
// Marked as internal as it is here just for propagation purposes, the correct way to edit this value is through the probe itself.
|
|
internal float probeRangeCompressionFactor;
|
|
|
|
[SerializeField][FormerlySerializedAs("renderingPath")][Obsolete("For data migration")]
|
|
internal int m_ObsoleteRenderingPath;
|
|
#pragma warning disable 618 // Type or member is obsolete
|
|
[SerializeField][FormerlySerializedAs("frameSettings")][Obsolete("For data migration")]
|
|
internal ObsoleteFrameSettings m_ObsoleteFrameSettings;
|
|
#pragma warning restore 618
|
|
|
|
internal Hash128 GetHash()
|
|
{
|
|
var h = new Hash128();
|
|
var h2 = new Hash128();
|
|
|
|
HashUtilities.ComputeHash128(ref bufferClearing, ref h);
|
|
HashUtilities.ComputeHash128(ref culling, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref customRenderingSettings, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref defaultFrameSettings, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref flipYMode, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref frustum, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref invertFaceCulling, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref probeLayerMask, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref probeRangeCompressionFactor, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref renderingPathCustomFrameSettings, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
HashUtilities.ComputeHash128(ref renderingPathCustomFrameSettingsOverrideMask, ref h2);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
int volumeHash = volumes.GetHashCode();
|
|
h2 = new Hash128((ulong)volumeHash, 0);
|
|
HashUtilities.AppendHash(ref h2, ref h);
|
|
|
|
return h;
|
|
}
|
|
}
|
|
}
|