using System;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Assertions;
using UnityEngine.Experimental.GlobalIllumination;
using UnityEngine.Experimental.Rendering;
using Lightmapping = UnityEngine.Experimental.GlobalIllumination.Lightmapping;
namespace UnityEngine.Rendering.Universal
{
static class NativeArrayExtensions
{
///
/// IMPORTANT: Make sure you do not write to the value! There are no checks for this!
///
public static unsafe ref T UnsafeElementAt(this NativeArray array, int index) where T : struct
{
return ref UnsafeUtility.ArrayElementAsRef(array.GetUnsafeReadOnlyPtr(), index);
}
public static unsafe ref T UnsafeElementAtMutable(this NativeArray array, int index) where T : struct
{
return ref UnsafeUtility.ArrayElementAsRef(array.GetUnsafePtr(), index);
}
}
///
/// Options for mixed lighting setup.
///
public enum MixedLightingSetup
{
///
/// Use this to disable mixed lighting.
///
None,
///
/// Use this to select shadow mask.
///
ShadowMask,
///
/// Use this to select subtractive.
///
Subtractive,
};
///
/// Enumeration that indicates what kind of image scaling is occurring if any
///
internal enum ImageScalingMode
{
/// No scaling
None,
/// Upscaling to a larger image
Upscaling,
/// Downscaling to a smaller image
Downscaling
}
///
/// Enumeration that indicates what kind of upscaling filter is being used
///
internal enum ImageUpscalingFilter
{
/// Bilinear filtering
Linear,
/// Nearest-Neighbor filtering
Point,
/// FidelityFX Super Resolution
FSR
}
///
/// Struct that flattens several rendering settings used to render a camera stack.
/// URP builds the RenderingData settings from several places, including the pipeline asset, camera and light settings.
/// The settings also might vary on different platforms and depending on if Adaptive Performance is used.
///
public struct RenderingData
{
internal CommandBuffer commandBuffer;
///
/// Returns culling results that exposes handles to visible objects, lights and probes.
/// You can use this to draw objects with ScriptableRenderContext.DrawRenderers
///
///
///
public CullingResults cullResults;
///
/// Holds several rendering settings related to camera.
///
///
public CameraData cameraData;
///
/// Holds several rendering settings related to lights.
///
///
public LightData lightData;
///
/// Holds several rendering settings related to shadows.
///
///
public ShadowData shadowData;
///
/// Holds several rendering settings and resources related to the integrated post-processing stack.
///
///
public PostProcessingData postProcessingData;
///
/// True if the pipeline supports dynamic batching.
/// This settings doesn't apply when drawing shadow casters. Dynamic batching is always disabled when drawing shadow casters.
///
public bool supportsDynamicBatching;
///
/// Holds per-object data that are requested when drawing
///
///
public PerObjectData perObjectData;
///
/// True if post-processing effect is enabled while rendering the camera stack.
///
public bool postProcessingEnabled;
}
///
/// Struct that holds settings related to lights.
///
public struct LightData
{
///
/// Holds the main light index from the VisibleLight list returned by culling. If there's no main light in the scene, mainLightIndex is set to -1.
/// The main light is the directional light assigned as Sun source in light settings or the brightest directional light.
///
///
public int mainLightIndex;
///
/// The number of additional lights visible by the camera.
///
public int additionalLightsCount;
///
/// Maximum amount of lights that can be shaded per-object. This value only affects forward rendering.
///
public int maxPerObjectAdditionalLightsCount;
///
/// List of visible lights returned by culling.
///
public NativeArray visibleLights;
///
/// True if additional lights should be shaded in vertex shader, otherwise additional lights will be shaded per pixel.
///
public bool shadeAdditionalLightsPerVertex;
///
/// True if mixed lighting is supported.
///
public bool supportsMixedLighting;
///
/// True if box projection is enabled for reflection probes.
///
public bool reflectionProbeBoxProjection;
///
/// True if blending is enabled for reflection probes.
///
public bool reflectionProbeBlending;
///
/// True if light layers are enabled.
///
public bool supportsLightLayers;
///
/// True if additional lights enabled.
///
public bool supportsAdditionalLights;
}
///
/// Struct that holds settings related to camera.
///
public struct CameraData
{
// Internal camera data as we are not yet sure how to expose View in stereo context.
// We might change this API soon.
Matrix4x4 m_ViewMatrix;
Matrix4x4 m_ProjectionMatrix;
Matrix4x4 m_JitterMatrix;
internal void SetViewAndProjectionMatrix(Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix)
{
m_ViewMatrix = viewMatrix;
m_ProjectionMatrix = projectionMatrix;
m_JitterMatrix = Matrix4x4.identity;
}
internal void SetViewProjectionAndJitterMatrix(Matrix4x4 viewMatrix, Matrix4x4 projectionMatrix, Matrix4x4 jitterMatrix)
{
m_ViewMatrix = viewMatrix;
m_ProjectionMatrix = projectionMatrix;
m_JitterMatrix = jitterMatrix;
}
// Helper function to populate builtin stereo matricies as well as URP stereo matricies
internal void PushBuiltinShaderConstantsXR(CommandBuffer cmd, bool renderIntoTexture)
{
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
{
cmd.SetViewProjectionMatrices(GetViewMatrix(), GetProjectionMatrix());
if (xr.singlePassEnabled)
{
for (int viewId = 0; viewId < xr.viewCount; viewId++)
{
XRBuiltinShaderConstants.UpdateBuiltinShaderConstants(GetViewMatrix(viewId), GetProjectionMatrix(viewId), renderIntoTexture, viewId);
}
XRBuiltinShaderConstants.SetBuiltinShaderConstants(cmd);
}
}
#endif
}
///
/// Returns the camera view matrix.
///
/// View index in case of stereo rendering. By default viewIndex is set to 0.
/// The camera view matrix.
public Matrix4x4 GetViewMatrix(int viewIndex = 0)
{
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
return xr.GetViewMatrix(viewIndex);
#endif
return m_ViewMatrix;
}
///
/// Returns the camera projection matrix. Might be jittered for temporal features.
///
/// View index in case of stereo rendering. By default viewIndex is set to 0.
/// The camera projection matrix.
public Matrix4x4 GetProjectionMatrix(int viewIndex = 0)
{
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
return m_JitterMatrix * xr.GetProjMatrix(viewIndex);
#endif
return m_JitterMatrix * m_ProjectionMatrix;
}
internal Matrix4x4 GetProjectionMatrixNoJitter(int viewIndex = 0)
{
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
return xr.GetProjMatrix(viewIndex);
#endif
return m_ProjectionMatrix;
}
///
/// Returns the camera GPU projection matrix. This contains platform specific changes to handle y-flip and reverse z. Includes camera jitter if required by active features.
/// Similar to GL.GetGPUProjectionMatrix but queries URP internal state to know if the pipeline is rendering to render texture.
/// For more info on platform differences regarding camera projection check: https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
///
/// View index in case of stereo rendering. By default viewIndex is set to 0.
///
///
public Matrix4x4 GetGPUProjectionMatrix(int viewIndex = 0)
{
// GetGPUProjectionMatrix takes a projection matrix and returns a GfxAPI adjusted version, does not set or get any state.
return m_JitterMatrix * GL.GetGPUProjectionMatrix(GetProjectionMatrixNoJitter(viewIndex), IsCameraProjectionMatrixFlipped());
}
///
/// Returns the camera GPU projection matrix. This contains platform specific changes to handle y-flip and reverse z. Does not include any camera jitter.
/// Similar to GL.GetGPUProjectionMatrix but queries URP internal state to know if the pipeline is rendering to render texture.
/// For more info on platform differences regarding camera projection check: https://docs.unity3d.com/Manual/SL-PlatformDifferences.html
///
/// View index in case of stereo rendering. By default viewIndex is set to 0.
///
///
public Matrix4x4 GetGPUProjectionMatrixNoJitter(int viewIndex = 0)
{
// GetGPUProjectionMatrix takes a projection matrix and returns a GfxAPI adjusted version, does not set or get any state.
return GL.GetGPUProjectionMatrix(GetProjectionMatrixNoJitter(viewIndex), IsCameraProjectionMatrixFlipped());
}
internal Matrix4x4 GetGPUProjectionMatrix(bool renderIntoTexture, int viewIndex = 0)
{
return m_JitterMatrix * GL.GetGPUProjectionMatrix(GetProjectionMatrix(viewIndex), renderIntoTexture);
}
///
/// The camera component.
///
public Camera camera;
///
/// The camera render type used for camera stacking.
///
///
public CameraRenderType renderType;
///
/// Controls the final target texture for a camera. If null camera will resolve rendering to screen.
///
public RenderTexture targetTexture;
///
/// Render texture settings used to create intermediate camera textures for rendering.
///
public RenderTextureDescriptor cameraTargetDescriptor;
internal Rect pixelRect;
internal bool useScreenCoordOverride;
internal Vector4 screenSizeOverride;
internal Vector4 screenCoordScaleBias;
internal int pixelWidth;
internal int pixelHeight;
internal float aspectRatio;
///
/// Render scale to apply when creating camera textures.
///
public float renderScale;
internal ImageScalingMode imageScalingMode;
internal ImageUpscalingFilter upscalingFilter;
internal bool fsrOverrideSharpness;
internal float fsrSharpness;
internal HDRColorBufferPrecision hdrColorBufferPrecision;
///
/// True if this camera should clear depth buffer. This setting only applies to cameras of type CameraRenderType.Overlay
///
///
public bool clearDepth;
///
/// The camera type.
///
///
public CameraType cameraType;
///
/// True if this camera is drawing to a viewport that maps to the entire screen.
///
public bool isDefaultViewport;
///
/// True if this camera should render to high dynamic range color targets.
///
public bool isHdrEnabled;
///
/// True if this camera allow color conversion and encoding for high dynamic range displays.
///
public bool allowHDROutput;
///
/// True if this camera requires to write _CameraDepthTexture.
///
public bool requiresDepthTexture;
///
/// True if this camera requires to copy camera color texture to _CameraOpaqueTexture.
///
public bool requiresOpaqueTexture;
///
/// Returns true if post processing passes require depth texture.
///
public bool postProcessingRequiresDepthTexture;
///
/// Returns true if XR rendering is enabled.
///
public bool xrRendering;
internal bool requireSrgbConversion
{
get
{
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
return !xr.renderTargetDesc.sRGB && (QualitySettings.activeColorSpace == ColorSpace.Linear);
#endif
return targetTexture == null && Display.main.requiresSrgbBlitToBackbuffer;
}
}
///
/// True if the camera rendering is for the scene window in the editor.
///
public bool isSceneViewCamera => cameraType == CameraType.SceneView;
///
/// True if the camera rendering is for the preview window in the editor.
///
public bool isPreviewCamera => cameraType == CameraType.Preview;
internal bool isRenderPassSupportedCamera => (cameraType == CameraType.Game || cameraType == CameraType.Reflection);
internal bool resolveToScreen => targetTexture == null && resolveFinalTarget && (cameraType == CameraType.Game || camera.cameraType == CameraType.VR);
///
/// True if the Camera should output to an HDR display.
///
public bool isHDROutputActive => UniversalRenderPipeline.HDROutputIsActive() && allowHDROutput && resolveToScreen;
///
/// True if the Camera should render overlay UI.
///
public bool rendersOverlayUI => SupportedRenderingFeatures.active.rendersUIOverlay && resolveToScreen;
///
/// True is the handle has its content flipped on the y axis.
/// This happens only with certain rendering APIs.
/// On those platforms, any handle will have its content flipped unless rendering to a backbuffer, however,
/// the scene view will always be flipped.
/// When transitioning from a flipped space to a non-flipped space - or vice-versa - the content must be flipped
/// in the shader:
/// shouldPerformYFlip = IsHandleYFlipped(source) != IsHandleYFlipped(target)
///
/// Handle to check the flipped status on.
/// True is the content is flipped in y.
public bool IsHandleYFlipped(RTHandle handle)
{
if (!SystemInfo.graphicsUVStartsAtTop)
return false;
if (cameraType == CameraType.SceneView)
return true;
var handleID = new RenderTargetIdentifier(handle.nameID, 0, CubemapFace.Unknown, 0);
bool isBackbuffer = handleID == BuiltinRenderTextureType.CameraTarget;
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
isBackbuffer |= handleID == new RenderTargetIdentifier(xr.renderTarget, 0, CubemapFace.Unknown, 0);
#endif
return !isBackbuffer;
}
///
/// True if the camera device projection matrix is flipped. This happens when the pipeline is rendering
/// to a render texture in non OpenGL platforms. If you are doing a custom Blit pass to copy camera textures
/// (_CameraColorTexture, _CameraDepthAttachment) you need to check this flag to know if you should flip the
/// matrix when rendering with for cmd.Draw* and reading from camera textures.
///
/// True if the camera device projection matrix is flipped.
public bool IsCameraProjectionMatrixFlipped()
{
if (!SystemInfo.graphicsUVStartsAtTop)
return false;
// Users only have access to CameraData on URP rendering scope. The current renderer should never be null.
var renderer = ScriptableRenderer.current;
Debug.Assert(renderer != null, "IsCameraProjectionMatrixFlipped is being called outside camera rendering scope.");
if (renderer != null)
{
var handle = renderer.cameraColorTargetHandle;
bool flipped;
#pragma warning disable 0618 // Obsolete usage: Backwards compatibility for renderer using cameraColorTarget instead of cameraColorTargetHandle
if (handle == null)
{
if (cameraType == CameraType.SceneView)
{
flipped = true;
}
else
{
var handleID = new RenderTargetIdentifier(renderer.cameraColorTarget, 0, CubemapFace.Unknown, 0);
bool isBackbuffer = handleID == BuiltinRenderTextureType.CameraTarget;
#if ENABLE_VR && ENABLE_XR_MODULE
if (xr.enabled)
isBackbuffer |= handleID == new RenderTargetIdentifier(xr.renderTarget, 0, CubemapFace.Unknown, 0);
#endif
flipped = !isBackbuffer;
}
}
else
#pragma warning restore 0618
flipped = IsHandleYFlipped(handle);
return flipped || targetTexture != null;
}
return true;
}
///
/// True if the render target's projection matrix is flipped. This happens when the pipeline is rendering
/// to a render texture in non OpenGL platforms. If you are doing a custom Blit pass to copy camera textures
/// (_CameraColorTexture, _CameraDepthAttachment) you need to check this flag to know if you should flip the
/// matrix when rendering with for cmd.Draw* and reading from camera textures.
///
/// Color render target to check whether the matrix is flipped.
/// Depth render target which is used if color is null. By default depth is set to null.
/// True if the render target's projection matrix is flipped.
public bool IsRenderTargetProjectionMatrixFlipped(RTHandle color, RTHandle depth = null)
{
if (!SystemInfo.graphicsUVStartsAtTop)
return false;
return targetTexture != null || IsHandleYFlipped(color ?? depth);
}
internal bool IsTemporalAAEnabled()
{
UniversalAdditionalCameraData additionalCameraData;
camera.TryGetComponent(out additionalCameraData);
return (antialiasing == AntialiasingMode.TemporalAntiAliasing) // Enabled
&& (taaPersistentData != null) // Initialized
&& (cameraTargetDescriptor.msaaSamples == 1) // No MSAA
&& !(additionalCameraData?.renderType == CameraRenderType.Overlay || additionalCameraData?.cameraStack.Count > 0) // No Camera stack
&& !camera.allowDynamicResolution // No Dynamic Resolution
&& postProcessEnabled; // No Postprocessing
}
///
/// The sorting criteria used when drawing opaque objects by the internal URP render passes.
/// When a GPU supports hidden surface removal, URP will rely on that information to avoid sorting opaque objects front to back and
/// benefit for more optimal static batching.
///
///
public SortingCriteria defaultOpaqueSortFlags;
///
/// XRPass holds the render target information and a list of XRView.
/// XRView contains the parameters required to render (projection and view matrices, viewport, etc)
///
public XRPass xr { get; internal set; }
internal XRPassUniversal xrUniversal => xr as XRPassUniversal;
///
/// Is XR enabled or not.
/// This is obsolete, please use xr.enabled instead.
///
[Obsolete("Please use xr.enabled instead.", true)]
public bool isStereoEnabled;
///
/// Maximum shadow distance visible to the camera. When set to zero shadows will be disable for that camera.
///
public float maxShadowDistance;
///
/// True if post-processing is enabled for this camera.
///
public bool postProcessEnabled;
///
/// Provides set actions to the renderer to be triggered at the end of the render loop for camera capture.
///
public IEnumerator> captureActions;
///
/// The camera volume layer mask.
///
public LayerMask volumeLayerMask;
///
/// The camera volume trigger.
///
public Transform volumeTrigger;
///
/// If set to true, the integrated post-processing stack will replace any NaNs generated by render passes prior to post-processing with black/zero.
/// Enabling this option will cause a noticeable performance impact. It should be used while in development mode to identify NaN issues.
///
public bool isStopNaNEnabled;
///
/// If set to true a final post-processing pass will be applied to apply dithering.
/// This can be combined with post-processing antialiasing.
///
///
public bool isDitheringEnabled;
///
/// Controls the anti-alising mode used by the integrated post-processing stack.
/// When any other value other than AntialiasingMode.None is chosen, a final post-processing pass will be applied to apply anti-aliasing.
/// This pass can be combined with dithering.
///
///
///
public AntialiasingMode antialiasing;
///
/// Controls the anti-alising quality of the anti-aliasing mode.
///
///
///
public AntialiasingQuality antialiasingQuality;
///
/// Returns the current renderer used by this camera.
///
///
public ScriptableRenderer renderer;
///
/// True if this camera is resolving rendering to the final camera render target.
/// When rendering a stack of cameras only the last camera in the stack will resolve to camera target.
///
public bool resolveFinalTarget;
///
/// Camera position in world space.
///
public Vector3 worldSpaceCameraPos;
///
/// Final background color in the active color space.
///
public Color backgroundColor;
///
/// Persistent TAA data, primarily for the accumulation texture.
///
internal TaaPersistentData taaPersistentData;
// TAA settings.
internal TemporalAA.Settings taaSettings;
// Post-process history reset has been triggered for this camera.
internal bool resetHistory
{
get => taaSettings.resetHistoryFrames != 0;
}
///
/// Camera at the top of the overlay camera stack
///
public Camera baseCamera;
}
///
/// Container struct for various data used for shadows in URP.
///
public struct ShadowData
{
///
/// True if main light shadows are enabled.
///
public bool supportsMainLightShadows;
///
/// True if additional lights shadows are enabled in the URP Asset
///
internal bool mainLightShadowsEnabled;
///
/// True if screen space shadows are required.
/// Obsolete, this feature was replaced by new 'ScreenSpaceShadows' renderer feature
///
[Obsolete("Obsolete, this feature was replaced by new 'ScreenSpaceShadows' renderer feature")]
public bool requiresScreenSpaceShadowResolve;
///
/// The width of the main light shadow map.
///
public int mainLightShadowmapWidth;
///
/// The height of the main light shadow map.
///
public int mainLightShadowmapHeight;
///
/// The number of shadow cascades.
///
public int mainLightShadowCascadesCount;
///
/// The split between cascades.
///
public Vector3 mainLightShadowCascadesSplit;
///
/// Main light last cascade shadow fade border.
/// Value represents the width of shadow fade that ranges from 0 to 1.
/// Where value 0 is used for no shadow fade.
///
public float mainLightShadowCascadeBorder;
///
/// True if additional lights shadows are enabled.
///
public bool supportsAdditionalLightShadows;
///
/// True if additional lights shadows are enabled in the URP Asset
///
internal bool additionalLightShadowsEnabled;
///
/// The width of the additional light shadow map.
///
public int additionalLightsShadowmapWidth;
///
/// The height of the additional light shadow map.
///
public int additionalLightsShadowmapHeight;
///
/// True if soft shadows are enabled.
///
public bool supportsSoftShadows;
///
/// The number of bits used.
///
public int shadowmapDepthBufferBits;
///
/// A list of shadow bias.
///
public List bias;
///
/// A list of resolution for the shadow maps.
///
public List resolution;
internal bool isKeywordAdditionalLightShadowsEnabled;
internal bool isKeywordSoftShadowsEnabled;
}
///
/// Precomputed tile data.
/// Tile left, right, bottom and top plane equations in view space.
/// Normals are pointing out.
///
public struct PreTile
{
///
/// The left plane.
///
public Unity.Mathematics.float4 planeLeft;
///
/// The right plane.
///
public Unity.Mathematics.float4 planeRight;
///
/// The bottom plane.
///
public Unity.Mathematics.float4 planeBottom;
///
/// The top plane.
///
public Unity.Mathematics.float4 planeTop;
}
///
/// The tile data passed to the deferred shaders.
///
public struct TileData
{
///
/// The tile ID.
///
public uint tileID; // 2x 16 bits
///
/// The list bit mask.
///
public uint listBitMask; // 32 bits
///
/// The relative light offset.
///
public uint relLightOffset; // 16 bits is enough
///
/// Unused variable.
///
public uint unused;
}
///
/// The point/spot light data passed to the deferred shaders.
///
public struct PunctualLightData
{
///
/// The world position.
///
public Vector3 wsPos;
///
/// The radius of the light.
///
public float radius; // TODO remove? included in attenuation
///
/// The color of the light.
///
public Vector4 color;
///
/// The attenuation of the light.
///
public Vector4 attenuation; // .xy are used by DistanceAttenuation - .zw are used by AngleAttenuation (for SpotLights)
///
/// The direction for spot lights.
///
public Vector3 spotDirection; // for spotLights
///
/// The flags used.
///
public int flags;
///
/// The occlusion probe info.
///
public Vector4 occlusionProbeInfo;
///
/// The layer mask used.
///
public uint layerMask;
}
internal static class ShaderPropertyId
{
public static readonly int glossyEnvironmentColor = Shader.PropertyToID("_GlossyEnvironmentColor");
public static readonly int subtractiveShadowColor = Shader.PropertyToID("_SubtractiveShadowColor");
public static readonly int glossyEnvironmentCubeMap = Shader.PropertyToID("_GlossyEnvironmentCubeMap");
public static readonly int glossyEnvironmentCubeMapHDR = Shader.PropertyToID("_GlossyEnvironmentCubeMap_HDR");
public static readonly int ambientSkyColor = Shader.PropertyToID("unity_AmbientSky");
public static readonly int ambientEquatorColor = Shader.PropertyToID("unity_AmbientEquator");
public static readonly int ambientGroundColor = Shader.PropertyToID("unity_AmbientGround");
public static readonly int time = Shader.PropertyToID("_Time");
public static readonly int sinTime = Shader.PropertyToID("_SinTime");
public static readonly int cosTime = Shader.PropertyToID("_CosTime");
public static readonly int deltaTime = Shader.PropertyToID("unity_DeltaTime");
public static readonly int timeParameters = Shader.PropertyToID("_TimeParameters");
public static readonly int scaledScreenParams = Shader.PropertyToID("_ScaledScreenParams");
public static readonly int worldSpaceCameraPos = Shader.PropertyToID("_WorldSpaceCameraPos");
public static readonly int screenParams = Shader.PropertyToID("_ScreenParams");
public static readonly int alphaToMaskAvailable = Shader.PropertyToID("_AlphaToMaskAvailable");
public static readonly int projectionParams = Shader.PropertyToID("_ProjectionParams");
public static readonly int zBufferParams = Shader.PropertyToID("_ZBufferParams");
public static readonly int orthoParams = Shader.PropertyToID("unity_OrthoParams");
public static readonly int globalMipBias = Shader.PropertyToID("_GlobalMipBias");
public static readonly int screenSize = Shader.PropertyToID("_ScreenSize");
public static readonly int screenCoordScaleBias = Shader.PropertyToID("_ScreenCoordScaleBias");
public static readonly int screenSizeOverride = Shader.PropertyToID("_ScreenSizeOverride");
public static readonly int viewMatrix = Shader.PropertyToID("unity_MatrixV");
public static readonly int projectionMatrix = Shader.PropertyToID("glstate_matrix_projection");
public static readonly int viewAndProjectionMatrix = Shader.PropertyToID("unity_MatrixVP");
public static readonly int inverseViewMatrix = Shader.PropertyToID("unity_MatrixInvV");
public static readonly int inverseProjectionMatrix = Shader.PropertyToID("unity_MatrixInvP");
public static readonly int inverseViewAndProjectionMatrix = Shader.PropertyToID("unity_MatrixInvVP");
public static readonly int cameraProjectionMatrix = Shader.PropertyToID("unity_CameraProjection");
public static readonly int inverseCameraProjectionMatrix = Shader.PropertyToID("unity_CameraInvProjection");
public static readonly int worldToCameraMatrix = Shader.PropertyToID("unity_WorldToCamera");
public static readonly int cameraToWorldMatrix = Shader.PropertyToID("unity_CameraToWorld");
public static readonly int cameraWorldClipPlanes = Shader.PropertyToID("unity_CameraWorldClipPlanes");
public static readonly int billboardNormal = Shader.PropertyToID("unity_BillboardNormal");
public static readonly int billboardTangent = Shader.PropertyToID("unity_BillboardTangent");
public static readonly int billboardCameraParams = Shader.PropertyToID("unity_BillboardCameraParams");
public static readonly int blitTexture = Shader.PropertyToID("_BlitTexture");
public static readonly int blitScaleBias = Shader.PropertyToID("_BlitScaleBias");
public static readonly int sourceTex = Shader.PropertyToID("_SourceTex");
public static readonly int scaleBias = Shader.PropertyToID("_ScaleBias");
public static readonly int scaleBiasRt = Shader.PropertyToID("_ScaleBiasRt");
// Required for 2D Unlit Shadergraph master node as it doesn't currently support hidden properties.
public static readonly int rendererColor = Shader.PropertyToID("_RendererColor");
public static readonly int ditheringTexture = Shader.PropertyToID("_DitheringTexture");
public static readonly int ditheringTextureInvSize = Shader.PropertyToID("_DitheringTextureInvSize");
public static readonly int renderingLayerMaxInt = Shader.PropertyToID("_RenderingLayerMaxInt");
public static readonly int renderingLayerRcpMaxInt = Shader.PropertyToID("_RenderingLayerRcpMaxInt");
public static readonly int overlayUITexture = Shader.PropertyToID("_OverlayUITexture");
public static readonly int hdrOutputLuminanceParams = Shader.PropertyToID("_HDROutputLuminanceParams");
public static readonly int hdrOutputGradingParams = Shader.PropertyToID("_HDROutputGradingParams");
}
///
/// Settings used for Post Processing.
///
public struct PostProcessingData
{
///
/// The ColorGradingMode to use.
///
///
public ColorGradingMode gradingMode;
///
/// The size of the Look Up Table (LUT)
///
public int lutSize;
///
/// True if fast approximation functions are used when converting between the sRGB and Linear color spaces, false otherwise.
///
public bool useFastSRGBLinearConversion;
}
///
/// Container class for keywords used in URP shaders.
///
public static class ShaderKeywordStrings
{
/// Keyword used for shadows without cascades.
public const string MainLightShadows = "_MAIN_LIGHT_SHADOWS";
/// Keyword used for shadows with cascades.
public const string MainLightShadowCascades = "_MAIN_LIGHT_SHADOWS_CASCADE";
/// Keyword used for screen space shadows.
public const string MainLightShadowScreen = "_MAIN_LIGHT_SHADOWS_SCREEN";
/// Keyword used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias.
public const string CastingPunctualLightShadow = "_CASTING_PUNCTUAL_LIGHT_SHADOW";
/// Keyword used for per vertex additional lights.
public const string AdditionalLightsVertex = "_ADDITIONAL_LIGHTS_VERTEX";
/// Keyword used for per pixel additional lights.
public const string AdditionalLightsPixel = "_ADDITIONAL_LIGHTS";
/// Keyword used for Forward+.
internal const string ForwardPlus = "_FORWARD_PLUS";
/// Keyword used for shadows on additional lights.
public const string AdditionalLightShadows = "_ADDITIONAL_LIGHT_SHADOWS";
/// Keyword used for Box Projection with Reflection Probes.
public const string ReflectionProbeBoxProjection = "_REFLECTION_PROBE_BOX_PROJECTION";
/// Keyword used for Reflection probe blending.
public const string ReflectionProbeBlending = "_REFLECTION_PROBE_BLENDING";
/// Keyword used for soft shadows.
public const string SoftShadows = "_SHADOWS_SOFT";
/// Keyword used for Mixed Lights in Subtractive lighting mode.
public const string MixedLightingSubtractive = "_MIXED_LIGHTING_SUBTRACTIVE"; // Backward compatibility
/// Keyword used for mixing lightmap shadows.
public const string LightmapShadowMixing = "LIGHTMAP_SHADOW_MIXING";
/// Keyword used for Shadowmask.
public const string ShadowsShadowMask = "SHADOWS_SHADOWMASK";
/// Keyword used for Light Layers.
public const string LightLayers = "_LIGHT_LAYERS";
/// Keyword used for RenderPass.
public const string RenderPassEnabled = "_RENDER_PASS_ENABLED";
/// Keyword used for Billboard cameras.
public const string BillboardFaceCameraPos = "BILLBOARD_FACE_CAMERA_POS";
/// Keyword used for Light Cookies.
public const string LightCookies = "_LIGHT_COOKIES";
/// Keyword used for no Multi Sampling Anti-Aliasing (MSAA).
public const string DepthNoMsaa = "_DEPTH_NO_MSAA";
/// Keyword used for Multi Sampling Anti-Aliasing (MSAA) with 2 per pixel sample count.
public const string DepthMsaa2 = "_DEPTH_MSAA_2";
/// Keyword used for Multi Sampling Anti-Aliasing (MSAA) with 4 per pixel sample count.
public const string DepthMsaa4 = "_DEPTH_MSAA_4";
/// Keyword used for Multi Sampling Anti-Aliasing (MSAA) with 8 per pixel sample count.
public const string DepthMsaa8 = "_DEPTH_MSAA_8";
/// Keyword used for Linear to SRGB conversions.
public const string LinearToSRGBConversion = "_LINEAR_TO_SRGB_CONVERSION";
/// Keyword used for less expensive Linear to SRGB conversions.
internal const string UseFastSRGBLinearConversion = "_USE_FAST_SRGB_LINEAR_CONVERSION";
/// Keyword used for first target in the DBuffer.
public const string DBufferMRT1 = "_DBUFFER_MRT1";
/// Keyword used for second target in the DBuffer.
public const string DBufferMRT2 = "_DBUFFER_MRT2";
/// Keyword used for third target in the DBuffer.
public const string DBufferMRT3 = "_DBUFFER_MRT3";
/// Keyword used for low quality normal reconstruction in Decals.
public const string DecalNormalBlendLow = "_DECAL_NORMAL_BLEND_LOW";
/// Keyword used for medium quality normal reconstruction in Decals.
public const string DecalNormalBlendMedium = "_DECAL_NORMAL_BLEND_MEDIUM";
/// Keyword used for high quality normal reconstruction in Decals.
public const string DecalNormalBlendHigh = "_DECAL_NORMAL_BLEND_HIGH";
/// Keyword used for Decal Layers.
public const string DecalLayers = "_DECAL_LAYERS";
/// Keyword used for writing Rendering Layers.
public const string WriteRenderingLayers = "_WRITE_RENDERING_LAYERS";
/// Keyword used for low quality Subpixel Morphological Anti-aliasing (SMAA).
public const string SmaaLow = "_SMAA_PRESET_LOW";
/// Keyword used for medium quality Subpixel Morphological Anti-aliasing (SMAA).
public const string SmaaMedium = "_SMAA_PRESET_MEDIUM";
/// Keyword used for high quality Subpixel Morphological Anti-aliasing (SMAA).
public const string SmaaHigh = "_SMAA_PRESET_HIGH";
/// Keyword used for generic Panini Projection.
public const string PaniniGeneric = "_GENERIC";
/// Keyword used for unit distance Panini Projection.
public const string PaniniUnitDistance = "_UNIT_DISTANCE";
/// Keyword used for low quality Bloom.
public const string BloomLQ = "_BLOOM_LQ";
/// Keyword used for high quality Bloom.
public const string BloomHQ = "_BLOOM_HQ";
/// Keyword used for low quality Bloom dirt.
public const string BloomLQDirt = "_BLOOM_LQ_DIRT";
/// Keyword used for high quality Bloom dirt.
public const string BloomHQDirt = "_BLOOM_HQ_DIRT";
/// Keyword used for RGBM format for Bloom.
public const string UseRGBM = "_USE_RGBM";
/// Keyword used for Distortion.
public const string Distortion = "_DISTORTION";
/// Keyword used for Chromatic Aberration.
public const string ChromaticAberration = "_CHROMATIC_ABERRATION";
/// Keyword used for HDR Color Grading.
public const string HDRGrading = "_HDR_GRADING";
/// Keyword used for ACES Tonemapping.
public const string TonemapACES = "_TONEMAP_ACES";
/// Keyword used for Neutral Tonemapping.
public const string TonemapNeutral = "_TONEMAP_NEUTRAL";
/// Keyword used for Film Grain.
public const string FilmGrain = "_FILM_GRAIN";
/// Keyword used for Fast Approximate Anti-aliasing (FXAA).
public const string Fxaa = "_FXAA";
/// Keyword used for Dithering.
public const string Dithering = "_DITHERING";
/// Keyword used for Screen Space Occlusion, such as Screen Space Ambient Occlusion (SSAO).
public const string ScreenSpaceOcclusion = "_SCREEN_SPACE_OCCLUSION";
/// Keyword used for Point sampling when doing upsampling.
public const string PointSampling = "_POINT_SAMPLING";
/// Keyword used for Robust Contrast-Adaptive Sharpening (RCAS) when doing upsampling.
public const string Rcas = "_RCAS";
/// Keyword used for Robust Contrast-Adaptive Sharpening (RCAS) when doing upsampling, after EASU has ran and with HDR Dsiplay output.
public const string EasuRcasAndHDRInput = "_EASU_RCAS_AND_HDR_INPUT";
/// Keyword used for Gamma 2.0.
public const string Gamma20 = "_GAMMA_20";
/// Keyword used for Gamma 2.0 with HDR_INPUT.
public const string Gamma20AndHDRInput = "_GAMMA_20_AND_HDR_INPUT";
/// Keyword used for high quality sampling for Depth Of Field.
public const string HighQualitySampling = "_HIGH_QUALITY_SAMPLING";
/// Keyword used for Spot lights.
public const string _SPOT = "_SPOT";
/// Keyword used for Directional lights.
public const string _DIRECTIONAL = "_DIRECTIONAL";
/// Keyword used for Point lights.
public const string _POINT = "_POINT";
/// Keyword used for stencils when rendering with the Deferred rendering path.
public const string _DEFERRED_STENCIL = "_DEFERRED_STENCIL";
/// Keyword used for the first light when rendering with the Deferred rendering path.
public const string _DEFERRED_FIRST_LIGHT = "_DEFERRED_FIRST_LIGHT";
/// Keyword used for the main light when rendering with the Deferred rendering path.
public const string _DEFERRED_MAIN_LIGHT = "_DEFERRED_MAIN_LIGHT";
/// Keyword used for Accurate G-buffer normals when rendering with the Deferred rendering path.
public const string _GBUFFER_NORMALS_OCT = "_GBUFFER_NORMALS_OCT";
/// Keyword used for Mixed Lighting when rendering with the Deferred rendering path.
public const string _DEFERRED_MIXED_LIGHTING = "_DEFERRED_MIXED_LIGHTING";
/// Keyword used for Lightmaps.
public const string LIGHTMAP_ON = "LIGHTMAP_ON";
/// Keyword used for dynamic Lightmaps.
public const string DYNAMICLIGHTMAP_ON = "DYNAMICLIGHTMAP_ON";
/// Keyword used for Alpha testing.
public const string _ALPHATEST_ON = "_ALPHATEST_ON";
/// Keyword used for combined directional Lightmaps.
public const string DIRLIGHTMAP_COMBINED = "DIRLIGHTMAP_COMBINED";
/// Keyword used for 2x detail mapping.
public const string _DETAIL_MULX2 = "_DETAIL_MULX2";
/// Keyword used for scaled detail mapping.
public const string _DETAIL_SCALED = "_DETAIL_SCALED";
/// Keyword used for Clear Coat.
public const string _CLEARCOAT = "_CLEARCOAT";
/// Keyword used for Clear Coat maps.
public const string _CLEARCOATMAP = "_CLEARCOATMAP";
/// Keyword used for Debug Display.
public const string DEBUG_DISPLAY = "DEBUG_DISPLAY";
/// Keyword used for LOD Crossfade.
public const string LOD_FADE_CROSSFADE = "LOD_FADE_CROSSFADE";
/// Keyword used for LOD Crossfade with ShaderGraph shaders.
public const string USE_UNITY_CROSSFADE = "USE_UNITY_CROSSFADE";
/// Keyword used for Emission.
public const string _EMISSION = "_EMISSION";
/// Keyword used for receiving shadows.
public const string _RECEIVE_SHADOWS_OFF = "_RECEIVE_SHADOWS_OFF";
/// Keyword used for opaque or transparent surface types.
public const string _SURFACE_TYPE_TRANSPARENT = "_SURFACE_TYPE_TRANSPARENT";
/// Keyword used for Alpha premultiply.
public const string _ALPHAPREMULTIPLY_ON = "_ALPHAPREMULTIPLY_ON";
/// Keyword used for Alpha modulate.
public const string _ALPHAMODULATE_ON = "_ALPHAMODULATE_ON";
/// Keyword used for Normal maps.
public const string _NORMALMAP = "_NORMALMAP";
/// Keyword used for editor visualization.
public const string EDITOR_VISUALIZATION = "EDITOR_VISUALIZATION";
/// Keyword used for disabling Texture 2D Arrays.
public const string DisableTexture2DXArray = "DISABLE_TEXTURE2D_X_ARRAY";
/// Keyword used for Single Slice Blits.
public const string BlitSingleSlice = "BLIT_SINGLE_SLICE";
/// Keyword used for rendering a combined mesh for XR.
public const string XROcclusionMeshCombined = "XR_OCCLUSION_MESH_COMBINED";
/// Keyword used for applying scale and bias.
public const string SCREEN_COORD_OVERRIDE = "SCREEN_COORD_OVERRIDE";
/// Keyword used for half size downsampling.
public const string DOWNSAMPLING_SIZE_2 = "DOWNSAMPLING_SIZE_2";
/// Keyword used for quarter size downsampling.
public const string DOWNSAMPLING_SIZE_4 = "DOWNSAMPLING_SIZE_4";
/// Keyword used for eighth size downsampling.
public const string DOWNSAMPLING_SIZE_8 = "DOWNSAMPLING_SIZE_8";
/// Keyword used for sixteenth size downsampling.
public const string DOWNSAMPLING_SIZE_16 = "DOWNSAMPLING_SIZE_16";
/// Keyword used for foveated rendering.
public const string FoveatedRenderingNonUniformRaster = "_FOVEATED_RENDERING_NON_UNIFORM_RASTER";
/// Keyword used for mixed Spherical Harmonic (SH) evaluation in URP Lit shaders.
public const string EVALUATE_SH_MIXED = "EVALUATE_SH_MIXED";
/// Keyword used for vertex Spherical Harmonic (SH) evaluation in URP Lit shaders.
public const string EVALUATE_SH_VERTEX = "EVALUATE_SH_VERTEX";
/// Keyword used for Drawing procedurally.
public const string UseDrawProcedural = "_USE_DRAW_PROCEDURAL";
}
public sealed partial class UniversalRenderPipeline
{
// Holds light direction for directional lights or position for punctual lights.
// When w is set to 1.0, it means it's a punctual light.
static Vector4 k_DefaultLightPosition = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
static Vector4 k_DefaultLightColor = Color.black;
// Default light attenuation is setup in a particular way that it causes
// directional lights to return 1.0 for both distance and angle attenuation
static Vector4 k_DefaultLightAttenuation = new Vector4(0.0f, 1.0f, 0.0f, 1.0f);
static Vector4 k_DefaultLightSpotDirection = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
static Vector4 k_DefaultLightsProbeChannel = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
static List m_ShadowBiasData = new List();
static List m_ShadowResolutionData = new List();
///
/// Checks if a camera is a game camera.
///
/// Camera to check state from.
/// true if given camera is a game camera, false otherwise.
public static bool IsGameCamera(Camera camera)
{
if (camera == null)
throw new ArgumentNullException("camera");
return camera.cameraType == CameraType.Game || camera.cameraType == CameraType.VR;
}
///
/// Checks if a camera is rendering in stereo mode.
///
/// Camera to check state from.
/// Returns true if the given camera is rendering in stereo mode, false otherwise.
[Obsolete("Please use CameraData.xr.enabled instead.", true)]
public static bool IsStereoEnabled(Camera camera)
{
if (camera == null)
throw new ArgumentNullException("camera");
return IsGameCamera(camera) && (camera.stereoTargetEye == StereoTargetEyeMask.Both);
}
///
/// Returns the current render pipeline asset for the current quality setting.
/// If no render pipeline asset is assigned in QualitySettings, then returns the one assigned in GraphicsSettings.
///
public static UniversalRenderPipelineAsset asset
{
get => GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
}
Comparison cameraComparison = (camera1, camera2) => { return (int)camera1.depth - (int)camera2.depth; };
#if UNITY_2021_1_OR_NEWER
void SortCameras(List cameras)
{
if (cameras.Count > 1)
cameras.Sort(cameraComparison);
}
#else
void SortCameras(Camera[] cameras)
{
if (cameras.Length > 1)
Array.Sort(cameras, cameraComparison);
}
#endif
internal static GraphicsFormat MakeRenderTextureGraphicsFormat(bool isHdrEnabled, HDRColorBufferPrecision requestHDRColorBufferPrecision, bool needsAlpha)
{
if (isHdrEnabled)
{
// TODO: we need a proper format scoring system. Score formats, sort, pick first or pick first supported (if not in score).
if (!needsAlpha && requestHDRColorBufferPrecision != HDRColorBufferPrecision._64Bits && RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.B10G11R11_UFloatPack32, FormatUsage.Linear | FormatUsage.Render))
return GraphicsFormat.B10G11R11_UFloatPack32;
if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat, FormatUsage.Linear | FormatUsage.Render))
return GraphicsFormat.R16G16B16A16_SFloat;
return SystemInfo.GetGraphicsFormat(DefaultFormat.HDR); // This might actually be a LDR format on old devices.
}
return SystemInfo.GetGraphicsFormat(DefaultFormat.LDR);
}
// Returns a UNORM based render texture format
// When supported by the device, this function will prefer formats with higher precision, but the same bit-depth
// NOTE: This function does not guarantee that the returned format will contain an alpha channel.
internal static GraphicsFormat MakeUnormRenderTextureGraphicsFormat()
{
if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.A2B10G10R10_UNormPack32, FormatUsage.Linear | FormatUsage.Render))
return GraphicsFormat.A2B10G10R10_UNormPack32;
else
return GraphicsFormat.R8G8B8A8_UNorm;
}
static RenderTextureDescriptor CreateRenderTextureDescriptor(Camera camera, float renderScale,
bool isHdrEnabled, HDRColorBufferPrecision requestHDRColorBufferPrecision, int msaaSamples, bool needsAlpha, bool requiresOpaqueTexture)
{
int scaledWidth = (int)((float)camera.pixelWidth * renderScale);
int scaledHeight = (int)((float)camera.pixelHeight * renderScale);
RenderTextureDescriptor desc;
if (camera.targetTexture == null)
{
desc = new RenderTextureDescriptor(camera.pixelWidth, camera.pixelHeight);
desc.width = scaledWidth;
desc.height = scaledHeight;
desc.graphicsFormat = MakeRenderTextureGraphicsFormat(isHdrEnabled, requestHDRColorBufferPrecision, needsAlpha);
desc.depthBufferBits = 32;
desc.msaaSamples = msaaSamples;
desc.sRGB = (QualitySettings.activeColorSpace == ColorSpace.Linear);
}
else
{
desc = camera.targetTexture.descriptor;
desc.msaaSamples = msaaSamples;
desc.width = scaledWidth;
desc.height = scaledHeight;
if (camera.cameraType == CameraType.SceneView && !isHdrEnabled)
{
desc.graphicsFormat = SystemInfo.GetGraphicsFormat(DefaultFormat.LDR);
}
// SystemInfo.SupportsRenderTextureFormat(camera.targetTexture.descriptor.colorFormat)
// will assert on R8_SINT since it isn't a valid value of RenderTextureFormat.
// If this is fixed then we can implement debug statement to the user explaining why some
// RenderTextureFormats available resolves in a black render texture when no warning or error
// is given.
}
// Make sure dimension is non zero
desc.width = Mathf.Max(1, desc.width);
desc.height = Mathf.Max(1, desc.height);
desc.enableRandomWrite = false;
desc.bindMS = false;
desc.useDynamicScale = camera.allowDynamicResolution;
// The way RenderTextures handle MSAA fallback when an unsupported sample count of 2 is requested (falling back to numSamples = 1), differs fom the way
// the fallback is handled when setting up the Vulkan swapchain (rounding up numSamples to 4, if supported). This caused an issue on Mali GPUs which don't support
// 2x MSAA.
// The following code makes sure that on Vulkan the MSAA unsupported fallback behaviour is consistent between RenderTextures and Swapchain.
// TODO: we should review how all backends handle MSAA fallbacks and move these implementation details in engine code.
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)
{
// if the requested number of samples is 2, and the supported value is 1x, it means that 2x is unsupported on this GPU.
// Then we bump up the requested value to 4.
if (desc.msaaSamples == 2 && SystemInfo.GetRenderTextureSupportedMSAASampleCount(desc) == 1)
desc.msaaSamples = 4;
}
// check that the requested MSAA samples count is supported by the current platform. If it's not supported,
// replace the requested desc.msaaSamples value with the actual value the engine falls back to
desc.msaaSamples = SystemInfo.GetRenderTextureSupportedMSAASampleCount(desc);
// if the target platform doesn't support storing multisampled RTs and we are doing any offscreen passes, using a Load load action on the subsequent passes
// will result in loading Resolved data, which on some platforms is discarded, resulting in losing the results of the previous passes.
// As a workaround we disable MSAA to make sure that the results of previous passes are stored. (fix for Case 1247423).
if (!SystemInfo.supportsStoreAndResolveAction)
desc.msaaSamples = 1;
return desc;
}
private static Lightmapping.RequestLightsDelegate lightsDelegate = (Light[] requests, NativeArray lightsOutput) =>
{
LightDataGI lightData = new LightDataGI();
#if UNITY_EDITOR
// Always extract lights in the Editor.
for (int i = 0; i < requests.Length; i++)
{
Light light = requests[i];
var additionalLightData = light.GetUniversalAdditionalLightData();
LightmapperUtils.Extract(light, out Cookie cookie);
switch (light.type)
{
case LightType.Directional:
DirectionalLight directionalLight = new DirectionalLight();
LightmapperUtils.Extract(light, ref directionalLight);
if (light.cookie != null)
{
// Size == 1 / Scale
cookie.sizes = additionalLightData.lightCookieSize;
// Offset, Map cookie UV offset to light position on along local axes.
if (additionalLightData.lightCookieOffset != Vector2.zero)
{
var r = light.transform.right * additionalLightData.lightCookieOffset.x;
var u = light.transform.up * additionalLightData.lightCookieOffset.y;
var offset = r + u;
directionalLight.position += offset;
}
}
lightData.Init(ref directionalLight, ref cookie);
break;
case LightType.Point:
PointLight pointLight = new PointLight();
LightmapperUtils.Extract(light, ref pointLight);
lightData.Init(ref pointLight, ref cookie);
break;
case LightType.Spot:
SpotLight spotLight = new SpotLight();
LightmapperUtils.Extract(light, ref spotLight);
spotLight.innerConeAngle = light.innerSpotAngle * Mathf.Deg2Rad;
spotLight.angularFalloff = AngularFalloffType.AnalyticAndInnerAngle;
lightData.Init(ref spotLight, ref cookie);
break;
case LightType.Area:
RectangleLight rectangleLight = new RectangleLight();
LightmapperUtils.Extract(light, ref rectangleLight);
rectangleLight.mode = LightMode.Baked;
lightData.Init(ref rectangleLight);
break;
case LightType.Disc:
DiscLight discLight = new DiscLight();
LightmapperUtils.Extract(light, ref discLight);
discLight.mode = LightMode.Baked;
lightData.Init(ref discLight);
break;
default:
lightData.InitNoBake(light.GetInstanceID());
break;
}
lightData.falloff = FalloffType.InverseSquared;
lightsOutput[i] = lightData;
}
#else
// If Enlighten realtime GI isn't active, we don't extract lights.
if (SupportedRenderingFeatures.active.enlighten == false || ((int)SupportedRenderingFeatures.active.lightmapBakeTypes | (int)LightmapBakeType.Realtime) == 0)
{
for (int i = 0; i < requests.Length; i++)
{
Light light = requests[i];
lightData.InitNoBake(light.GetInstanceID());
lightsOutput[i] = lightData;
}
}
else
{
for (int i = 0; i < requests.Length; i++)
{
Light light = requests[i];
switch (light.type)
{
case LightType.Directional:
DirectionalLight directionalLight = new DirectionalLight();
LightmapperUtils.Extract(light, ref directionalLight);
lightData.Init(ref directionalLight);
break;
case LightType.Point:
PointLight pointLight = new PointLight();
LightmapperUtils.Extract(light, ref pointLight);
lightData.Init(ref pointLight);
break;
case LightType.Spot:
SpotLight spotLight = new SpotLight();
LightmapperUtils.Extract(light, ref spotLight);
spotLight.innerConeAngle = light.innerSpotAngle * Mathf.Deg2Rad;
spotLight.angularFalloff = AngularFalloffType.AnalyticAndInnerAngle;
lightData.Init(ref spotLight);
break;
case LightType.Area:
// Rect area light is baked only in URP.
lightData.InitNoBake(light.GetInstanceID());
break;
case LightType.Disc:
// Disc light is baked only.
lightData.InitNoBake(light.GetInstanceID());
break;
default:
lightData.InitNoBake(light.GetInstanceID());
break;
}
lightData.falloff = FalloffType.InverseSquared;
lightsOutput[i] = lightData;
}
}
#endif
};
// Called from DeferredLights.cs too
///
/// Calculates the attenuation for a given light and also direction for spot lights.
///
/// The type of light.
/// The range of the light.
/// The local to world light matrix.
/// The spotlight angle.
/// The spotlight inner angle.
/// The light attenuation.
/// The spot light direction.
public static void GetLightAttenuationAndSpotDirection(
LightType lightType, float lightRange, Matrix4x4 lightLocalToWorldMatrix,
float spotAngle, float? innerSpotAngle,
out Vector4 lightAttenuation, out Vector4 lightSpotDir)
{
// Default is directional
lightAttenuation = k_DefaultLightAttenuation;
lightSpotDir = k_DefaultLightSpotDirection;
if (lightType != LightType.Directional)
{
GetPunctualLightDistanceAttenuation(lightRange, ref lightAttenuation);
if (lightType == LightType.Spot)
{
GetSpotDirection(ref lightLocalToWorldMatrix, out lightSpotDir);
GetSpotAngleAttenuation(spotAngle, innerSpotAngle, ref lightAttenuation);
}
}
}
internal static void GetPunctualLightDistanceAttenuation(float lightRange, ref Vector4 lightAttenuation)
{
// Light attenuation in universal matches the unity vanilla one (HINT_NICE_QUALITY).
// attenuation = 1.0 / distanceToLightSqr
// The smoothing factor makes sure that the light intensity is zero at the light range limit.
// (We used to offer two different smoothing factors.)
// The current smoothing factor matches the one used in the Unity lightmapper.
// smoothFactor = (1.0 - saturate((distanceSqr * 1.0 / lightRangeSqr)^2))^2
float lightRangeSqr = lightRange * lightRange;
float fadeStartDistanceSqr = 0.8f * 0.8f * lightRangeSqr;
float fadeRangeSqr = (fadeStartDistanceSqr - lightRangeSqr);
float lightRangeSqrOverFadeRangeSqr = -lightRangeSqr / fadeRangeSqr;
float oneOverLightRangeSqr = 1.0f / Mathf.Max(0.0001f, lightRangeSqr);
// On all devices: Use the smoothing factor that matches the GI.
lightAttenuation.x = oneOverLightRangeSqr;
lightAttenuation.y = lightRangeSqrOverFadeRangeSqr;
}
internal static void GetSpotAngleAttenuation(
float spotAngle, float? innerSpotAngle,
ref Vector4 lightAttenuation)
{
// Spot Attenuation with a linear falloff can be defined as
// (SdotL - cosOuterAngle) / (cosInnerAngle - cosOuterAngle)
// This can be rewritten as
// invAngleRange = 1.0 / (cosInnerAngle - cosOuterAngle)
// SdotL * invAngleRange + (-cosOuterAngle * invAngleRange)
// If we precompute the terms in a MAD instruction
float cosOuterAngle = Mathf.Cos(Mathf.Deg2Rad * spotAngle * 0.5f);
// We need to do a null check for particle lights
// This should be changed in the future
// Particle lights will use an inline function
float cosInnerAngle;
if (innerSpotAngle.HasValue)
cosInnerAngle = Mathf.Cos(innerSpotAngle.Value * Mathf.Deg2Rad * 0.5f);
else
cosInnerAngle = Mathf.Cos((2.0f * Mathf.Atan(Mathf.Tan(spotAngle * 0.5f * Mathf.Deg2Rad) * (64.0f - 18.0f) / 64.0f)) * 0.5f);
float smoothAngleRange = Mathf.Max(0.001f, cosInnerAngle - cosOuterAngle);
float invAngleRange = 1.0f / smoothAngleRange;
float add = -cosOuterAngle * invAngleRange;
lightAttenuation.z = invAngleRange;
lightAttenuation.w = add;
}
internal static void GetSpotDirection(ref Matrix4x4 lightLocalToWorldMatrix, out Vector4 lightSpotDir)
{
Vector4 dir = lightLocalToWorldMatrix.GetColumn(2);
lightSpotDir = new Vector4(-dir.x, -dir.y, -dir.z, 0.0f);
}
///
/// Initializes common light constants.
///
/// List of lights to iterate.
/// The index of the light.
/// The position of the light.
/// The color of the light.
/// The attenuation of the light.
/// The direction of the light.
/// The occlusion probe channel for the light.
public static void InitializeLightConstants_Common(NativeArray lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir, out Vector4 lightOcclusionProbeChannel)
{
lightPos = k_DefaultLightPosition;
lightColor = k_DefaultLightColor;
lightOcclusionProbeChannel = k_DefaultLightsProbeChannel;
lightAttenuation = k_DefaultLightAttenuation; // Directional by default.
lightSpotDir = k_DefaultLightSpotDirection;
// When no lights are visible, main light will be set to -1.
// In this case we initialize it to default values and return
if (lightIndex < 0)
return;
// Avoid memcpys. Pass by ref and locals for multiple uses.
ref VisibleLight lightData = ref lights.UnsafeElementAtMutable(lightIndex);
var light = lightData.light;
var lightLocalToWorld = lightData.localToWorldMatrix;
var lightType = lightData.lightType;
if (lightType == LightType.Directional)
{
Vector4 dir = -lightLocalToWorld.GetColumn(2);
lightPos = new Vector4(dir.x, dir.y, dir.z, 0.0f);
}
else
{
Vector4 pos = lightLocalToWorld.GetColumn(3);
lightPos = new Vector4(pos.x, pos.y, pos.z, 1.0f);
GetPunctualLightDistanceAttenuation(lightData.range, ref lightAttenuation);
if (lightType == LightType.Spot)
{
GetSpotAngleAttenuation(lightData.spotAngle, light?.innerSpotAngle, ref lightAttenuation);
GetSpotDirection(ref lightLocalToWorld, out lightSpotDir);
}
}
// VisibleLight.finalColor already returns color in active color space
lightColor = lightData.finalColor;
if (light != null && light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed &&
0 <= light.bakingOutput.occlusionMaskChannel &&
light.bakingOutput.occlusionMaskChannel < 4)
{
lightOcclusionProbeChannel[light.bakingOutput.occlusionMaskChannel] = 1.0f;
}
}
}
internal enum URPProfileId
{
// CPU
UniversalRenderTotal,
UpdateVolumeFramework,
RenderCameraStack,
// GPU
AdditionalLightsShadow,
ColorGradingLUT,
CopyColor,
CopyDepth,
DepthNormalPrepass,
DepthPrepass,
UpdateReflectionProbeAtlas,
// DrawObjectsPass
DrawOpaqueObjects,
DrawTransparentObjects,
DrawScreenSpaceUI,
// RenderObjectsPass
//RenderObjects,
LightCookies,
MainLightShadow,
ResolveShadows,
SSAO,
// PostProcessPass
StopNaNs,
SMAA,
GaussianDepthOfField,
BokehDepthOfField,
TemporalAA,
MotionBlur,
PaniniProjection,
UberPostProcess,
Bloom,
LensFlareDataDrivenComputeOcclusion,
LensFlareDataDriven,
MotionVectors,
DrawFullscreen,
FinalBlit
}
// Internal class to detect and cache runtime platform information.
// TODO: refine the logic to provide platform abstraction. Eg, we should devide platforms based on capabilities and perf budget.
// TODO: isXRMobile is a bad catagory. Alignment and refactor needed.
// TODO: Compress all the query data into "isXRMobile" style bools and enums.
internal static class PlatformAutoDetect
{
///
/// Detect and cache runtime platform information. This function should only be called once when creating the URP.
///
internal static void Initialize()
{
bool isRunningXRMobile = false;
#if ENABLE_VR && ENABLE_VR_MODULE
#if PLATFORM_WINRT || PLATFORM_ANDROID
isRunningXRMobile = IsRunningXRMobile();
#endif
#endif
isXRMobile = isRunningXRMobile;
}
#if ENABLE_VR && ENABLE_VR_MODULE
#if PLATFORM_WINRT || PLATFORM_ANDROID
// XR mobile platforms are not treated as dedicated mobile platforms in Core. Handle them specially here. (Quest and HL).
private static List displaySubsystemList = new List();
private static bool IsRunningXRMobile()
{
var platform = Application.platform;
if (platform == RuntimePlatform.WSAPlayerX86 || platform == RuntimePlatform.WSAPlayerARM || platform == RuntimePlatform.WSAPlayerX64 || platform == RuntimePlatform.Android)
{
XR.XRDisplaySubsystem display = null;
SubsystemManager.GetInstances(displaySubsystemList);
if (displaySubsystemList.Count > 0)
display = displaySubsystemList[0];
if (display != null)
return true;
}
return false;
}
#endif
#endif
///
/// If true, the runtime platform is an XR mobile platform.
///
static internal bool isXRMobile { get; private set; } = false;
}
}