A game about forced loneliness, made by TACStudios
1using System; 2using System.IO; 3using System.Linq; 4using System.Collections.Generic; 5using UnityEngine.Experimental.Rendering; 6 7namespace UnityEngine.Rendering 8{ 9 using UnityObject = UnityEngine.Object; 10 11 /// <summary> 12 /// Set of utility functions for the Core Scriptable Render Pipeline Library 13 /// </summary> 14 public static class CoreUtils 15 { 16 /// <summary> 17 /// List of look at matrices for cubemap faces. 18 /// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx 19 /// </summary> 20 static public readonly Vector3[] lookAtList = 21 { 22 new Vector3(1.0f, 0.0f, 0.0f), 23 new Vector3(-1.0f, 0.0f, 0.0f), 24 new Vector3(0.0f, 1.0f, 0.0f), 25 new Vector3(0.0f, -1.0f, 0.0f), 26 new Vector3(0.0f, 0.0f, 1.0f), 27 new Vector3(0.0f, 0.0f, -1.0f), 28 }; 29 30 /// <summary> 31 /// List of up vectors for cubemap faces. 32 /// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx 33 /// </summary> 34 static public readonly Vector3[] upVectorList = 35 { 36 new Vector3(0.0f, 1.0f, 0.0f), 37 new Vector3(0.0f, 1.0f, 0.0f), 38 new Vector3(0.0f, 0.0f, -1.0f), 39 new Vector3(0.0f, 0.0f, 1.0f), 40 new Vector3(0.0f, 1.0f, 0.0f), 41 new Vector3(0.0f, 1.0f, 0.0f), 42 }; 43 44 /// <summary> 45 /// Class to store the menu sections 46 /// </summary> 47 public static class Sections 48 { 49 /// <summary>Menu section 1</summary> 50 public const int section1 = 10000; 51 /// <summary>Menu section 2</summary> 52 public const int section2 = 20000; 53 /// <summary>Menu section 3</summary> 54 public const int section3 = 30000; 55 /// <summary>Menu section 4</summary> 56 public const int section4 = 40000; 57 /// <summary>Menu section 5</summary> 58 public const int section5 = 50000; 59 /// <summary>Menu section 6</summary> 60 public const int section6 = 60000; 61 /// <summary>Menu section 7</summary> 62 public const int section7 = 70000; 63 /// <summary>Menu section 8</summary> 64 public const int section8 = 80000; 65 } 66 67 /// <summary> 68 /// Class to store the menu priorities on each top level menu 69 /// </summary> 70 public static class Priorities 71 { 72 /// <summary>Assets > Create > Shader priority</summary> 73 public const int assetsCreateShaderMenuPriority = 83; 74 /// <summary>Assets > Create > Rendering priority</summary> 75 public const int assetsCreateRenderingMenuPriority = 308; 76 /// <summary>Edit Menu base priority</summary> 77 public const int editMenuPriority = 320; 78 /// <summary>Game Object Menu priority</summary> 79 public const int gameObjectMenuPriority = 10; 80 /// <summary>Lens Flare Priority</summary> 81 public const int srpLensFlareMenuPriority = 303; 82 } 83 84 const string obsoletePriorityMessage = "Use CoreUtils.Priorities instead"; 85 86 /// <summary>Edit Menu priority 1</summary> 87 [Obsolete(obsoletePriorityMessage, false)] 88 public const int editMenuPriority1 = 320; 89 /// <summary>Edit Menu priority 2</summary> 90 [Obsolete(obsoletePriorityMessage, false)] 91 public const int editMenuPriority2 = 331; 92 /// <summary>Edit Menu priority 3</summary> 93 [Obsolete(obsoletePriorityMessage, false)] 94 public const int editMenuPriority3 = 342; 95 /// <summary>Edit Menu priority 4</summary> 96 [Obsolete(obsoletePriorityMessage, false)] 97 public const int editMenuPriority4 = 353; 98 /// <summary>Asset Create Menu priority 1</summary> 99 [Obsolete(obsoletePriorityMessage, false)] 100 public const int assetCreateMenuPriority1 = 230; 101 /// <summary>Asset Create Menu priority 2</summary> 102 [Obsolete(obsoletePriorityMessage, false)] 103 public const int assetCreateMenuPriority2 = 241; 104 /// <summary>Asset Create Menu priority 3</summary> 105 [Obsolete(obsoletePriorityMessage, false)] 106 public const int assetCreateMenuPriority3 = 300; 107 /// <summary>Game Object Menu priority</summary> 108 [Obsolete(obsoletePriorityMessage, false)] 109 public const int gameObjectMenuPriority = 10; 110 111 static Cubemap m_BlackCubeTexture; 112 /// <summary> 113 /// Black cubemap texture. 114 /// </summary> 115 public static Cubemap blackCubeTexture 116 { 117 get 118 { 119 if (m_BlackCubeTexture == null) 120 { 121 m_BlackCubeTexture = new Cubemap(1, GraphicsFormat.R8G8B8A8_SRGB, TextureCreationFlags.None); 122 for (int i = 0; i < 6; ++i) 123 m_BlackCubeTexture.SetPixel((CubemapFace)i, 0, 0, Color.black); 124 m_BlackCubeTexture.Apply(); 125 } 126 127 return m_BlackCubeTexture; 128 } 129 } 130 131 static Cubemap m_MagentaCubeTexture; 132 /// <summary> 133 /// Magenta cubemap texture. 134 /// </summary> 135 public static Cubemap magentaCubeTexture 136 { 137 get 138 { 139 if (m_MagentaCubeTexture == null) 140 { 141 m_MagentaCubeTexture = new Cubemap(1, GraphicsFormat.R8G8B8A8_SRGB, TextureCreationFlags.None); 142 for (int i = 0; i < 6; ++i) 143 m_MagentaCubeTexture.SetPixel((CubemapFace)i, 0, 0, Color.magenta); 144 m_MagentaCubeTexture.Apply(); 145 } 146 147 return m_MagentaCubeTexture; 148 } 149 } 150 151 static CubemapArray m_MagentaCubeTextureArray; 152 /// <summary> 153 /// Black cubemap array texture. 154 /// </summary> 155 public static CubemapArray magentaCubeTextureArray 156 { 157 get 158 { 159 if (m_MagentaCubeTextureArray == null) 160 { 161 m_MagentaCubeTextureArray = new CubemapArray(1, 1, GraphicsFormat.R32G32B32A32_SFloat, TextureCreationFlags.None); 162 for (int i = 0; i < 6; ++i) 163 { 164 Color[] colors = { Color.magenta }; 165 m_MagentaCubeTextureArray.SetPixels(colors, (CubemapFace)i, 0); 166 } 167 m_MagentaCubeTextureArray.Apply(); 168 } 169 170 return m_MagentaCubeTextureArray; 171 } 172 } 173 174 static Cubemap m_WhiteCubeTexture; 175 /// <summary> 176 /// White cubemap texture. 177 /// </summary> 178 public static Cubemap whiteCubeTexture 179 { 180 get 181 { 182 if (m_WhiteCubeTexture == null) 183 { 184 m_WhiteCubeTexture = new Cubemap(1, GraphicsFormat.R8G8B8A8_SRGB, TextureCreationFlags.None); 185 for (int i = 0; i < 6; ++i) 186 m_WhiteCubeTexture.SetPixel((CubemapFace)i, 0, 0, Color.white); 187 m_WhiteCubeTexture.Apply(); 188 } 189 190 return m_WhiteCubeTexture; 191 } 192 } 193 194 static RenderTexture m_EmptyUAV; 195 /// <summary> 196 /// Empty 1x1 texture usable as a dummy UAV. 197 /// </summary> 198 public static RenderTexture emptyUAV 199 { 200 get 201 { 202 if (m_EmptyUAV == null) 203 { 204 m_EmptyUAV = new RenderTexture(1, 1, 0); 205 m_EmptyUAV.enableRandomWrite = true; 206 m_EmptyUAV.Create(); 207 } 208 209 return m_EmptyUAV; 210 } 211 } 212 213 static GraphicsBuffer m_EmptyBuffer; 214 /// <summary> 215 /// Empty 4-Byte buffer resource usable as a dummy. 216 /// </summary> 217 public static GraphicsBuffer emptyBuffer 218 { 219 get 220 { 221 if (m_EmptyBuffer == null || !m_EmptyBuffer.IsValid()) 222 { 223 m_EmptyBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Raw, 1, sizeof(uint)); 224 } 225 226 return m_EmptyBuffer; 227 } 228 } 229 230 static Texture3D m_BlackVolumeTexture; 231 /// <summary> 232 /// Black 3D texture. 233 /// </summary> 234 public static Texture3D blackVolumeTexture 235 { 236 get 237 { 238 if (m_BlackVolumeTexture == null) 239 { 240 Color[] colors = { Color.black }; 241 m_BlackVolumeTexture = new Texture3D(1, 1, 1, GraphicsFormat.R8G8B8A8_SRGB, TextureCreationFlags.None); 242 m_BlackVolumeTexture.SetPixels(colors, 0); 243 m_BlackVolumeTexture.Apply(); 244 } 245 246 return m_BlackVolumeTexture; 247 } 248 } 249 250 internal static Texture3D m_WhiteVolumeTexture; 251 252 /// <summary> 253 /// White 3D texture. 254 /// </summary> 255 internal static Texture3D whiteVolumeTexture 256 { 257 get 258 { 259 if (m_WhiteVolumeTexture == null) 260 { 261 Color[] colors = { Color.white }; 262 m_WhiteVolumeTexture = new Texture3D(1, 1, 1, GraphicsFormat.R8G8B8A8_SRGB, TextureCreationFlags.None); 263 m_WhiteVolumeTexture.SetPixels(colors, 0); 264 m_WhiteVolumeTexture.Apply(); 265 } 266 267 return m_WhiteVolumeTexture; 268 } 269 } 270 271 /// <summary> 272 /// Clear the currently bound render texture. 273 /// </summary> 274 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 275 /// <param name="clearFlag">Specify how the render texture should be cleared.</param> 276 /// <param name="clearColor">Specify with which color the render texture should be cleared.</param> 277 public static void ClearRenderTarget(CommandBuffer cmd, ClearFlag clearFlag, Color clearColor) 278 { 279 if (clearFlag != ClearFlag.None) 280 cmd.ClearRenderTarget((RTClearFlags)clearFlag, clearColor, 1.0f, 0x00); 281 } 282 283 // We use -1 as a default value because when doing SPI for XR, it will bind the full texture array by default (and has no effect on 2D textures) 284 // Unfortunately, for cubemaps, passing -1 does not work for faces other than the first one, so we fall back to 0 in this case. 285 private static int FixupDepthSlice(int depthSlice, RTHandle buffer) 286 { 287 // buffer.rt can be null in case the RTHandle is constructed from a RenderTextureIdentifier. 288 if (depthSlice == -1 && buffer.rt?.dimension == TextureDimension.Cube) 289 depthSlice = 0; 290 291 return depthSlice; 292 } 293 294 private static int FixupDepthSlice(int depthSlice, CubemapFace cubemapFace) 295 { 296 if (depthSlice == -1 && cubemapFace != CubemapFace.Unknown) 297 depthSlice = 0; 298 299 return depthSlice; 300 } 301 302 /// <summary> 303 /// Set the current render texture. 304 /// </summary> 305 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 306 /// <param name="buffer">RenderTargetIdentifier of the render texture.</param> 307 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 308 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 309 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 310 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 311 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 312 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 313 { 314 depthSlice = FixupDepthSlice(depthSlice, cubemapFace); 315 cmd.SetRenderTarget(buffer, miplevel, cubemapFace, depthSlice); 316 ClearRenderTarget(cmd, clearFlag, clearColor); 317 } 318 319 /// <summary> 320 /// Set the current render texture. 321 /// </summary> 322 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 323 /// <param name="buffer">RenderTargetIdentifier of the render texture.</param> 324 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 325 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 326 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 327 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 328 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, ClearFlag clearFlag = ClearFlag.None, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 329 { 330 SetRenderTarget(cmd, buffer, clearFlag, Color.clear, miplevel, cubemapFace, depthSlice); 331 } 332 333 /// <summary> 334 /// Set the current render texture. 335 /// </summary> 336 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 337 /// <param name="colorBuffer">RenderTargetIdentifier of the color render texture.</param> 338 /// <param name="depthBuffer">RenderTargetIdentifier of the depth render texture.</param> 339 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 340 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 341 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 342 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 343 { 344 SetRenderTarget(cmd, colorBuffer, depthBuffer, ClearFlag.None, Color.clear, miplevel, cubemapFace, depthSlice); 345 } 346 347 /// <summary> 348 /// Set the current render texture. 349 /// </summary> 350 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 351 /// <param name="colorBuffer">RenderTargetIdentifier of the color render texture.</param> 352 /// <param name="depthBuffer">RenderTargetIdentifier of the depth render texture.</param> 353 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 354 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 355 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 356 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 357 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 358 { 359 SetRenderTarget(cmd, colorBuffer, depthBuffer, clearFlag, Color.clear, miplevel, cubemapFace, depthSlice); 360 } 361 362 /// <summary> 363 /// Set the current render texture. 364 /// </summary> 365 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 366 /// <param name="colorBuffer">RenderTargetIdentifier of the color render texture.</param> 367 /// <param name="depthBuffer">RenderTargetIdentifier of the depth render texture.</param> 368 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 369 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 370 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 371 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 372 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 373 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 374 { 375 depthSlice = FixupDepthSlice(depthSlice, cubemapFace); 376 cmd.SetRenderTarget(colorBuffer, depthBuffer, miplevel, cubemapFace, depthSlice); 377 ClearRenderTarget(cmd, clearFlag, clearColor); 378 } 379 380 /// <summary> 381 /// Set the current multiple render texture. 382 /// </summary> 383 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 384 /// <param name="colorBuffers">RenderTargetIdentifier array of the color render textures.</param> 385 /// <param name="depthBuffer">RenderTargetIdentifier of the depth render texture.</param> 386 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer) 387 { 388 SetRenderTarget(cmd, colorBuffers, depthBuffer, ClearFlag.None, Color.clear); 389 } 390 391 /// <summary> 392 /// Set the current multiple render texture. 393 /// </summary> 394 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 395 /// <param name="colorBuffers">RenderTargetIdentifier array of the color render textures.</param> 396 /// <param name="depthBuffer">RenderTargetIdentifier of the depth render texture.</param> 397 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 398 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag = ClearFlag.None) 399 { 400 SetRenderTarget(cmd, colorBuffers, depthBuffer, clearFlag, Color.clear); 401 } 402 403 /// <summary> 404 /// Set the current multiple render texture. 405 /// </summary> 406 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 407 /// <param name="colorBuffers">RenderTargetIdentifier array of the color render textures.</param> 408 /// <param name="depthBuffer">RenderTargetIdentifier of the depth render texture.</param> 409 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 410 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 411 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthBuffer, ClearFlag clearFlag, Color clearColor) 412 { 413 cmd.SetRenderTarget(colorBuffers, depthBuffer, 0, CubemapFace.Unknown, -1); 414 ClearRenderTarget(cmd, clearFlag, clearColor); 415 } 416 417 // Explicit load and store actions 418 /// <summary> 419 /// Set the current render texture. 420 /// </summary> 421 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 422 /// <param name="buffer">Color buffer RenderTargetIdentifier.</param> 423 /// <param name="loadAction">Load action.</param> 424 /// <param name="storeAction">Store action.</param> 425 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 426 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 427 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, ClearFlag clearFlag, Color clearColor) 428 { 429 cmd.SetRenderTarget(buffer, loadAction, storeAction); 430 ClearRenderTarget(cmd, clearFlag, clearColor); 431 } 432 433 // Explicit load and store actions 434 /// <summary> 435 /// Set the current render texture. 436 /// </summary> 437 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 438 /// <param name="buffer">Color buffer RenderTargetIdentifier.</param> 439 /// <param name="loadAction">Load action.</param> 440 /// <param name="storeAction">Store action.</param> 441 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 442 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 443 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 444 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, 445 int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 446 { 447 depthSlice = FixupDepthSlice(depthSlice, cubemapFace); 448 buffer = new RenderTargetIdentifier(buffer, miplevel, cubemapFace, depthSlice); 449 cmd.SetRenderTarget(buffer, loadAction, storeAction); 450 } 451 452 // Explicit load and store actions 453 /// <summary> 454 /// Set the current render texture. 455 /// </summary> 456 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 457 /// <param name="buffer">Color buffer RenderTargetIdentifier.</param> 458 /// <param name="loadAction">Load action.</param> 459 /// <param name="storeAction">Store action.</param> 460 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 461 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 462 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 463 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 464 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 465 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, 466 ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 467 { 468 depthSlice = FixupDepthSlice(depthSlice, cubemapFace); 469 buffer = new RenderTargetIdentifier(buffer, miplevel, cubemapFace, depthSlice); 470 SetRenderTarget(cmd, buffer, loadAction, storeAction, clearFlag, clearColor); 471 } 472 473 /// <summary> 474 /// Set the current render texture. 475 /// </summary> 476 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 477 /// <param name="buffer">Color buffer RenderTargetIdentifier.</param> 478 /// <param name="loadAction">Load action.</param> 479 /// <param name="storeAction">Store action.</param> 480 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 481 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, ClearFlag clearFlag) 482 { 483 SetRenderTarget(cmd, buffer, loadAction, storeAction, clearFlag, Color.clear); 484 } 485 486 /// <summary> 487 /// Set the current render texture. 488 /// </summary> 489 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 490 /// <param name="colorBuffer">Color buffer RenderTargetIdentifier.</param> 491 /// <param name="colorLoadAction">Color buffer load action.</param> 492 /// <param name="colorStoreAction">Color buffer store action.</param> 493 /// <param name="depthBuffer">Depth buffer RenderTargetIdentifier.</param> 494 /// <param name="depthLoadAction">Depth buffer load action.</param> 495 /// <param name="depthStoreAction">Depth buffer store action.</param> 496 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 497 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 498 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, 499 RenderTargetIdentifier depthBuffer, RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, 500 ClearFlag clearFlag, Color clearColor) 501 { 502 cmd.SetRenderTarget(colorBuffer, colorLoadAction, colorStoreAction, depthBuffer, depthLoadAction, depthStoreAction); 503 ClearRenderTarget(cmd, clearFlag, clearColor); 504 } 505 506 /// <summary> 507 /// Set the current render texture. 508 /// </summary> 509 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 510 /// <param name="colorBuffer">Color buffer RenderTargetIdentifier.</param> 511 /// <param name="colorLoadAction">Color buffer load action.</param> 512 /// <param name="colorStoreAction">Color buffer store action.</param> 513 /// <param name="depthBuffer">Depth buffer RenderTargetIdentifier.</param> 514 /// <param name="depthLoadAction">Depth buffer load action.</param> 515 /// <param name="depthStoreAction">Depth buffer store action.</param> 516 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 517 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 518 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 519 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, 520 RenderTargetIdentifier depthBuffer, RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, 521 int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 522 { 523 depthSlice = FixupDepthSlice(depthSlice, cubemapFace); 524 colorBuffer = new RenderTargetIdentifier(colorBuffer, miplevel, cubemapFace, depthSlice); 525 depthBuffer = new RenderTargetIdentifier(depthBuffer, miplevel, cubemapFace, depthSlice); 526 cmd.SetRenderTarget(colorBuffer, colorLoadAction, colorStoreAction, depthBuffer, depthLoadAction, depthStoreAction); 527 } 528 529 /// <summary> 530 /// Set the current render texture. 531 /// </summary> 532 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 533 /// <param name="colorBuffer">Color buffer RenderTargetIdentifier.</param> 534 /// <param name="colorLoadAction">Color buffer load action.</param> 535 /// <param name="colorStoreAction">Color buffer store action.</param> 536 /// <param name="depthBuffer">Depth buffer RenderTargetIdentifier.</param> 537 /// <param name="depthLoadAction">Depth buffer load action.</param> 538 /// <param name="depthStoreAction">Depth buffer store action.</param> 539 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 540 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 541 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 542 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 543 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 544 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, 545 RenderTargetIdentifier depthBuffer, RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, 546 ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 547 { 548 depthSlice = FixupDepthSlice(depthSlice, cubemapFace); 549 colorBuffer = new RenderTargetIdentifier(colorBuffer, miplevel, cubemapFace, depthSlice); 550 depthBuffer = new RenderTargetIdentifier(depthBuffer, miplevel, cubemapFace, depthSlice); 551 SetRenderTarget(cmd, colorBuffer, colorLoadAction, colorStoreAction, depthBuffer, depthLoadAction, depthStoreAction, clearFlag, clearColor); 552 } 553 554 /// <summary> 555 /// Set the current render texture. 556 /// </summary> 557 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 558 /// <param name="buffer">RenderTargetIdentifier of the render texture.</param> 559 /// <param name="colorLoadAction">Color buffer load action.</param> 560 /// <param name="colorStoreAction">Color buffer store action.</param> 561 /// <param name="depthLoadAction">Depth buffer load action.</param> 562 /// <param name="depthStoreAction">Depth buffer store action.</param> 563 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 564 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 565 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, 566 RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, ClearFlag clearFlag, Color clearColor) 567 { 568 cmd.SetRenderTarget(buffer, colorLoadAction, colorStoreAction, depthLoadAction, depthStoreAction); 569 ClearRenderTarget(cmd, clearFlag, clearColor); 570 } 571 572 /// <summary> 573 /// Set the current render texture. 574 /// </summary> 575 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 576 /// <param name="colorBuffer">Color buffer RenderTargetIdentifier.</param> 577 /// <param name="colorLoadAction">Color buffer load action.</param> 578 /// <param name="colorStoreAction">Color buffer store action.</param> 579 /// <param name="depthBuffer">Depth buffer RenderTargetIdentifier.</param> 580 /// <param name="depthLoadAction">Depth buffer load action.</param> 581 /// <param name="depthStoreAction">Depth buffer store action.</param> 582 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 583 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorBuffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, 584 RenderTargetIdentifier depthBuffer, RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, 585 ClearFlag clearFlag) 586 { 587 SetRenderTarget(cmd, colorBuffer, colorLoadAction, colorStoreAction, depthBuffer, depthLoadAction, depthStoreAction, clearFlag, Color.clear); 588 } 589 590 private static void SetViewportAndClear(CommandBuffer cmd, RTHandle buffer, ClearFlag clearFlag, Color clearColor) 591 { 592 // Clearing a partial viewport currently does not go through the hardware clear. 593 // Instead it goes through a quad rendered with a specific shader. 594 // When enabling wireframe mode in the scene view, unfortunately it overrides this shader thus breaking every clears. 595 // That's why in the editor we don't set the viewport before clearing (it's set to full screen by the previous SetRenderTarget) but AFTER so that we benefit from un-bugged hardware clear. 596 // We consider that the small loss in performance is acceptable in the editor. 597 // A refactor of wireframe is needed before we can fix this properly (with not doing anything!) 598#if !UNITY_EDITOR 599 SetViewport(cmd, buffer); 600#endif 601 CoreUtils.ClearRenderTarget(cmd, clearFlag, clearColor); 602#if UNITY_EDITOR 603 SetViewport(cmd, buffer); 604#endif 605 } 606 607 // This set of RenderTarget management methods is supposed to be used when rendering RTHandle render texture. 608 // This will automatically set the viewport based on the RTHandle System reference size and the RTHandle scaling info. 609 610 /// <summary> 611 /// Setup the current render texture using an RTHandle 612 /// </summary> 613 /// <param name="cmd">CommandBuffer used for rendering commands</param> 614 /// <param name="buffer">Color buffer RTHandle</param> 615 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 616 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 617 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 618 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 619 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 620 public static void SetRenderTarget(CommandBuffer cmd, RTHandle buffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 621 { 622 depthSlice = FixupDepthSlice(depthSlice, buffer); 623 cmd.SetRenderTarget(buffer.nameID, miplevel, cubemapFace, depthSlice); 624 SetViewportAndClear(cmd, buffer, clearFlag, clearColor); 625 } 626 627 /// <summary> 628 /// Setup the current render texture using an RTHandle 629 /// </summary> 630 /// <param name="cmd">CommandBuffer used for rendering commands</param> 631 /// <param name="buffer">Color buffer RTHandle</param> 632 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 633 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 634 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 635 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 636 public static void SetRenderTarget(CommandBuffer cmd, RTHandle buffer, ClearFlag clearFlag = ClearFlag.None, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 637 => SetRenderTarget(cmd, buffer, clearFlag, Color.clear, miplevel, cubemapFace, depthSlice); 638 639 /// <summary> 640 /// Setup the current render texture using an RTHandle 641 /// </summary> 642 /// <param name="cmd">CommandBuffer used for rendering commands</param> 643 /// <param name="colorBuffer">Color buffer RTHandle</param> 644 /// <param name="depthBuffer">Depth buffer RTHandle</param> 645 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 646 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 647 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 648 public static void SetRenderTarget(CommandBuffer cmd, RTHandle colorBuffer, RTHandle depthBuffer, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 649 { 650#if DEVELOPMENT_BUILD || UNITY_EDITOR 651 if (colorBuffer.rt != null && depthBuffer.rt != null) 652 { 653 int cw = colorBuffer.rt.width; 654 int ch = colorBuffer.rt.height; 655 int dw = depthBuffer.rt.width; 656 int dh = depthBuffer.rt.height; 657 658 Debug.Assert(cw == dw && ch == dh); 659 } 660#endif 661 662 SetRenderTarget(cmd, colorBuffer, depthBuffer, ClearFlag.None, Color.clear, miplevel, cubemapFace, depthSlice); 663 } 664 665 /// <summary> 666 /// Setup the current render texture using an RTHandle 667 /// </summary> 668 /// <param name="cmd">CommandBuffer used for rendering commands</param> 669 /// <param name="colorBuffer">Color buffer RTHandle</param> 670 /// <param name="depthBuffer">Depth buffer RTHandle</param> 671 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 672 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 673 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 674 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 675 public static void SetRenderTarget(CommandBuffer cmd, RTHandle colorBuffer, RTHandle depthBuffer, ClearFlag clearFlag, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 676 { 677#if DEVELOPMENT_BUILD || UNITY_EDITOR 678 if (colorBuffer.rt != null && depthBuffer.rt != null) 679 { 680 int cw = colorBuffer.rt.width; 681 int ch = colorBuffer.rt.height; 682 int dw = depthBuffer.rt.width; 683 int dh = depthBuffer.rt.height; 684 685 Debug.Assert(cw == dw && ch == dh); 686 } 687#endif 688 689 SetRenderTarget(cmd, colorBuffer, depthBuffer, clearFlag, Color.clear, miplevel, cubemapFace, depthSlice); 690 } 691 692 /// <summary> 693 /// Setup the current render texture using an RTHandle 694 /// </summary> 695 /// <param name="cmd">CommandBuffer used for rendering commands</param> 696 /// <param name="colorBuffer">Color buffer RTHandle</param> 697 /// <param name="depthBuffer">Depth buffer RTHandle</param> 698 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 699 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 700 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 701 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 702 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 703 public static void SetRenderTarget(CommandBuffer cmd, RTHandle colorBuffer, RTHandle depthBuffer, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 704 { 705#if DEVELOPMENT_BUILD || UNITY_EDITOR 706 if (colorBuffer.rt != null && depthBuffer.rt != null) 707 { 708 int cw = colorBuffer.rt.width; 709 int ch = colorBuffer.rt.height; 710 int dw = depthBuffer.rt.width; 711 int dh = depthBuffer.rt.height; 712 713 Debug.Assert(cw == dw && ch == dh); 714 } 715#endif 716 717 SetRenderTarget(cmd, colorBuffer.nameID, depthBuffer.nameID, miplevel, cubemapFace, depthSlice); 718 SetViewportAndClear(cmd, colorBuffer, clearFlag, clearColor); 719 } 720 721 // Explicit load and store actions 722 /// <summary> 723 /// Set the current render texture. 724 /// </summary> 725 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 726 /// <param name="buffer">Color buffer RTHandleRTR.</param> 727 /// <param name="loadAction">Load action.</param> 728 /// <param name="storeAction">Store action.</param> 729 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 730 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 731 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 732 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 733 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 734 public static void SetRenderTarget(CommandBuffer cmd, RTHandle buffer, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 735 { 736 SetRenderTarget(cmd, buffer.nameID, loadAction, storeAction, miplevel, cubemapFace, depthSlice); 737 SetViewportAndClear(cmd, buffer, clearFlag, clearColor); 738 } 739 740 /// <summary> 741 /// Set the current render texture. 742 /// </summary> 743 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 744 /// <param name="colorBuffer">Color buffer RTHandle.</param> 745 /// <param name="colorLoadAction">Color buffer load action.</param> 746 /// <param name="colorStoreAction">Color buffer store action.</param> 747 /// <param name="depthBuffer">Depth buffer RTHandle.</param> 748 /// <param name="depthLoadAction">Depth buffer load action.</param> 749 /// <param name="depthStoreAction">Depth buffer store action.</param> 750 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 751 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 752 /// <param name="miplevel">Mip level that should be bound as a render texture if applicable.</param> 753 /// <param name="cubemapFace">Cubemap face that should be bound as a render texture if applicable.</param> 754 /// <param name="depthSlice">Depth slice that should be bound as a render texture if applicable.</param> 755 public static void SetRenderTarget(CommandBuffer cmd, RTHandle colorBuffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, 756 RTHandle depthBuffer, RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, 757 ClearFlag clearFlag, Color clearColor, int miplevel = 0, CubemapFace cubemapFace = CubemapFace.Unknown, int depthSlice = -1) 758 { 759#if DEVELOPMENT_BUILD || UNITY_EDITOR 760 if (colorBuffer.rt != null && depthBuffer.rt != null) 761 { 762 int cw = colorBuffer.rt.width; 763 int ch = colorBuffer.rt.height; 764 int dw = depthBuffer.rt.width; 765 int dh = depthBuffer.rt.height; 766 767 Debug.Assert(cw == dw && ch == dh); 768 } 769#endif 770 771 SetRenderTarget(cmd, colorBuffer.nameID, colorLoadAction, colorStoreAction, depthBuffer.nameID, depthLoadAction, depthStoreAction, miplevel, cubemapFace, depthSlice); 772 SetViewportAndClear(cmd, colorBuffer, clearFlag, clearColor); 773 } 774 775 /// <summary> 776 /// Set the current multiple render texture. 777 /// </summary> 778 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 779 /// <param name="colorBuffers">RenderTargetIdentifier array of the color render textures.</param> 780 /// <param name="depthBuffer">Depth Buffer RTHandle.</param> 781 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RTHandle depthBuffer) 782 { 783 SetRenderTarget(cmd, colorBuffers, depthBuffer.nameID, ClearFlag.None, Color.clear); 784 SetViewport(cmd, depthBuffer); 785 } 786 787 /// <summary> 788 /// Set the current multiple render texture. 789 /// </summary> 790 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 791 /// <param name="colorBuffers">RenderTargetIdentifier array of the color render textures.</param> 792 /// <param name="depthBuffer">Depth Buffer RTHandle.</param> 793 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 794 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RTHandle depthBuffer, ClearFlag clearFlag = ClearFlag.None) 795 { 796 SetRenderTarget(cmd, colorBuffers, depthBuffer.nameID); // Don't clear here, viewport needs to be set before we do. 797 SetViewportAndClear(cmd, depthBuffer, clearFlag, Color.clear); 798 } 799 800 /// <summary> 801 /// Set the current multiple render texture. 802 /// </summary> 803 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 804 /// <param name="colorBuffers">RenderTargetIdentifier array of the color render textures.</param> 805 /// <param name="depthBuffer">Depth Buffer RTHandle.</param> 806 /// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param> 807 /// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param> 808 public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier[] colorBuffers, RTHandle depthBuffer, ClearFlag clearFlag, Color clearColor) 809 { 810 cmd.SetRenderTarget(colorBuffers, depthBuffer.nameID, 0, CubemapFace.Unknown, -1); 811 SetViewportAndClear(cmd, depthBuffer, clearFlag, clearColor); 812 } 813 814 // Scaling viewport is done for auto-scaling render targets. 815 // In the context of SRP, every auto-scaled RT is scaled against the maximum RTHandles reference size (that can only grow). 816 // When we render using a camera whose viewport is smaller than the RTHandles reference size (and thus smaller than the RT actual size), we need to set it explicitly (otherwise, native code will set the viewport at the size of the RT) 817 // For auto-scaled RTs (like for example a half-resolution RT), we need to scale this viewport accordingly. 818 // For non scaled RTs we just do nothing, the native code will set the viewport at the size of the RT anyway. 819 820 /// <summary> 821 /// Setup the viewport to the size of the provided RTHandle. 822 /// </summary> 823 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 824 /// <param name="target">RTHandle from which to compute the proper viewport.</param> 825 public static void SetViewport(CommandBuffer cmd, RTHandle target) 826 { 827 if (target.useScaling) 828 { 829 Vector2Int scaledViewportSize = target.GetScaledSize(target.rtHandleProperties.currentViewportSize); 830 cmd.SetViewport(new Rect(0.0f, 0.0f, scaledViewportSize.x, scaledViewportSize.y)); 831 } 832 } 833 834 /// <summary> 835 /// Generate a name based on render texture parameters. 836 /// </summary> 837 /// <param name="width">With of the texture.</param> 838 /// <param name="height">Height of the texture.</param> 839 /// <param name="depth">Depth of the texture.</param> 840 /// <param name="format">Format of the render texture.</param> 841 /// <param name="name">Base name of the texture.</param> 842 /// <param name="mips">True if the texture has mip maps.</param> 843 /// <param name="enableMSAA">True if the texture is multisampled.</param> 844 /// <param name="msaaSamples">Number of MSAA samples.</param> 845 /// <returns>Generated names bassed on the provided parameters.</returns> 846 public static string GetRenderTargetAutoName(int width, int height, int depth, RenderTextureFormat format, string name, bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None) 847 => GetRenderTargetAutoName(width, height, depth, format.ToString(), TextureDimension.None, name, mips, enableMSAA, msaaSamples, dynamicRes: false, dynamicResExplicit: false); 848 849 /// <summary> 850 /// Generate a name based on render texture parameters. 851 /// </summary> 852 /// <param name="width">With of the texture.</param> 853 /// <param name="height">Height of the texture.</param> 854 /// <param name="depth">Depth of the texture.</param> 855 /// <param name="format">Graphics format of the render texture.</param> 856 /// <param name="name">Base name of the texture.</param> 857 /// <param name="mips">True if the texture has mip maps.</param> 858 /// <param name="enableMSAA">True if the texture is multisampled.</param> 859 /// <param name="msaaSamples">Number of MSAA samples.</param> 860 /// <returns>Generated names bassed on the provided parameters.</returns> 861 public static string GetRenderTargetAutoName(int width, int height, int depth, GraphicsFormat format, string name, bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None) 862 => GetRenderTargetAutoName(width, height, depth, format.ToString(), TextureDimension.None, name, mips, enableMSAA, msaaSamples, dynamicRes: false, dynamicResExplicit: false); 863 864 /// <summary> 865 /// Generate a name based on render texture parameters. 866 /// </summary> 867 /// <param name="width">With of the texture.</param> 868 /// <param name="height">Height of the texture.</param> 869 /// <param name="depth">Depth of the texture.</param> 870 /// <param name="format">Graphics format of the render texture.</param> 871 /// <param name="dim">Dimension of the texture.</param> 872 /// <param name="name">Base name of the texture.</param> 873 /// <param name="mips">True if the texture has mip maps.</param> 874 /// <param name="enableMSAA">True if the texture is multisampled.</param> 875 /// <param name="msaaSamples">Number of MSAA samples.</param> 876 /// <param name="dynamicRes">True if the texture uses dynamic resolution.</param> 877 /// <param name="dynamicResExplicit">True if the texture uses dynamic resolution with explicit resize control.</param> 878 /// <returns>Generated names bassed on the provided parameters.</returns> 879 public static string GetRenderTargetAutoName(int width, int height, int depth, GraphicsFormat format, TextureDimension dim, string name, bool mips = false, bool enableMSAA = false, MSAASamples msaaSamples = MSAASamples.None, bool dynamicRes = false, bool dynamicResExplicit = false) 880 => GetRenderTargetAutoName(width, height, depth, format.ToString(), dim, name, mips, enableMSAA, msaaSamples, dynamicRes, dynamicResExplicit); 881 882 static string GetRenderTargetAutoName(int width, int height, int depth, string format, TextureDimension dim, string name, bool mips, bool enableMSAA, MSAASamples msaaSamples, bool dynamicRes, bool dynamicResExplicit) 883 { 884 string result = string.Format("{0}_{1}x{2}", name, width, height); 885 886 if (depth > 1) 887 result = string.Format("{0}x{1}", result, depth); 888 889 if (mips) 890 result = string.Format("{0}_{1}", result, "Mips"); 891 892 result = string.Format("{0}_{1}", result, format); 893 894 if (dim != TextureDimension.None) 895 result = string.Format("{0}_{1}", result, dim); 896 897 if (enableMSAA) 898 result = string.Format("{0}_{1}", result, msaaSamples.ToString()); 899 900 if (dynamicRes) 901 result = string.Format("{0}_{1}", result, "Dynamic"); 902 903 if (dynamicResExplicit) 904 result = string.Format("{0}_{1}", result, "DynamicExplicit"); 905 906 return result; 907 } 908 909 /// <summary> 910 /// Generate a name based on texture parameters. 911 /// </summary> 912 /// <param name="width">With of the texture.</param> 913 /// <param name="height">Height of the texture.</param> 914 /// <param name="format">Format of the texture.</param> 915 /// <param name="dim">Dimension of the texture.</param> 916 /// <param name="name">Base name of the texture.</param> 917 /// <param name="mips">True if the texture has mip maps.</param> 918 /// <param name="depth">Depth of the texture.</param> 919 /// <returns>Generated names based on the provided parameters.</returns> 920 public static string GetTextureAutoName(int width, int height, TextureFormat format, TextureDimension dim = TextureDimension.None, string name = "", bool mips = false, int depth = 0) 921 => GetTextureAutoName(width, height, format.ToString(), dim, name, mips, depth); 922 923 /// <summary> 924 /// Generate a name based on texture parameters. 925 /// </summary> 926 /// <param name="width">With of the texture.</param> 927 /// <param name="height">Height of the texture.</param> 928 /// <param name="format">Graphics format of the texture.</param> 929 /// <param name="dim">Dimension of the texture.</param> 930 /// <param name="name">Base name of the texture.</param> 931 /// <param name="mips">True if the texture has mip maps.</param> 932 /// <param name="depth">Depth of the texture.</param> 933 /// <returns>Generated names based on the provided parameters.</returns> 934 public static string GetTextureAutoName(int width, int height, GraphicsFormat format, TextureDimension dim = TextureDimension.None, string name = "", bool mips = false, int depth = 0) 935 => GetTextureAutoName(width, height, format.ToString(), dim, name, mips, depth); 936 937 static string GetTextureAutoName(int width, int height, string format, TextureDimension dim = TextureDimension.None, string name = "", bool mips = false, int depth = 0) 938 { 939 string temp; 940 if (depth == 0) 941 temp = string.Format("{0}x{1}{2}_{3}", width, height, mips ? "_Mips" : "", format); 942 else 943 temp = string.Format("{0}x{1}x{2}{3}_{4}", width, height, depth, mips ? "_Mips" : "", format); 944 temp = String.Format("{0}_{1}_{2}", name == "" ? "Texture" : name, (dim == TextureDimension.None) ? "" : dim.ToString(), temp); 945 946 return temp; 947 } 948 949 /// <summary> 950 /// Clear a cubemap render texture. 951 /// </summary> 952 /// <param name="cmd">CommandBuffer used for rendering commands.</param> 953 /// <param name="renderTexture">Cubemap render texture that needs to be cleared.</param> 954 /// <param name="clearColor">Color used for clearing.</param> 955 /// <param name="clearMips">Set to true to clear the mip maps of the render texture.</param> 956 public static void ClearCubemap(CommandBuffer cmd, RenderTexture renderTexture, Color clearColor, bool clearMips = false) 957 { 958 int mipCount = 1; 959 if (renderTexture.useMipMap && clearMips) 960 { 961 mipCount = (int)Mathf.Log((float)renderTexture.width, 2.0f) + 1; 962 } 963 964 for (int i = 0; i < 6; ++i) 965 { 966 for (int mip = 0; mip < mipCount; ++mip) 967 { 968 SetRenderTarget(cmd, new RenderTargetIdentifier(renderTexture), ClearFlag.Color, clearColor, mip, (CubemapFace)i); 969 } 970 } 971 } 972 973 /// <summary> 974 /// Draws a full screen triangle. 975 /// </summary> 976 /// <param name="commandBuffer">CommandBuffer used for rendering commands.</param> 977 /// <param name="material">Material used on the full screen triangle.</param> 978 /// <param name="properties">Optional material property block for the provided material.</param> 979 /// <param name="shaderPassId">Index of the material pass.</param> 980 public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, 981 MaterialPropertyBlock properties = null, int shaderPassId = 0) 982 { 983 commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); 984 } 985 986 /// <summary> 987 /// Draws a full screen triangle. 988 /// </summary> 989 /// <param name="commandBuffer">RasterCommandBuffer used for rendering commands.</param> 990 /// <param name="material">Material used on the full screen triangle.</param> 991 /// <param name="properties">Optional material property block for the provided material.</param> 992 /// <param name="shaderPassId">Index of the material pass.</param> 993 public static void DrawFullScreen(RasterCommandBuffer commandBuffer, Material material, 994 MaterialPropertyBlock properties = null, int shaderPassId = 0) 995 { 996 DrawFullScreen(commandBuffer.m_WrappedCommandBuffer, material, properties, shaderPassId); 997 } 998 999 /// <summary> 1000 /// Draws a full screen triangle. 1001 /// </summary> 1002 /// <param name="commandBuffer">CommandBuffer used for rendering commands.</param> 1003 /// <param name="material">Material used on the full screen triangle.</param> 1004 /// <param name="colorBuffer">RenderTargetIdentifier of the color buffer that needs to be set before drawing the full screen triangle.</param> 1005 /// <param name="properties">Optional material property block for the provided material.</param> 1006 /// <param name="shaderPassId">Index of the material pass.</param> 1007 public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, 1008 RenderTargetIdentifier colorBuffer, 1009 MaterialPropertyBlock properties = null, int shaderPassId = 0) 1010 { 1011 commandBuffer.SetRenderTarget(colorBuffer, 0, CubemapFace.Unknown, -1); 1012 commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); 1013 } 1014 1015 /// <summary> 1016 /// Draws a full screen triangle. 1017 /// </summary> 1018 /// <param name="commandBuffer">CommandBuffer used for rendering commands.</param> 1019 /// <param name="material">Material used on the full screen triangle.</param> 1020 /// <param name="colorBuffer">RenderTargetIdentifier of the color buffer that needs to be set before drawing the full screen triangle.</param> 1021 /// <param name="depthStencilBuffer">RenderTargetIdentifier of the depth buffer that needs to be set before drawing the full screen triangle.</param> 1022 /// <param name="properties">Optional material property block for the provided material.</param> 1023 /// <param name="shaderPassId">Index of the material pass.</param> 1024 public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, 1025 RenderTargetIdentifier colorBuffer, RenderTargetIdentifier depthStencilBuffer, 1026 MaterialPropertyBlock properties = null, int shaderPassId = 0) 1027 { 1028 commandBuffer.SetRenderTarget(colorBuffer, depthStencilBuffer, 0, CubemapFace.Unknown, -1); 1029 commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); 1030 } 1031 1032 /// <summary> 1033 /// Draws a full screen triangle. 1034 /// </summary> 1035 /// <param name="commandBuffer">CommandBuffer used for rendering commands.</param> 1036 /// <param name="material">Material used on the full screen triangle.</param> 1037 /// <param name="colorBuffers">RenderTargetIdentifier array of the color buffers that needs to be set before drawing the full screen triangle.</param> 1038 /// <param name="depthStencilBuffer">RenderTargetIdentifier of the depth buffer that needs to be set before drawing the full screen triangle.</param> 1039 /// <param name="properties">Optional material property block for the provided material.</param> 1040 /// <param name="shaderPassId">Index of the material pass.</param> 1041 public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, 1042 RenderTargetIdentifier[] colorBuffers, RenderTargetIdentifier depthStencilBuffer, 1043 MaterialPropertyBlock properties = null, int shaderPassId = 0) 1044 { 1045 commandBuffer.SetRenderTarget(colorBuffers, depthStencilBuffer, 0, CubemapFace.Unknown, -1); 1046 commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassId, MeshTopology.Triangles, 3, 1, properties); 1047 } 1048 1049 // Important: the first RenderTarget must be created with 0 depth bits! 1050 1051 /// <summary> 1052 /// Draws a full screen triangle. 1053 /// </summary> 1054 /// <param name="commandBuffer">CommandBuffer used for rendering commands.</param> 1055 /// <param name="material">Material used on the full screen triangle.</param> 1056 /// <param name="colorBuffers">RenderTargetIdentifier array of the color buffers that needs to be set before drawing the full screen triangle.</param> 1057 /// <param name="properties">Optional material property block for the provided material.</param> 1058 /// <param name="shaderPassId">Index of the material pass.</param> 1059 public static void DrawFullScreen(CommandBuffer commandBuffer, Material material, 1060 RenderTargetIdentifier[] colorBuffers, 1061 MaterialPropertyBlock properties = null, int shaderPassId = 0) 1062 { 1063 // It is currently not possible to have MRT without also setting a depth target. 1064 // To work around this deficiency of the CommandBuffer.SetRenderTarget() API, 1065 // we pass the first color target as the depth target. If it has 0 depth bits, 1066 // no depth target ends up being bound. 1067 DrawFullScreen(commandBuffer, material, colorBuffers, colorBuffers[0], properties, shaderPassId); 1068 } 1069 1070 // Color space utilities 1071 /// <summary> 1072 /// Converts the provided sRGB color to the current active color space. 1073 /// </summary> 1074 /// <param name="color">Input color.</param> 1075 /// <returns>Linear color if the active color space is ColorSpace.Linear, the original input otherwise.</returns> 1076 public static Color ConvertSRGBToActiveColorSpace(Color color) 1077 { 1078 return (QualitySettings.activeColorSpace == ColorSpace.Linear) ? color.linear : color; 1079 } 1080 1081 /// <summary> 1082 /// Converts the provided linear color to the current active color space. 1083 /// </summary> 1084 /// <param name="color">Input color.</param> 1085 /// <returns>sRGB color if the active color space is ColorSpace.Gamma, the original input otherwise.</returns> 1086 public static Color ConvertLinearToActiveColorSpace(Color color) 1087 { 1088 return (QualitySettings.activeColorSpace == ColorSpace.Linear) ? color : color.gamma; 1089 } 1090 1091 /// <summary> 1092 /// Creates a Material with the provided shader path. 1093 /// hideFlags will be set to HideFlags.HideAndDontSave. 1094 /// </summary> 1095 /// <param name="shaderPath">Path of the shader used for the material.</param> 1096 /// <returns>A new Material instance using the shader found at the provided path.</returns> 1097 public static Material CreateEngineMaterial(string shaderPath) 1098 { 1099 if (string.IsNullOrEmpty(shaderPath)) 1100 throw new ArgumentException(nameof(shaderPath)); 1101 1102 Shader shader = Shader.Find(shaderPath); 1103 if (shader == null) 1104 { 1105 Debug.LogError("Cannot create required material because shader " + shaderPath + " could not be found"); 1106 return null; 1107 } 1108 1109 return CreateEngineMaterial(shader); 1110 } 1111 1112 /// <summary> 1113 /// Creates a Material with the provided shader. 1114 /// hideFlags will be set to HideFlags.HideAndDontSave. 1115 /// </summary> 1116 /// <param name="shader">Shader used for the material.</param> 1117 /// <returns>A new Material instance using the provided shader.</returns> 1118 public static Material CreateEngineMaterial(Shader shader) 1119 { 1120 if (shader == null) 1121 { 1122 Debug.LogError("Cannot create required material because shader is null"); 1123 return null; 1124 } 1125 1126 1127 return new Material(shader) 1128 { 1129 hideFlags = HideFlags.HideAndDontSave 1130 }; 1131 } 1132 1133 /// <summary> 1134 /// Bitfield flag test. 1135 /// </summary> 1136 /// <typeparam name="T">Type of the enum flag.</typeparam> 1137 /// <param name="mask">Bitfield to test the flag against.</param> 1138 /// <param name="flag">Flag to be tested against the provided mask.</param> 1139 /// <returns>True if the flag is present in the mask.</returns> 1140 public static bool HasFlag<T>(T mask, T flag) where T : IConvertible 1141 { 1142 return (mask.ToUInt32(null) & flag.ToUInt32(null)) != 0; 1143 } 1144 1145 /// <summary> 1146 /// Swaps two values. 1147 /// </summary> 1148 /// <typeparam name="T">Type of the values</typeparam> 1149 /// <param name="a">First value.</param> 1150 /// <param name="b">Second value.</param> 1151 public static void Swap<T>(ref T a, ref T b) 1152 { 1153 var tmp = a; 1154 a = b; 1155 b = tmp; 1156 } 1157 1158 /// <summary> 1159 /// Set a global keyword using a CommandBuffer 1160 /// </summary> 1161 /// <param name="cmd">CommandBuffer on which to set the global keyword.</param> 1162 /// <param name="keyword">Keyword to be set.</param> 1163 /// <param name="state">Value of the keyword to be set.</param> 1164 public static void SetKeyword(CommandBuffer cmd, string keyword, bool state) 1165 { 1166 if (state) 1167 cmd.EnableShaderKeyword(keyword); 1168 else 1169 cmd.DisableShaderKeyword(keyword); 1170 } 1171 1172 /// <summary> 1173 /// Set a local keyword on a ComputeShader using a CommandBuffer 1174 /// </summary> 1175 /// <param name="cmd">CommandBuffer on which to set the global keyword.</param> 1176 /// <param name="cs">Compute Shader on which to set the keyword.</param> 1177 /// <param name="keyword">Keyword to be set.</param> 1178 /// <param name="state">Value of the keyword to be set.</param> 1179 public static void SetKeyword(CommandBuffer cmd, ComputeShader cs, string keyword, bool state) 1180 { 1181 var kw = new LocalKeyword(cs, keyword); 1182 if (state) 1183 cmd.EnableKeyword(cs, kw); 1184 else 1185 cmd.DisableKeyword(cs, kw); 1186 } 1187 1188 /// <summary> 1189 /// Set a global keyword using a RasterCommandBuffer 1190 /// </summary> 1191 /// <param name="cmd">CommandBuffer on which to set the global keyword.</param> 1192 /// <param name="keyword">Keyword to be set.</param> 1193 /// <param name="state">Value of the keyword to be set.</param> 1194 public static void SetKeyword(BaseCommandBuffer cmd, string keyword, bool state) 1195 { 1196 if (state) 1197 cmd.m_WrappedCommandBuffer.EnableShaderKeyword(keyword); 1198 else 1199 cmd.m_WrappedCommandBuffer.DisableShaderKeyword(keyword); 1200 } 1201 1202 // Caution: such a call should not be use interleaved with command buffer command, as it is immediate 1203 /// <summary> 1204 /// Set a keyword immediately on a Material. 1205 /// </summary> 1206 /// <param name="material">Material on which to set the keyword.</param> 1207 /// <param name="keyword">Keyword to set on the material.</param> 1208 /// <param name="state">Value of the keyword to set on the material.</param> 1209 public static void SetKeyword(Material material, string keyword, bool state) 1210 { 1211 if (state) 1212 material.EnableKeyword(keyword); 1213 else 1214 material.DisableKeyword(keyword); 1215 } 1216 1217 // Caution: such a call should not be use interleaved with command buffer command, as it is immediate 1218 /// <summary> 1219 /// Set a keyword immediately on a Material. 1220 /// </summary> 1221 /// <param name="material">Material on which to set the keyword.</param> 1222 /// <param name="keyword">Keyword to set on the material.</param> 1223 /// <param name="state">Value of the keyword to set on the material.</param> 1224 public static void SetKeyword(Material material, LocalKeyword keyword, bool state) 1225 { 1226 if (state) 1227 material.EnableKeyword(keyword); 1228 else 1229 material.DisableKeyword(keyword); 1230 } 1231 1232 // Caution: such a call should not be use interleaved with command buffer command, as it is immediate 1233 /// <summary> 1234 /// Set a keyword immediately on a compute shader 1235 /// </summary> 1236 /// <param name="cs">Compute Shader on which to set the keyword.</param> 1237 /// <param name="keyword">Keyword to be set.</param> 1238 /// <param name="state">Value of the keyword to be set.</param> 1239 public static void SetKeyword(ComputeShader cs, string keyword, bool state) 1240 { 1241 if (state) 1242 cs.EnableKeyword(keyword); 1243 else 1244 cs.DisableKeyword(keyword); 1245 } 1246 1247 /// <summary> 1248 /// Destroys a UnityObject safely. 1249 /// </summary> 1250 /// <param name="obj">Object to be destroyed.</param> 1251 public static void Destroy(UnityObject obj) 1252 { 1253 if (obj != null) 1254 { 1255#if UNITY_EDITOR 1256 if (Application.isPlaying && !UnityEditor.EditorApplication.isPaused) 1257 UnityObject.Destroy(obj); 1258 else 1259 UnityObject.DestroyImmediate(obj); 1260#else 1261 UnityObject.Destroy(obj); 1262#endif 1263 } 1264 } 1265 1266 static IEnumerable<Type> m_AssemblyTypes; 1267 1268 /// <summary> 1269 /// Returns all assembly types. 1270 /// </summary> 1271 /// <returns>The list of all assembly types of the current domain.</returns> 1272 public static IEnumerable<Type> GetAllAssemblyTypes() 1273 { 1274 if (m_AssemblyTypes == null) 1275 { 1276 m_AssemblyTypes = AppDomain.CurrentDomain.GetAssemblies() 1277 .SelectMany(t => 1278 { 1279 // Ugly hack to handle mis-versioned dlls 1280 var innerTypes = new Type[0]; 1281 try 1282 { 1283 innerTypes = t.GetTypes(); 1284 } 1285 catch { } 1286 return innerTypes; 1287 }); 1288 } 1289 1290 return m_AssemblyTypes; 1291 } 1292 1293 /// <summary> 1294 /// Returns a list of types that inherit from the provided type. 1295 /// </summary> 1296 /// <typeparam name="T">Parent Type</typeparam> 1297 /// <returns>A list of types that inherit from the provided type.</returns> 1298 public static IEnumerable<Type> GetAllTypesDerivedFrom<T>() 1299 { 1300#if UNITY_EDITOR && UNITY_2019_2_OR_NEWER 1301 return UnityEditor.TypeCache.GetTypesDerivedFrom<T>(); 1302#else 1303 return GetAllAssemblyTypes().Where(t => t.IsSubclassOf(typeof(T))); 1304#endif 1305 } 1306 1307 /// <summary> 1308 /// Safely release a Graphics Buffer. 1309 /// </summary> 1310 /// <param name="buffer">Graphics Buffer that needs to be released.</param> 1311 public static void SafeRelease(GraphicsBuffer buffer) 1312 { 1313 if (buffer != null) 1314 buffer.Release(); 1315 } 1316 1317 /// <summary> 1318 /// Safely release a Compute Buffer. 1319 /// </summary> 1320 /// <param name="buffer">Compute Buffer that needs to be released.</param> 1321 public static void SafeRelease(ComputeBuffer buffer) 1322 { 1323 if (buffer != null) 1324 buffer.Release(); 1325 } 1326 1327 /// <summary> 1328 /// Creates a cube mesh. 1329 /// </summary> 1330 /// <param name="min">Minimum corner coordinates in local space.</param> 1331 /// <param name="max">Maximum corner coordinates in local space.</param> 1332 /// <returns>A new instance of a cube Mesh.</returns> 1333 public static Mesh CreateCubeMesh(Vector3 min, Vector3 max) 1334 { 1335 Mesh mesh = new Mesh(); 1336 1337 Vector3[] vertices = new Vector3[8]; 1338 1339 vertices[0] = new Vector3(min.x, min.y, min.z); 1340 vertices[1] = new Vector3(max.x, min.y, min.z); 1341 vertices[2] = new Vector3(max.x, max.y, min.z); 1342 vertices[3] = new Vector3(min.x, max.y, min.z); 1343 vertices[4] = new Vector3(min.x, min.y, max.z); 1344 vertices[5] = new Vector3(max.x, min.y, max.z); 1345 vertices[6] = new Vector3(max.x, max.y, max.z); 1346 vertices[7] = new Vector3(min.x, max.y, max.z); 1347 1348 mesh.vertices = vertices; 1349 1350 int[] triangles = new int[36]; 1351 1352 triangles[0] = 0; triangles[1] = 2; triangles[2] = 1; 1353 triangles[3] = 0; triangles[4] = 3; triangles[5] = 2; 1354 triangles[6] = 1; triangles[7] = 6; triangles[8] = 5; 1355 triangles[9] = 1; triangles[10] = 2; triangles[11] = 6; 1356 triangles[12] = 5; triangles[13] = 7; triangles[14] = 4; 1357 triangles[15] = 5; triangles[16] = 6; triangles[17] = 7; 1358 triangles[18] = 4; triangles[19] = 3; triangles[20] = 0; 1359 triangles[21] = 4; triangles[22] = 7; triangles[23] = 3; 1360 triangles[24] = 3; triangles[25] = 6; triangles[26] = 2; 1361 triangles[27] = 3; triangles[28] = 7; triangles[29] = 6; 1362 triangles[30] = 4; triangles[31] = 1; triangles[32] = 5; 1363 triangles[33] = 4; triangles[34] = 0; triangles[35] = 1; 1364 1365 mesh.triangles = triangles; 1366 return mesh; 1367 } 1368 1369 /// <summary> 1370 /// Returns true if "Post Processes" are enabled for the view associated with the given camera. 1371 /// </summary> 1372 /// <param name="camera">Input camera.</param> 1373 /// <returns>True if "Post Processes" are enabled for the view associated with the given camera.</returns> 1374 public static bool ArePostProcessesEnabled(Camera camera) 1375 { 1376 bool enabled = true; 1377 1378#if UNITY_EDITOR 1379 if (camera.cameraType == CameraType.SceneView) 1380 { 1381 enabled = false; 1382 1383 // Determine whether the "Post Processes" checkbox is checked for the current view. 1384 for (int i = 0; i < UnityEditor.SceneView.sceneViews.Count; i++) 1385 { 1386 var sv = UnityEditor.SceneView.sceneViews[i] as UnityEditor.SceneView; 1387 1388 // Post-processing is disabled in scene view if either showImageEffects is disabled or we are 1389 // rendering in wireframe mode. 1390 if (sv.camera == camera && 1391 (sv.sceneViewState.imageEffectsEnabled && sv.cameraMode.drawMode != UnityEditor.DrawCameraMode.Wireframe)) 1392 { 1393 enabled = true; 1394 break; 1395 } 1396 } 1397 } 1398#endif 1399 1400 return enabled; 1401 } 1402 1403 /// <summary> 1404 /// Returns true if "Animated Materials" are enabled for the view associated with the given camera. 1405 /// </summary> 1406 /// <param name="camera">Input camera.</param> 1407 /// <returns>True if "Animated Materials" are enabled for the view associated with the given camera.</returns> 1408 public static bool AreAnimatedMaterialsEnabled(Camera camera) 1409 { 1410 bool animateMaterials = true; 1411 1412#if UNITY_EDITOR 1413 animateMaterials = Application.isPlaying; // For Game and VR views; Reflection views pass the parent camera 1414 1415 if (camera.cameraType == CameraType.SceneView) 1416 { 1417 animateMaterials = false; 1418 1419 // Determine whether the "Animated Materials" checkbox is checked for the current view. 1420 for (int i = 0; i < UnityEditor.SceneView.sceneViews.Count; i++) // Using a foreach on an ArrayList generates garbage ... 1421 { 1422 var sv = UnityEditor.SceneView.sceneViews[i] as UnityEditor.SceneView; 1423#if UNITY_2020_2_OR_NEWER 1424 if (sv.camera == camera && sv.sceneViewState.alwaysRefreshEnabled) 1425#else 1426 if (sv.camera == camera && sv.sceneViewState.materialUpdateEnabled) 1427#endif 1428 { 1429 animateMaterials = true; 1430 break; 1431 } 1432 } 1433 } 1434 else if (camera.cameraType == CameraType.Preview) 1435 { 1436 // Enable for previews so the shader graph main preview works with time parameters. 1437 animateMaterials = true; 1438 } 1439 else if (camera.cameraType == CameraType.Reflection) 1440 { 1441 // Reflection cameras should be handled outside this function. 1442 // Debug.Assert(false, "Unexpected View type."); 1443 } 1444 1445 // IMHO, a better solution would be: 1446 // A window invokes a camera render. The camera knows which window called it, so it can query its properies 1447 // (such as animated materials). This camera provides the space-time position. It should also be able 1448 // to access the rendering settings somehow. Using this information, it is then able to construct the 1449 // primary view with information about camera-relative rendering, LOD, time, rendering passes/features 1450 // enabled, etc. We then render this view. It can have multiple sub-views (shadows, reflections). 1451 // They inherit all the properties of the primary view, but also have the ability to override them 1452 // (e.g. primary cam pos and time are retained, matrices are modified, SSS and tessellation are disabled). 1453 // These views can then have multiple sub-views (probably not practical for games), 1454 // which simply amounts to a recursive call, and then the story repeats itself. 1455 // 1456 // TLDR: we need to know the caller and its status/properties to make decisions. 1457#endif 1458 1459 return animateMaterials; 1460 } 1461 1462 /// <summary> 1463 /// Returns true if "Scene Lighting" is enabled for the view associated with the given camera. 1464 /// </summary> 1465 /// <param name="camera">Input camera.</param> 1466 /// <returns>True if "Scene Lighting" is enabled for the view associated with the given camera.</returns> 1467 public static bool IsSceneLightingDisabled(Camera camera) 1468 { 1469 bool disabled = false; 1470#if UNITY_EDITOR 1471 if (camera.cameraType == CameraType.SceneView) 1472 { 1473 // Determine whether the "No Scene Lighting" checkbox is checked for the current view. 1474 for (int i = 0; i < UnityEditor.SceneView.sceneViews.Count; i++) 1475 { 1476 var sv = UnityEditor.SceneView.sceneViews[i] as UnityEditor.SceneView; 1477 if (sv.camera == camera && !sv.sceneLighting) 1478 { 1479 disabled = true; 1480 break; 1481 } 1482 } 1483 } 1484#endif 1485 return disabled; 1486 } 1487 1488 /// <summary> 1489 /// Returns true if the "Light Overlap" scene view draw mode is enabled. 1490 /// </summary> 1491 /// <param name="camera">Input camera.</param> 1492 /// <returns>True if "Light Overlap" is enabled in the scene view associated with the input camera.</returns> 1493 public static bool IsLightOverlapDebugEnabled(Camera camera) 1494 { 1495 bool enabled = false; 1496#if UNITY_EDITOR 1497 if (camera.cameraType == CameraType.SceneView) 1498 { 1499 // Determine whether the "LightOverlap" mode is enabled for the current view. 1500 for (int i = 0; i < UnityEditor.SceneView.sceneViews.Count; i++) 1501 { 1502 var sv = UnityEditor.SceneView.sceneViews[i] as UnityEditor.SceneView; 1503 if (sv.camera == camera && sv.cameraMode.drawMode == UnityEditor.DrawCameraMode.LightOverlap) 1504 { 1505 enabled = true; 1506 break; 1507 } 1508 } 1509 } 1510#endif 1511 return enabled; 1512 } 1513 1514 /// <summary> 1515 /// Returns true if "Fog" is enabled for the view associated with the given camera. 1516 /// </summary> 1517 /// <param name="camera">Input camera.</param> 1518 /// <returns>True if "Fog" is enabled for the view associated with the given camera.</returns> 1519 public static bool IsSceneViewFogEnabled(Camera camera) 1520 { 1521 bool fogEnable = true; 1522 1523#if UNITY_EDITOR 1524 if (camera.cameraType == CameraType.SceneView) 1525 { 1526 fogEnable = false; 1527 1528 var sceneViews = UnityEditor.SceneView.sceneViews; 1529 // Determine whether the "Animated Materials" checkbox is checked for the current view. 1530 for (int i = 0; i < sceneViews.Count; i++) 1531 { 1532 if (sceneViews[i] is UnityEditor.SceneView sv && sv.camera == camera && sv.sceneViewState.fogEnabled) 1533 { 1534 fogEnable = true; 1535 break; 1536 } 1537 } 1538 } 1539#endif 1540 1541 return fogEnable; 1542 } 1543 1544 /// <summary> 1545 /// Returns true if any Scene view is using the Scene filtering. 1546 /// </summary> 1547 /// <returns>True if any Scene view is using the Scene filtering.</returns> 1548 public static bool IsSceneFilteringEnabled() 1549 { 1550#if UNITY_EDITOR && UNITY_2021_2_OR_NEWER 1551 var sceneViews = UnityEditor.SceneView.sceneViews; 1552 for (int i = 0; i < sceneViews.Count; i++) 1553 { 1554 if (sceneViews[i] is UnityEditor.SceneView sv && sv.isUsingSceneFiltering) 1555 return true; 1556 } 1557#endif 1558 return false; 1559 } 1560 1561#if UNITY_EDITOR 1562 static Func<int> s_GetSceneViewPrefabStageContextFunc = null; 1563 1564 static Func<int> LoadSceneViewMethods() 1565 { 1566 var stageNavigatorManager = typeof(UnityEditor.SceneManagement.PrefabStage).Assembly.GetType("UnityEditor.SceneManagement.StageNavigationManager"); 1567 var instance = stageNavigatorManager.GetProperty("instance", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy); 1568 var renderMode = stageNavigatorManager.GetProperty("contextRenderMode", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 1569 1570 var renderModeAccessor = System.Linq.Expressions.Expression.Property(System.Linq.Expressions.Expression.Property(null, instance), renderMode); 1571 var internalRenderModeLambda = System.Linq.Expressions.Expression.Lambda<Func<int>>(System.Linq.Expressions.Expression.Convert(renderModeAccessor, typeof(int))); 1572 return internalRenderModeLambda.Compile(); 1573 } 1574 1575 /// <summary> 1576 /// Returns true if the currently opened prefab stage context is set to Hidden. 1577 /// </summary> 1578 /// <returns>True if the currently opened prefab stage context is set to Hidden.</returns> 1579 public static bool IsSceneViewPrefabStageContextHidden() 1580 { 1581 s_GetSceneViewPrefabStageContextFunc ??= LoadSceneViewMethods(); 1582 return s_GetSceneViewPrefabStageContextFunc() == 2; // 2 is hidden, see ContextRenderMode enum 1583 } 1584#else 1585 /// <summary> 1586 /// Returns true if the currently opened prefab stage context is set to Hidden. 1587 /// </summary> 1588 /// <returns>True if the currently opened prefab stage context is set to Hidden.</returns> 1589 public static bool IsSceneViewPrefabStageContextHidden() => false; 1590#endif 1591 1592 /// <summary> 1593 /// Draw a renderer list. 1594 /// </summary> 1595 /// <param name="renderContext">Current Scriptable Render Context.</param> 1596 /// <param name="cmd">Command Buffer used for rendering.</param> 1597 /// <param name="rendererList">Renderer List to render.</param> 1598 public static void DrawRendererList(ScriptableRenderContext renderContext, CommandBuffer cmd, UnityEngine.Rendering.RendererList rendererList) 1599 { 1600#if DEVELOPMENT_BUILD || UNITY_EDITOR 1601 if (!rendererList.isValid) 1602 throw new ArgumentException("Invalid renderer list provided to DrawRendererList"); 1603#endif 1604 cmd.DrawRendererList(rendererList); 1605 } 1606 1607 /// <summary> 1608 /// Compute a hash of texture properties. 1609 /// </summary> 1610 /// <param name="texture"> Source texture.</param> 1611 /// <returns>Returns hash of texture properties.</returns> 1612 public static int GetTextureHash(Texture texture) 1613 { 1614 int hash = texture.GetHashCode(); 1615 1616 unchecked 1617 { 1618#if UNITY_EDITOR 1619 hash = 23 * hash + texture.imageContentsHash.GetHashCode(); 1620#endif 1621 hash = 23 * hash + texture.GetInstanceID().GetHashCode(); 1622 hash = 23 * hash + texture.graphicsFormat.GetHashCode(); 1623 hash = 23 * hash + texture.wrapMode.GetHashCode(); 1624 hash = 23 * hash + texture.width.GetHashCode(); 1625 hash = 23 * hash + texture.height.GetHashCode(); 1626 hash = 23 * hash + texture.filterMode.GetHashCode(); 1627 hash = 23 * hash + texture.anisoLevel.GetHashCode(); 1628 hash = 23 * hash + texture.mipmapCount.GetHashCode(); 1629 hash = 23 * hash + texture.updateCount.GetHashCode(); 1630 } 1631 1632 return hash; 1633 } 1634 1635 // Hacker’s Delight, Second Edition page 66 1636 /// <summary> 1637 /// Branchless previous power of two. 1638 /// </summary> 1639 /// <param name="size">Starting size or number.</param> 1640 /// <returns>Previous power of two.</returns> 1641 public static int PreviousPowerOfTwo(int size) 1642 { 1643 if (size <= 0) 1644 return 0; 1645 1646 size |= (size >> 1); 1647 size |= (size >> 2); 1648 size |= (size >> 4); 1649 size |= (size >> 8); 1650 size |= (size >> 16); 1651 return size - (size >> 1); 1652 } 1653 1654 /// <summary> 1655 /// Gets the Mip Count for a given size 1656 /// </summary> 1657 /// <param name="size">The size to obtain the mip count</param> 1658 /// <returns>The mip count</returns> 1659 public static int GetMipCount(int size) 1660 { 1661 return Mathf.FloorToInt(Mathf.Log(size, 2.0f)) + 1; 1662 } 1663 1664 /// <summary> 1665 /// Gets the Mip Count for a given size 1666 /// </summary> 1667 /// <param name="size">The size to obtain the mip count</param> 1668 /// <returns>The mip count</returns> 1669 public static int GetMipCount(float size) 1670 { 1671 return Mathf.FloorToInt(Mathf.Log(size, 2.0f)) + 1; 1672 } 1673 1674 /// <summary> 1675 /// Divides one value by another and rounds up to the next integer. 1676 /// This is often used to calculate dispatch dimensions for compute shaders. 1677 /// </summary> 1678 /// <param name="value">The value to divide.</param> 1679 /// <param name="divisor">The value to divide by.</param> 1680 /// <returns>The value divided by the divisor rounded up to the next integer.</returns> 1681 public static int DivRoundUp(int value, int divisor) 1682 { 1683 return (value + (divisor - 1)) / divisor; 1684 } 1685 1686 /// <summary> 1687 /// Get the last declared value from an enum Type 1688 /// </summary> 1689 /// <typeparam name="T">Type of the enum</typeparam> 1690 /// <returns>Last value of the enum</returns> 1691 public static T GetLastEnumValue<T>() where T : Enum 1692 => typeof(T).GetEnumValues().Cast<T>().Last(); 1693 1694 internal static string GetCorePath() 1695 => "Packages/com.unity.render-pipelines.core/"; 1696 1697#if UNITY_EDITOR 1698 // This is required in Runtime assembly between #if UNITY_EDITOR 1699 /// <summary> 1700 /// AssetDataBase.FindAssets("t:<type>") load all asset in project to check the type. 1701 /// This utility function will try to filter at much possible before loading anything. 1702 /// This also works with Interface and inherited types. 1703 /// This will not find embedded sub assets. 1704 /// This still take times on big project so it must be only used in Editor context only. 1705 /// </summary> 1706 /// <typeparam name="T">Type or Interface to search</typeparam> 1707 /// <param name="extension">Extension of files to search in</param> 1708 /// <param name="allowSubTypes">Allows to retrieve type inheriting from T.</param> 1709 /// <returns>List of all asset of type T or implementing interface T.</returns> 1710 public static IEnumerable<T> LoadAllAssets<T>(string extension = "asset", bool allowSubTypes = true) 1711 where T : class 1712 { 1713 if (string.IsNullOrEmpty(extension)) 1714 throw new ArgumentNullException(nameof(extension), "You must pass a valid extension"); 1715 1716 bool isInterface = typeof(T).IsInterface; 1717 if (!typeof(UnityEngine.Object).IsAssignableFrom(typeof(T)) && !isInterface) 1718 throw new Exception("T must be an interface or inherite UnityEngine.Object."); 1719 1720 Func<Type, bool> needsLoad = (allowSubTypes || isInterface) 1721 ? (type) => typeof(T).IsAssignableFrom(type) 1722 : (type) => typeof(T) == type; 1723 1724 string[] guids = UnityEditor.AssetDatabase.FindAssets($"glob:\"*.{extension}\""); 1725 foreach (string guid in guids) 1726 { 1727 string path = UnityEditor.AssetDatabase.GUIDToAssetPath(guid); 1728 Type type = UnityEditor.AssetDatabase.GetMainAssetTypeAtPath(path); 1729 if (needsLoad(type)) 1730 yield return UnityEditor.AssetDatabase.LoadAssetAtPath(path, type) as T; 1731 } 1732 } 1733 1734 /// <summary> 1735 /// Create any missing folders in the file path given. 1736 /// </summary> 1737 /// <param name="filePath">File or folder (ending with '/') path to ensure existence of each subfolder in. </param> 1738 public static void EnsureFolderTreeInAssetFilePath(string filePath) 1739 { 1740 var path = filePath.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar); 1741 if (!path.StartsWith("Assets" + Path.DirectorySeparatorChar, StringComparison.CurrentCultureIgnoreCase)) 1742 throw new ArgumentException($"Path should start with \"Assets/\". Got {filePath}.", filePath); 1743 var folderPath = Path.GetDirectoryName(path); 1744 1745 if (!UnityEditor.AssetDatabase.IsValidFolder(folderPath)) 1746 { 1747 var folderNames = folderPath.Split(Path.DirectorySeparatorChar); 1748 string rootPath = ""; 1749 foreach (var folderName in folderNames) 1750 { 1751 var newPath = rootPath + folderName; 1752 if (!UnityEditor.AssetDatabase.IsValidFolder(newPath)) 1753 UnityEditor.AssetDatabase.CreateFolder(rootPath.TrimEnd(Path.DirectorySeparatorChar), folderName); 1754 rootPath = newPath + Path.DirectorySeparatorChar; 1755 } 1756 } 1757 } 1758#endif 1759 1760 /// <summary> 1761 /// Calcualte frustum corners at specified camera depth given projection matrix and depth z. 1762 /// </summary> 1763 /// <param name="proj"> Projection matrix used by the view frustrum. </param> 1764 /// <param name="z"> Z-depth from the camera origin at which the corners will be calculated. </param> 1765 /// <returns> Return conner vectors for left-bottom, right-bottm, right-top, left-top in view space. </returns> 1766 public static Vector3[] CalculateViewSpaceCorners(Matrix4x4 proj, float z) 1767 { 1768 Vector3[] outCorners = new Vector3[4]; 1769 Matrix4x4 invProj = Matrix4x4.Inverse(proj); 1770 1771 // We transform a point further than near plane and closer than far plane, for precision reasons. 1772 // In a perspective camera setup (near=0.1, far=1000), a point at 0.95 projected depth is about 1773 // 5 units from the camera. 1774 const float projZ = 0.95f; 1775 outCorners[0] = invProj.MultiplyPoint(new Vector3(-1, -1, projZ)); 1776 outCorners[1] = invProj.MultiplyPoint(new Vector3(1, -1, projZ)); 1777 outCorners[2] = invProj.MultiplyPoint(new Vector3(1, 1, projZ)); 1778 outCorners[3] = invProj.MultiplyPoint(new Vector3(-1, 1, projZ)); 1779 1780 // Rescale vectors to have the desired z distance. 1781 for (int r = 0; r < 4; ++r) 1782 outCorners[r] *= z / (-outCorners[r].z); 1783 1784 return outCorners; 1785 } 1786 } 1787}