/// <summary> /// TextureDesc constructor for a texture using a functor for scaling /// </summary> /// <param name="func">Function used to determnine the texture size</param> /// <param name="dynamicResolution">Use dynamic resolution</param> /// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param> public TextureDesc(ScaleFunc func, bool dynamicResolution = false, bool xrReady = false) : this() { // Size related init sizeMode = TextureSizeMode.Functor; this.func = func; // Important default values not handled by zero construction in this() msaaSamples = MSAASamples.None; dimension = TextureDimension.Tex2D; InitDefaultValues(dynamicResolution, xrReady); }
/// <summary> /// TextureDesc constructor for a texture using explicit size /// </summary> /// <param name="width">Texture width</param> /// <param name="height">Texture height</param> /// <param name="dynamicResolution">Use dynamic resolution</param> /// <param name="xrReady">Set this to true if the Texture is a render texture in an XR setting.</param> public TextureDesc(int width, int height, bool dynamicResolution = false, bool xrReady = false) : this() { // Size related init sizeMode = TextureSizeMode.Explicit; this.width = width; this.height = height; // Important default values not handled by zero construction in this() msaaSamples = MSAASamples.None; InitDefaultValues(dynamicResolution, xrReady); }
/// <summary> /// Initialize the RTHandle system. /// </summary> /// <param name="width">Initial reference rendering width.</param> /// <param name="height">Initial reference rendering height.</param> /// <param name="scaledRTsupportsMSAA">Set to true if automatically scaled RTHandles should support MSAA</param> /// <param name="scaledRTMSAASamples">Number of MSAA samples for automatically scaled RTHandles.</param> public void Initialize(int width, int height, bool scaledRTsupportsMSAA, MSAASamples scaledRTMSAASamples) { Debug.Assert(m_AutoSizedRTs.Count == 0, "RTHandle.Initialize should only be called once before allocating any Render Texture. This may be caused by an unreleased RTHandle resource."); m_MaxWidths = width; m_MaxHeights = height; m_ScaledRTSupportsMSAA = scaledRTsupportsMSAA; m_ScaledRTCurrentMSAASamples = scaledRTMSAASamples; m_HardwareDynamicResRequested = DynamicResolutionHandler.instance.RequestsHardwareDynamicResolution(); }
public static void SetReferenceSize( int width, int height, MSAASamples msaaSamples ) { s_DefaultInstance.SetReferenceSize( width, height, msaaSamples ); }
// Call this once to set the initial size and allow msaa targets or not. public void Initialize(int width, int height, bool scaledRTsupportsMSAA, MSAASamples scaledRTMSAASamples) { Debug.Assert(m_AutoSizedRTs.Count == 0, "RTHandle.Initialize should only be called once before allocating any Render Texture."); m_MaxWidths = width; m_MaxHeights = height; m_ScaledRTSupportsMSAA = scaledRTsupportsMSAA; m_ScaledRTCurrentMSAASamples = scaledRTMSAASamples; m_HardwareDynamicResRequested = false; }
public void ResetReferenceSize(int width, int height, MSAASamples msaaSamples) { width = Mathf.Max(width, 1); height = Mathf.Max(height, 1); bool sizeChanged = width > GetMaxWidth() || height > GetMaxHeight(); bool msaaSamplesChanged = (msaaSamples != m_ScaledRTCurrentMSAASamples); if (sizeChanged || msaaSamplesChanged) { Resize(width, height, msaaSamples, sizeChanged, msaaSamplesChanged); } }
// Call this once to set the initial size and allow msaa targets or not. public static void Initialize(int width, int height, bool scaledRTsupportsMSAA, MSAASamples scaledRTMSAASamples) { Debug.Assert(s_AutoSizedRTs.Count == 0, "RTHandle.Initialize should only be called once before allocating any Render Texture."); for (int i = 0; i < (int)RTCategory.Count; ++i) { s_MaxWidths[i] = width; s_MaxHeights[i] = height; } s_ScaledRTSupportsMSAA = scaledRTsupportsMSAA; s_ScaledRTCurrentMSAASamples = scaledRTMSAASamples; }
// // You can provide your own scaling function for advanced scaling schemes (e.g. scaling to // the next POT). The function takes a Vec2 as parameter that holds max width & height // values for the current manager context and returns a Vec2 of the final size in pixels. // // var rth = Alloc( // size => new Vector2Int(size.x / 2, size.y), // [...] // ); // /// <summary> /// Allocate a new automatically sized RTHandle. /// </summary> /// <param name="scaleFunc">Function used for the RTHandle size computation.</param> /// <param name="slices">Number of slices of the RTHandle.</param> /// <param name="depthBufferBits">Bit depths of a depth buffer.</param> /// <param name="colorFormat">GraphicsFormat of a color buffer.</param> /// <param name="filterMode">Filtering mode of the RTHandle.</param> /// <param name="wrapMode">Addressing mode of the RTHandle.</param> /// <param name="dimension">Texture dimension of the RTHandle.</param> /// <param name="enableRandomWrite">Set to true to enable UAV random read writes on the texture.</param> /// <param name="useMipMap">Set to true if the texture should have mipmaps.</param> /// <param name="autoGenerateMips">Set to true to automatically generate mipmaps.</param> /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param> /// <param name="anisoLevel">Anisotropic filtering level.</param> /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param> /// <param name="msaaSamples">Number of MSAA samples.</param> /// <param name="bindTextureMS">Set to true if the texture needs to be bound as a multisampled texture in the shader.</param> /// <param name="useDynamicScale">Set to true to use hardware dynamic scaling.</param> /// <param name="memoryless">Use this property to set the render texture memoryless modes.</param> /// <param name="name">Name of the RTHandle.</param> /// <returns>A new RTHandle.</returns> public RTHandle Alloc( ScaleFunc scaleFunc, int slices = 1, DepthBits depthBufferBits = DepthBits.None, GraphicsFormat colorFormat = GraphicsFormat.R8G8B8A8_SRGB, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, bool enableRandomWrite = false, bool useMipMap = false, bool autoGenerateMips = true, bool isShadowMap = false, int anisoLevel = 1, float mipMapBias = 0f, MSAASamples msaaSamples = MSAASamples.None, bool bindTextureMS = false, bool useDynamicScale = false, RenderTextureMemoryless memoryless = RenderTextureMemoryless.None, string name = "" ) { var scaleFactor = scaleFunc(new Vector2Int(GetMaxWidth(), GetMaxHeight())); int width = Mathf.Max(scaleFactor.x, 1); int height = Mathf.Max(scaleFactor.y, 1); var rth = AllocAutoSizedRenderTexture(width, height, slices, depthBufferBits, colorFormat, filterMode, wrapMode, dimension, enableRandomWrite, useMipMap, autoGenerateMips, isShadowMap, anisoLevel, mipMapBias, msaaSamples, bindTextureMS, useDynamicScale, memoryless, name ); rth.referenceSize = new Vector2Int(width, height); rth.scaleFunc = scaleFunc; return(rth); }
void Resize(int width, int height, MSAASamples msaaSamples, bool sizeChanged, bool msaaSampleChanged) { m_MaxWidths = Math.Max(width, m_MaxWidths); m_MaxHeights = Math.Max(height, m_MaxHeights); m_ScaledRTCurrentMSAASamples = msaaSamples; var maxSize = new Vector2Int(m_MaxWidths, m_MaxHeights); Array.Resize(ref m_AutoSizedRTsArray, m_AutoSizedRTs.Count); m_AutoSizedRTs.CopyTo(m_AutoSizedRTsArray); for (int i = 0, c = m_AutoSizedRTsArray.Length; i < c; ++i) { // Grab the RT Handle var rth = m_AutoSizedRTsArray[i]; // If we are only processing MSAA sample count change, make sure this RT is an MSAA one if (!sizeChanged && msaaSampleChanged && !rth.m_EnableMSAA) { continue; } // Force its new reference size rth.referenceSize = maxSize; // Grab the render texture var renderTexture = rth.m_RT; // Free the previous version renderTexture.Release(); // Get the scaled size var scaledSize = rth.GetScaledSize(maxSize); renderTexture.width = Mathf.Max(scaledSize.x, 1); renderTexture.height = Mathf.Max(scaledSize.y, 1); // If this is a msaa texture, make sure to update its msaa count if (rth.m_EnableMSAA) { renderTexture.antiAliasing = (int)m_ScaledRTCurrentMSAASamples; } // Regenerate the name renderTexture.name = CoreUtils.GetRenderTargetAutoName(renderTexture.width, renderTexture.height, renderTexture.volumeDepth, renderTexture.format, rth.m_Name, mips: renderTexture.useMipMap, enableMSAA: rth.m_EnableMSAA, msaaSamples: m_ScaledRTCurrentMSAASamples); // Create the render texture renderTexture.Create(); } }
public static void Initialize( int width, int height, bool scaledRTsupportsMSAA, MSAASamples scaledRTMSAASamples ) { s_DefaultInstance.Initialize( width, height, scaledRTsupportsMSAA, scaledRTMSAASamples ); }
// // You can provide your own scaling function for advanced scaling schemes (e.g. scaling to // the next POT). The function takes a Vec2 as parameter that holds max width & height // values for the current manager context and returns a Vec2 of the final size in pixels. // // var rth = Alloc( // size => new Vector2Int(size.x / 2, size.y), // [...] // ); // public static RTHandle Alloc( ScaleFunc scaleFunc, DepthBits depthBufferBits = DepthBits.None, RenderTextureFormat colorFormat = RenderTextureFormat.Default, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, bool sRGB = true, bool enableRandomWrite = false, bool useMipMap = false, bool autoGenerateMips = true, int anisoLevel = 1, float mipMapBias = 0f, MSAASamples msaaSamples = MSAASamples.None, bool bindTextureMS = false, bool useDynamicScale = false, VRTextureUsage vrUsage = VRTextureUsage.None, RenderTextureMemoryless memoryless = RenderTextureMemoryless.None ) { var scaleFactor = scaleFunc(new Vector2Int(s_MaxWidth, s_MaxHeight)); int width = Mathf.Max(scaleFactor.x, 1); int height = Mathf.Max(scaleFactor.y, 1); var rth = Alloc(width, height, 1, depthBufferBits, colorFormat, filterMode, wrapMode, dimension, sRGB, enableRandomWrite, useMipMap, autoGenerateMips, anisoLevel, mipMapBias, msaaSamples, bindTextureMS, useDynamicScale, vrUsage, memoryless ); rth.scaleFunc = scaleFunc; s_AutoSizedRTs.Add(rth); return(rth); }
public static void ResetReferenceSize(int width, int height, bool msaa, MSAASamples msaaSamples) { // Technically, the enum could be passed as argument directly but let's not pollute public API with unnecessary complexity for now. RTCategory category = msaa ? RTCategory.MSAA : RTCategory.Regular; width = Mathf.Max(width, 1); height = Mathf.Max(height, 1); bool msaaSamplesChanged = msaa && (msaaSamples != s_ScaledRTCurrentMSAASamples); if (width != GetMaxWidth(category) || height != GetMaxHeight(category) || msaaSamplesChanged) { Resize(width, height, category, msaaSamples); } }
public static RTHandleSystem.RTHandle Alloc( int width, int height, int slices = 1, DepthBits depthBufferBits = DepthBits.None, GraphicsFormat colorFormat = GraphicsFormat.R8G8B8A8_SRGB, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, bool enableRandomWrite = false, bool useMipMap = false, bool autoGenerateMips = true, bool isShadowMap = false, int anisoLevel = 1, float mipMapBias = 0, MSAASamples msaaSamples = MSAASamples.None, bool bindTextureMS = false, bool useDynamicScale = false, bool xrInstancing = false, RenderTextureMemoryless memoryless = RenderTextureMemoryless.None, string name = "" ) { return(s_DefaultInstance.Alloc( width, height, slices, depthBufferBits, colorFormat, filterMode, wrapMode, dimension, enableRandomWrite, useMipMap, autoGenerateMips, isShadowMap, anisoLevel, mipMapBias, msaaSamples, bindTextureMS, useDynamicScale, xrInstancing, memoryless, name )); }
public static RTHandle Alloc( int width, int height, int slices = 1, DepthBits depthBufferBits = DepthBits.None, RenderTextureFormat colorFormat = RenderTextureFormat.Default, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, bool sRGB = true, bool enableRandomWrite = false, bool useMipMap = false, bool autoGenerateMips = true, int anisoLevel = 1, float mipMapBias = 0f, MSAASamples msaaSamples = MSAASamples.None, bool bindTextureMS = false, bool useDynamicScale = false, VRTextureUsage vrUsage = VRTextureUsage.None, RenderTextureMemoryless memoryless = RenderTextureMemoryless.None ) { var rt = new RenderTexture(width, height, (int)depthBufferBits, colorFormat, sRGB ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = enableRandomWrite, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = (int)msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = useDynamicScale, vrUsage = vrUsage, memorylessMode = memoryless }; rt.Create(); return(new RTHandle(rt)); }
/// <summary> /// Sets the reference rendering size for subsequent rendering for the RTHandle System /// </summary> /// <param name="width">Reference rendering width for subsequent rendering.</param> /// <param name="height">Reference rendering height for subsequent rendering.</param> /// <param name="msaaSamples">Number of MSAA samples for multisampled textures for subsequent rendering.</param> /// <param name="reset">If set to true, the new width and height will override the old values even if they are not bigger.</param> public void SetReferenceSize(int width, int height, MSAASamples msaaSamples, bool reset) { m_RTHandleProperties.previousViewportSize = m_RTHandleProperties.currentViewportSize; m_RTHandleProperties.previousRenderTargetSize = m_RTHandleProperties.currentRenderTargetSize; Vector2 lastFrameMaxSize = new Vector2(GetMaxWidth(), GetMaxHeight()); width = Mathf.Max(width, 1); height = Mathf.Max(height, 1); bool sizeChanged = width > GetMaxWidth() || height > GetMaxHeight() || reset; bool msaaSamplesChanged = (msaaSamples != m_ScaledRTCurrentMSAASamples); if (sizeChanged || msaaSamplesChanged) { Resize(width, height, msaaSamples, sizeChanged, msaaSamplesChanged); } m_RTHandleProperties.currentViewportSize = new Vector2Int(width, height); m_RTHandleProperties.currentRenderTargetSize = new Vector2Int(GetMaxWidth(), GetMaxHeight()); // If the currentViewportSize is 0, it mean we are the first frame of rendering (can happen when doing domain reload for example or for reflection probe) // in this case the scalePrevious below could be invalided. But some effect rely on having a correct value like TAA with the history buffer for the first frame. // to work around this, when we detect that size is 0, we setup previous size to current size. if (m_RTHandleProperties.previousViewportSize.x == 0) { m_RTHandleProperties.previousViewportSize = m_RTHandleProperties.currentViewportSize; m_RTHandleProperties.previousRenderTargetSize = m_RTHandleProperties.currentRenderTargetSize; lastFrameMaxSize = new Vector2(GetMaxWidth(), GetMaxHeight()); } if (DynamicResolutionHandler.instance.HardwareDynamicResIsEnabled() && m_HardwareDynamicResRequested) { float xScale = (float)DynamicResolutionHandler.instance.finalViewport.x / GetMaxWidth(); float yScale = (float)DynamicResolutionHandler.instance.finalViewport.y / GetMaxHeight(); m_RTHandleProperties.rtHandleScale = new Vector4(xScale, yScale, m_RTHandleProperties.rtHandleScale.x, m_RTHandleProperties.rtHandleScale.y); } else { Vector2 maxSize = new Vector2(GetMaxWidth(), GetMaxHeight()); Vector2 scaleCurrent = m_RTHandleProperties.currentViewportSize / maxSize; Vector2 scalePrevious = m_RTHandleProperties.previousViewportSize / lastFrameMaxSize; m_RTHandleProperties.rtHandleScale = new Vector4(scaleCurrent.x, scaleCurrent.y, scalePrevious.x, scalePrevious.y); } }
public static int SampleCountToPassIndex(MSAASamples samples) { switch (samples) { case MSAASamples.None: return(0); case MSAASamples.MSAA2x: return(1); case MSAASamples.MSAA4x: return(2); case MSAASamples.MSAA8x: return(3); } ; return(0); }
/// <summary> /// Initialize the RTHandle system. /// </summary> /// <param name="width">Initial reference rendering width.</param> /// <param name="height">Initial reference rendering height.</param> /// <param name="scaledRTsupportsMSAA">Set to true if automatically scaled RTHandles should support MSAA</param> /// <param name="scaledRTMSAASamples">Number of MSAA samples for automatically scaled RTHandles.</param> public void Initialize(int width, int height, bool scaledRTsupportsMSAA, MSAASamples scaledRTMSAASamples) { if (m_AutoSizedRTs.Count != 0) { string leakingResources = "Unreleased RTHandles:"; foreach (var rt in m_AutoSizedRTs) { leakingResources = string.Format("{0}\n {1}", leakingResources, rt.name); } Debug.LogError(string.Format("RTHandle.Initialize should only be called once before allocating any Render Texture. This may be caused by an unreleased RTHandle resource.\n{0}\n", leakingResources)); } m_MaxWidths = width; m_MaxHeights = height; m_ScaledRTSupportsMSAA = scaledRTsupportsMSAA; m_ScaledRTCurrentMSAASamples = scaledRTMSAASamples; m_HardwareDynamicResRequested = DynamicResolutionHandler.instance.RequestsHardwareDynamicResolution(); }
public static TextureHandle CreateVTFeedbackBuffer(RenderGraph renderGraph, MSAASamples msaaSamples) { bool msaa = msaaSamples != MSAASamples.None; #if UNITY_2020_2_OR_NEWER FastMemoryDesc colorFastMemDesc; colorFastMemDesc.inFastMemory = true; colorFastMemDesc.residencyFraction = 1.0f; colorFastMemDesc.flags = FastMemoryFlags.SpillTop; #endif return(renderGraph.CreateTexture( new TextureDesc(Vector2.one, true, true) { colorFormat = GetFeedbackBufferFormat(), enableRandomWrite = !msaa, bindTextureMS = msaa, msaaSamples = msaa ? msaaSamples : MSAASamples.None, clearBuffer = true, clearColor = Color.white, name = msaa ? "VTFeedbackMSAA" : "VTFeedback", fallBackToBlackTexture = true #if UNITY_2020_2_OR_NEWER , fastMemoryDesc = colorFastMemDesc #endif })); }
public void SetReferenceSize(int width, int height, bool msaa, MSAASamples msaaSamples) { // Technically, the enum could be passed as argument directly but let's not pollute public API with unnecessary complexity for now. RTCategory category = msaa ? RTCategory.MSAA : RTCategory.Regular; width = Mathf.Max(width, 1); height = Mathf.Max(height, 1); bool msaaSamplesChanged = msaa && (msaaSamples != m_ScaledRTCurrentMSAASamples); if (width > GetMaxWidth(category) || height > GetMaxHeight(category) || msaaSamplesChanged) { // The regular rendertargets should always be resized Resize(width, height, RTCategory.Regular, msaaSamples); // The MSAA render targets should only be resized if msaa if required (in addition to the regular ones given that both are used) if (msaa) { Resize(width, height, RTCategory.MSAA, msaaSamples); } } }
void Resize(int width, int height, RTCategory category, MSAASamples msaaSamples) { m_MaxWidths[(int)category] = width; m_MaxHeights[(int)category] = height; m_ScaledRTCurrentMSAASamples = msaaSamples; var maxSize = new Vector2Int(width, height); m_ScaledRTCurrentCategory = category; Array.Resize(ref m_AutoSizedRTsArray, m_AutoSizedRTs.Count); m_AutoSizedRTs.CopyTo(m_AutoSizedRTsArray); for (int i = 0, c = m_AutoSizedRTsArray.Length; i < c; ++i) { var rth = m_AutoSizedRTsArray[i]; rth.referenceSize = maxSize; var rt = rth.m_RTs[(int)category]; // This can happen if you create a RTH for MSAA. By default we only create the MSAA version of the target. // Missing version will be created when needed in the getter. if (rt != null) { rt.Release(); var scaledSize = rth.GetScaledSize(maxSize); rt.width = Mathf.Max(scaledSize.x, 1); rt.height = Mathf.Max(scaledSize.y, 1); if (category == RTCategory.MSAA) { rt.antiAliasing = (int)m_ScaledRTCurrentMSAASamples; } rt.name = CoreUtils.GetRenderTargetAutoName(rt.width, rt.height, rt.volumeDepth, rt.format, rth.m_Name, mips: rt.useMipMap, enableMSAA: category == RTCategory.MSAA, msaaSamples: m_ScaledRTCurrentMSAASamples); rt.Create(); } } }
/// <summary> /// Allocate a new fixed sized RTHandle. /// </summary> /// <param name="width">With of the RTHandle.</param> /// <param name="height">Heigh of the RTHandle.</param> /// <param name="slices">Number of slices of the RTHandle.</param> /// <param name="depthBufferBits">Bit depths of a depth buffer.</param> /// <param name="colorFormat">GraphicsFormat of a color buffer.</param> /// <param name="filterMode">Filtering mode of the RTHandle.</param> /// <param name="wrapMode">Addressing mode of the RTHandle.</param> /// <param name="dimension">Texture dimension of the RTHandle.</param> /// <param name="enableRandomWrite">Set to true to enable UAV random read writes on the texture.</param> /// <param name="useMipMap">Set to true if the texture should have mipmaps.</param> /// <param name="autoGenerateMips">Set to true to automatically generate mipmaps.</param> /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param> /// <param name="anisoLevel">Anisotropic filtering level.</param> /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param> /// <param name="msaaSamples">Number of MSAA samples for the RTHandle.</param> /// <param name="bindTextureMS">Set to true if the texture needs to be bound as a multisampled texture in the shader.</param> /// <param name="useDynamicScale">Set to true to use hardware dynamic scaling.</param> /// <param name="memoryless">Use this property to set the render texture memoryless modes.</param> /// <param name="name">Name of the RTHandle.</param> /// <returns></returns> public RTHandle Alloc( int width, int height, int slices = 1, DepthBits depthBufferBits = DepthBits.None, GraphicsFormat colorFormat = GraphicsFormat.R8G8B8A8_SRGB, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, bool enableRandomWrite = false, bool useMipMap = false, bool autoGenerateMips = true, bool isShadowMap = false, int anisoLevel = 1, float mipMapBias = 0f, MSAASamples msaaSamples = MSAASamples.None, bool bindTextureMS = false, bool useDynamicScale = false, RenderTextureMemoryless memoryless = RenderTextureMemoryless.None, string name = "" ) { bool enableMSAA = msaaSamples != MSAASamples.None; if (!enableMSAA && bindTextureMS == true) { Debug.LogWarning("RTHandle allocated without MSAA but with bindMS set to true, forcing bindMS to false."); bindTextureMS = false; } // We need to handle this in an explicit way since GraphicsFormat does not expose depth formats. TODO: Get rid of this branch once GraphicsFormat'll expose depth related formats RenderTexture rt; if (isShadowMap || depthBufferBits != DepthBits.None) { RenderTextureFormat format = isShadowMap ? RenderTextureFormat.Shadowmap : RenderTextureFormat.Depth; rt = new RenderTexture(width, height, (int)depthBufferBits, format, RenderTextureReadWrite.Linear) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = enableRandomWrite, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = (int)msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, memorylessMode = memoryless, name = CoreUtils.GetRenderTargetAutoName(width, height, slices, format, name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples) }; } else { rt = new RenderTexture(width, height, (int)depthBufferBits, colorFormat) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = enableRandomWrite, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = (int)msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, memorylessMode = memoryless, name = CoreUtils.GetRenderTargetAutoName(width, height, slices, GraphicsFormatUtility.GetRenderTextureFormat(colorFormat), name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples) }; } rt.Create(); var newRT = new RTHandle(this); newRT.SetRenderTexture(rt); newRT.useScaling = false; newRT.m_EnableRandomWrite = enableRandomWrite; newRT.m_EnableMSAA = enableMSAA; newRT.m_EnableHWDynamicScale = useDynamicScale; newRT.m_Name = name; newRT.referenceSize = new Vector2Int(width, height); return(newRT); }
// Pass all the systems that may want to update per-camera data here. // That way you will never update an HDCamera and forget to update the dependent system. public void Update(FrameSettings currentFrameSettings, PostProcessLayer postProcessLayer, VolumetricLightingSystem vlSys) { // store a shortcut on HDAdditionalCameraData (done here and not in the constructor as // we do'nt create HDCamera at every frame and user can change the HDAdditionalData later (Like when they create a new scene). m_AdditionalCameraData = camera.GetComponent <HDAdditionalCameraData>(); m_frameSettings = currentFrameSettings; // If TAA is enabled projMatrix will hold a jittered projection matrix. The original, // non-jittered projection matrix can be accessed via nonJitteredProjMatrix. bool taaEnabled = camera.cameraType == CameraType.Game && HDUtils.IsTemporalAntialiasingActive(postProcessLayer) && m_frameSettings.enablePostprocess; var nonJitteredCameraProj = camera.projectionMatrix; var cameraProj = taaEnabled ? postProcessLayer.temporalAntialiasing.GetJitteredProjectionMatrix(camera) : nonJitteredCameraProj; // The actual projection matrix used in shaders is actually massaged a bit to work across all platforms // (different Z value ranges etc.) var gpuProj = GL.GetGPUProjectionMatrix(cameraProj, true); // Had to change this from 'false' var gpuView = camera.worldToCameraMatrix; var gpuNonJitteredProj = GL.GetGPUProjectionMatrix(nonJitteredCameraProj, true); // In stereo, this corresponds to the center eye position var pos = camera.transform.position; worldSpaceCameraPos = pos; if (ShaderConfig.s_CameraRelativeRendering != 0) { // Zero out the translation component. gpuView.SetColumn(3, new Vector4(0, 0, 0, 1)); } var gpuVP = gpuNonJitteredProj * gpuView; // A camera could be rendered multiple times per frame, only updates the previous view proj & pos if needed if (m_LastFrameActive != Time.frameCount) { if (isFirstFrame) { prevCameraPos = pos; prevViewProjMatrix = gpuVP; } else { prevCameraPos = cameraPos; prevViewProjMatrix = nonJitteredViewProjMatrix; } isFirstFrame = false; } taaFrameIndex = taaEnabled ? (uint)postProcessLayer.temporalAntialiasing.sampleIndex : 0; taaFrameRotation = new Vector2(Mathf.Sin(taaFrameIndex * (0.5f * Mathf.PI)), Mathf.Cos(taaFrameIndex * (0.5f * Mathf.PI))); viewMatrix = gpuView; projMatrix = gpuProj; nonJitteredProjMatrix = gpuNonJitteredProj; cameraPos = pos; detViewMatrix = viewMatrix.determinant; if (ShaderConfig.s_CameraRelativeRendering != 0) { Matrix4x4 cameraDisplacement = Matrix4x4.Translate(cameraPos - prevCameraPos); // Non-camera-relative positions prevViewProjMatrix *= cameraDisplacement; // Now prevViewProjMatrix correctly transforms this frame's camera-relative positionWS } float n = camera.nearClipPlane; float f = camera.farClipPlane; // Analyze the projection matrix. // p[2][3] = (reverseZ ? 1 : -1) * (depth_0_1 ? 1 : 2) * (f * n) / (f - n) float scale = projMatrix[2, 3] / (f * n) * (f - n); bool depth_0_1 = Mathf.Abs(scale) < 1.5f; bool reverseZ = scale > 0; bool flipProj = projMatrix.inverse.MultiplyPoint(new Vector3(0, 1, 0)).y < 0; // http://www.humus.name/temp/Linearize%20depth.txt if (reverseZ) { zBufferParams = new Vector4(-1 + f / n, 1, -1 / f + 1 / n, 1 / f); } else { zBufferParams = new Vector4(1 - f / n, f / n, 1 / f - 1 / n, 1 / n); } projectionParams = new Vector4(flipProj ? -1 : 1, n, f, 1.0f / f); float orthoHeight = camera.orthographic ? 2 * camera.orthographicSize : 0; float orthoWidth = orthoHeight * camera.aspect; unity_OrthoParams = new Vector4(orthoWidth, orthoHeight, 0, camera.orthographic ? 1 : 0); frustum = Frustum.Create(viewProjMatrix, depth_0_1, reverseZ); // Left, right, top, bottom, near, far. for (int i = 0; i < 6; i++) { frustumPlaneEquations[i] = new Vector4(frustum.planes[i].normal.x, frustum.planes[i].normal.y, frustum.planes[i].normal.z, frustum.planes[i].distance); } m_LastFrameActive = Time.frameCount; m_ActualWidth = camera.pixelWidth; m_ActualHeight = camera.pixelHeight; var screenWidth = m_ActualWidth; var screenHeight = m_ActualHeight; //forest-begin: Added XboxOne to define around XR code #if !UNITY_SWITCH && !UNITY_XBOXONE //forest-end: if (m_frameSettings.enableStereo) { screenWidth = XRSettings.eyeTextureWidth; screenHeight = XRSettings.eyeTextureHeight; var xrDesc = XRSettings.eyeTextureDesc; m_ActualWidth = xrDesc.width; m_ActualHeight = xrDesc.height; ConfigureStereoMatrices(); } #endif // Unfortunately sometime (like in the HDCameraEditor) HDUtils.hdrpSettings can be null because of scripts that change the current pipeline... m_msaaSamples = HDUtils.hdrpSettings != null ? HDUtils.hdrpSettings.msaaSampleCount : MSAASamples.None; RTHandles.SetReferenceSize(m_ActualWidth, m_ActualHeight, m_frameSettings.enableMSAA, m_msaaSamples); m_HistoryRTSystem.SetReferenceSize(m_ActualWidth, m_ActualHeight, m_frameSettings.enableMSAA, m_msaaSamples); m_HistoryRTSystem.Swap(); int maxWidth = RTHandles.maxWidth; int maxHeight = RTHandles.maxHeight; m_ViewportScalePreviousFrame = m_ViewportScaleCurrentFrame; // Double-buffer m_ViewportScaleCurrentFrame.x = (float)m_ActualWidth / maxWidth; m_ViewportScaleCurrentFrame.y = (float)m_ActualHeight / maxHeight; screenSize = new Vector4(screenWidth, screenHeight, 1.0f / screenWidth, 1.0f / screenHeight); screenParams = new Vector4(screenSize.x, screenSize.y, 1 + screenSize.z, 1 + screenSize.w); if (vlSys != null) { vlSys.UpdatePerCameraData(this); } }
public void InitSharedBuffers(GBufferManager gbufferManager, RenderPipelineSettings settings, RenderPipelineResources resources) { // Set the flags m_MSAASupported = settings.supportMSAA; m_MSAASamples = m_MSAASupported ? settings.msaaSampleCount : MSAASamples.None; m_MotionVectorsSupport = settings.supportMotionVectors; m_ReuseGBufferMemory = settings.supportedLitShaderMode != RenderPipelineSettings.SupportedLitShaderMode.ForwardOnly; // Create the depth/stencil buffer m_CameraDepthStencilBuffer = RTHandles.Alloc(Vector2.one, depthBufferBits: DepthBits.Depth32, filterMode: FilterMode.Point, xrInstancing: true, useDynamicScale: true, name: "CameraDepthStencil"); // Create the mip chain buffer m_CameraDepthBufferMipChainInfo = new HDUtils.PackedMipChainInfo(); m_CameraDepthBufferMipChainInfo.Allocate(); m_CameraDepthBufferMipChain = RTHandles.Alloc(ComputeDepthBufferMipChainSize, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R32_SFloat), filterMode: FilterMode.Point, enableRandomWrite: true, xrInstancing: true, useDynamicScale: true, name: "CameraDepthBufferMipChain"); if (settings.lowresTransparentSettings.enabled) { // Create the half res depth buffer used for low resolution transparency m_CameraHalfResDepthBuffer = RTHandles.Alloc(Vector2.one * 0.5f, depthBufferBits: DepthBits.Depth32, filterMode: FilterMode.Point, xrInstancing: true, useDynamicScale: true, name: "LowResDepthBuffer"); } // Technically we won't need this buffer in some cases, but nothing that we can determine at init time. m_CameraStencilBufferCopy = RTHandles.Alloc(Vector2.one, depthBufferBits: DepthBits.None, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R8_UNorm), filterMode: FilterMode.Point, enableRandomWrite: true, xrInstancing: true, useDynamicScale: true, name: "CameraStencilCopy"); // DXGI_FORMAT_R8_UINT is not supported by Unity if (m_MotionVectorsSupport) { m_MotionVectorsRT = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: Builtin.GetMotionVectorFormat(), xrInstancing: true, useDynamicScale: true, name: "MotionVectors"); if (m_MSAASupported) { m_MotionVectorsMSAART = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: Builtin.GetMotionVectorFormat(), enableMSAA: true, bindTextureMS: true, xrInstancing: true, useDynamicScale: true, name: "MotionVectorsMSAA"); } } // Allocate the additional textures only if MSAA is supported if (m_MSAASupported) { // Let's create the MSAA textures m_CameraDepthStencilMSAABuffer = RTHandles.Alloc(Vector2.one, depthBufferBits: DepthBits.Depth24, filterMode: FilterMode.Point, bindTextureMS: true, enableMSAA: true, xrInstancing: true, useDynamicScale: true, name: "CameraDepthStencilMSAA"); m_CameraDepthValuesBuffer = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R32G32B32A32_SFloat), xrInstancing: true, useDynamicScale: true, name: "DepthValuesBuffer"); m_DepthAsColorMSAART = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R32_SFloat), bindTextureMS: true, enableMSAA: true, xrInstancing: true, useDynamicScale: true, name: "DepthAsColorMSAA"); // We need to allocate this texture as long as msaa is supported because on both mode, one of the cameras can be forward only using the framesettings m_NormalMSAART = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R8G8B8A8_UNorm), enableMSAA: true, bindTextureMS: true, xrInstancing: true, useDynamicScale: true, name: "NormalBufferMSAA"); // Create the required resolve materials m_DepthResolveMaterial = CoreUtils.CreateEngineMaterial(resources.shaders.depthValuesPS); m_ColorResolveMaterial = CoreUtils.CreateEngineMaterial(resources.shaders.colorResolvePS); } // If we are in the forward only mode if (!m_ReuseGBufferMemory) { // In case of full forward we must allocate the render target for normal buffer (or reuse one already existing) // TODO: Provide a way to reuse a render target m_NormalRT = RTHandles.Alloc(Vector2.one, filterMode: FilterMode.Point, colorFormat: UnityEngine.Experimental.Rendering.HDPipeline.HDRenderPipeline.OverrideRTGraphicsFormat(GraphicsFormat.R8G8B8A8_UNorm), enableRandomWrite: true, xrInstancing: true, useDynamicScale: true, name: "NormalBuffer"); } else { // When not forward only we should are using the normal buffer of the gbuffer // In case of deferred, we must be in sync with NormalBuffer.hlsl and lit.hlsl files and setup the correct buffers m_NormalRT = gbufferManager.GetNormalBuffer(0); // Normal + Roughness } }
public void SetNumMSAASamples(MSAASamples msaaSamples) { m_MSAASamples = msaaSamples; }
public static string GetRenderTargetAutoName(int width, int height, RenderTextureFormat format, string name = "", bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None, int CameraGroup = 0, bool bindMSTexture = false) { string str; if (enableMSAA) { str = string.Format("{0}x{1}_{2}{3}_{4}", width, height, format, mips ? "_Mips" : "", msaaSamples.ToString()); } else { str = string.Format("{0}x{1}_{2}{3}", width, height, format, mips ? "_Mips" : ""); } if (bindMSTexture) { str += "_bindMsTexture"; } str += "_CameraGroup" + CameraGroup.ToString(); str = string.Format("{0}_{1}", name == "" ? "Texture" : name, str); return(str); }
/// <summary> /// Set the reference size for this RT Handle System (<see cref="RTHandleSystem.SetReferenceSize(int, int, bool, MSAASamples)"/>) /// </summary> /// <param name="width">The width of the RTs of this buffer.</param> /// <param name="height">The height of the RTs of this buffer.</param> /// <param name="msaaSamples">Number of MSAA samples for this buffer.</param> public void SetReferenceSize(int width, int height, MSAASamples msaaSamples) { m_RTHandleSystem.SetReferenceSize(width, height, msaaSamples); }
// Pass all the systems that may want to update per-camera data here. // That way you will never update an HDCamera and forget to update the dependent system. public void Update(FrameSettings currentFrameSettings, VolumetricLightingSystem vlSys, MSAASamples msaaSamples) { // store a shortcut on HDAdditionalCameraData (done here and not in the constructor as // we don't create HDCamera at every frame and user can change the HDAdditionalData later (Like when they create a new scene). m_AdditionalCameraData = camera.GetComponent <HDAdditionalCameraData>(); m_frameSettings = currentFrameSettings; UpdateAntialiasing(); // Handle memory allocation. { bool isColorPyramidHistoryRequired = m_frameSettings.IsEnabled(FrameSettingsField.SSR); // TODO: TAA as well bool isVolumetricHistoryRequired = m_frameSettings.IsEnabled(FrameSettingsField.Volumetrics) && m_frameSettings.IsEnabled(FrameSettingsField.ReprojectionForVolumetrics); int numColorPyramidBuffersRequired = isColorPyramidHistoryRequired ? 2 : 1; // TODO: 1 -> 0 int numVolumetricBuffersRequired = isVolumetricHistoryRequired ? 2 : 0; // History + feedback if ((numColorPyramidBuffersAllocated != numColorPyramidBuffersRequired) || (numVolumetricBuffersAllocated != numVolumetricBuffersRequired)) { // Reinit the system. colorPyramidHistoryIsValid = false; vlSys.DeinitializePerCameraData(this); // The history system only supports the "nuke all" option. m_HistoryRTSystem.Dispose(); m_HistoryRTSystem = new BufferedRTHandleSystem(); if (numColorPyramidBuffersRequired != 0) { AllocHistoryFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain, HistoryBufferAllocatorFunction, numColorPyramidBuffersRequired); colorPyramidHistoryIsValid = false; } vlSys.InitializePerCameraData(this, numVolumetricBuffersRequired); // Mark as init. numColorPyramidBuffersAllocated = numColorPyramidBuffersRequired; numVolumetricBuffersAllocated = numVolumetricBuffersRequired; } } UpdateViewConstants(); // Update viewport sizes. m_ViewportSizePrevFrame = new Vector2Int(m_ActualWidth, m_ActualHeight); m_ActualWidth = Math.Max(camera.pixelWidth, 1); m_ActualHeight = Math.Max(camera.pixelHeight, 1); Vector2Int nonScaledSize = new Vector2Int(m_ActualWidth, m_ActualHeight); if (isMainGameView) { Vector2Int scaledSize = HDDynamicResolutionHandler.instance.GetRTHandleScale(new Vector2Int(camera.pixelWidth, camera.pixelHeight)); nonScaledSize = HDDynamicResolutionHandler.instance.cachedOriginalSize; m_ActualWidth = scaledSize.x; m_ActualHeight = scaledSize.y; } var screenWidth = m_ActualWidth; var screenHeight = m_ActualHeight; // XRTODO: double-wide cleanup textureWidthScaling = new Vector4(1.0f, 1.0f, 0.0f, 0.0f); if (camera.stereoEnabled && XRGraphics.stereoRenderingMode == XRGraphics.StereoRenderingMode.SinglePass) { Debug.Assert(HDDynamicResolutionHandler.instance.SoftwareDynamicResIsEnabled() == false); var xrDesc = XRGraphics.eyeTextureDesc; nonScaledSize.x = screenWidth = m_ActualWidth = xrDesc.width; nonScaledSize.y = screenHeight = m_ActualHeight = xrDesc.height; textureWidthScaling = new Vector4(2.0f, 0.5f, 0.0f, 0.0f); } m_LastFrameActive = Time.frameCount; // TODO: cache this, or make the history system spill the beans... Vector2Int prevColorPyramidBufferSize = Vector2Int.zero; if (numColorPyramidBuffersAllocated > 0) { var rt = GetCurrentFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain).rt; prevColorPyramidBufferSize.x = rt.width; prevColorPyramidBufferSize.y = rt.height; } // TODO: cache this, or make the history system spill the beans... Vector3Int prevVolumetricBufferSize = Vector3Int.zero; if (numVolumetricBuffersAllocated != 0) { var rt = GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting).rt; prevVolumetricBufferSize.x = rt.width; prevVolumetricBufferSize.y = rt.height; prevVolumetricBufferSize.z = rt.volumeDepth; } m_msaaSamples = msaaSamples; // Here we use the non scaled resolution for the RTHandleSystem ref size because we assume that at some point we will need full resolution anyway. // This is also useful because we have some RT after final up-rez that will need the full size. RTHandles.SetReferenceSize(nonScaledSize.x, nonScaledSize.y, m_msaaSamples); m_HistoryRTSystem.SetReferenceSize(nonScaledSize.x, nonScaledSize.y, m_msaaSamples); m_HistoryRTSystem.Swap(); Vector3Int currColorPyramidBufferSize = Vector3Int.zero; if (numColorPyramidBuffersAllocated != 0) { var rt = GetCurrentFrameRT((int)HDCameraFrameHistoryType.ColorBufferMipChain).rt; currColorPyramidBufferSize.x = rt.width; currColorPyramidBufferSize.y = rt.height; if ((currColorPyramidBufferSize.x != prevColorPyramidBufferSize.x) || (currColorPyramidBufferSize.y != prevColorPyramidBufferSize.y)) { // A reallocation has happened, so the new texture likely contains garbage. colorPyramidHistoryIsValid = false; } } Vector3Int currVolumetricBufferSize = Vector3Int.zero; if (numVolumetricBuffersAllocated != 0) { var rt = GetCurrentFrameRT((int)HDCameraFrameHistoryType.VolumetricLighting).rt; currVolumetricBufferSize.x = rt.width; currVolumetricBufferSize.y = rt.height; currVolumetricBufferSize.z = rt.volumeDepth; if ((currVolumetricBufferSize.x != prevVolumetricBufferSize.x) || (currVolumetricBufferSize.y != prevVolumetricBufferSize.y) || (currVolumetricBufferSize.z != prevVolumetricBufferSize.z)) { // A reallocation has happened, so the new texture likely contains garbage. volumetricHistoryIsValid = false; } } int maxWidth = RTHandles.maxWidth; int maxHeight = RTHandles.maxHeight; Vector2 rcpTextureSize = Vector2.one / new Vector2(maxWidth, maxHeight); m_ViewportScalePreviousFrame = m_ViewportSizePrevFrame * rcpTextureSize; m_ViewportScaleCurrentFrame = new Vector2Int(m_ActualWidth, m_ActualHeight) * rcpTextureSize; screenSize = new Vector4(screenWidth, screenHeight, 1.0f / screenWidth, 1.0f / screenHeight); screenParams = new Vector4(screenSize.x, screenSize.y, 1 + screenSize.z, 1 + screenSize.w); finalViewport = new Rect(camera.pixelRect.x, camera.pixelRect.y, nonScaledSize.x, nonScaledSize.y); if (vlSys != null) { vlSys.UpdatePerCameraData(this); } UpdateVolumeParameters(); m_RecorderCaptureActions = CameraCaptureBridge.GetCaptureActions(camera); }
/// <summary> /// Sets the reference rendering size for subsequent rendering for the RTHandle System /// </summary> /// <param name="width">Reference rendering width for subsequent rendering.</param> /// <param name="height">Reference rendering height for subsequent rendering.</param> /// <param name="msaaSamples">Number of MSAA samples for multisampled textures for subsequent rendering.</param> public void SetReferenceSize(int width, int height, MSAASamples msaaSamples) { SetReferenceSize(width, height, msaaSamples, false); }
public static string GetRenderTargetAutoName(int width, int height, int depth, RenderTextureFormat format, string name, bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None) { string result = string.Format("{0}_{1}x{2}", name, width, height); if (depth > 1) { result = string.Format("{0}x{1}", result, depth); } if (mips) { result = string.Format("{0}_{1}", result, "Mips"); } result = string.Format("{0}_{1}", result, format); if (enableMSAA) { result = string.Format("{0}_{1}", result, msaaSamples.ToString()); } return(result); }
/// <summary> /// Render Graph constructor. /// </summary> /// <param name="supportMSAA">Specify if this Render Graph should support MSAA.</param> /// <param name="initialSampleCount">Specify the initial sample count of MSAA render textures.</param> public RenderGraph(bool supportMSAA, MSAASamples initialSampleCount) { m_Resources = new RenderGraphResourceRegistry(supportMSAA, initialSampleCount, m_DebugParameters, m_Logger); }