A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using UnityEngine.Experimental.Rendering;
4using UnityEngine.Assertions;
5using System.Text.RegularExpressions;
6using UnityEngine.Rendering.RenderGraphModule.Util;
7#if UNITY_EDITOR
8using UnityEditor;
9#endif
10
11namespace UnityEngine.Rendering
12{
13 /// <summary>
14 /// Various blit (texture copy) utilities for the Scriptable Render Pipelines.
15 /// </summary>
16 public static class Blitter
17 {
18 static Material s_Copy;
19 static Material s_Blit;
20 static Material s_BlitTexArray;
21 static Material s_BlitTexArraySingleSlice;
22 static Material s_BlitColorAndDepth;
23
24 static MaterialPropertyBlock s_PropertyBlock = new MaterialPropertyBlock();
25
26 static Mesh s_TriangleMesh;
27 static Mesh s_QuadMesh;
28
29 static LocalKeyword s_DecodeHdrKeyword;
30
31 static class BlitShaderIDs
32 {
33 public static readonly int _BlitTexture = Shader.PropertyToID("_BlitTexture");
34 public static readonly int _BlitCubeTexture = Shader.PropertyToID("_BlitCubeTexture");
35 public static readonly int _BlitScaleBias = Shader.PropertyToID("_BlitScaleBias");
36 public static readonly int _BlitScaleBiasRt = Shader.PropertyToID("_BlitScaleBiasRt");
37 public static readonly int _BlitMipLevel = Shader.PropertyToID("_BlitMipLevel");
38 public static readonly int _BlitTexArraySlice = Shader.PropertyToID("_BlitTexArraySlice");
39 public static readonly int _BlitTextureSize = Shader.PropertyToID("_BlitTextureSize");
40 public static readonly int _BlitPaddingSize = Shader.PropertyToID("_BlitPaddingSize");
41 public static readonly int _BlitDecodeInstructions = Shader.PropertyToID("_BlitDecodeInstructions");
42 public static readonly int _InputDepth = Shader.PropertyToID("_InputDepthTexture");
43 }
44
45 // This enum needs to be in sync with the shader pass names and indices of the Blit.shader in every pipeline.
46 enum BlitShaderPassNames
47 {
48 Nearest = 0,
49 Bilinear = 1,
50 NearestQuad = 2,
51 BilinearQuad = 3,
52 NearestQuadPadding = 4,
53 BilinearQuadPadding = 5,
54 NearestQuadPaddingRepeat = 6,
55 BilinearQuadPaddingRepeat = 7,
56 BilinearQuadPaddingOctahedral = 8,
57 NearestQuadPaddingAlphaBlend = 9,
58 BilinearQuadPaddingAlphaBlend = 10,
59 NearestQuadPaddingAlphaBlendRepeat = 11,
60 BilinearQuadPaddingAlphaBlendRepeat = 12,
61 BilinearQuadPaddingAlphaBlendOctahedral = 13,
62 CubeToOctahedral = 14,
63 CubeToOctahedralLuminance = 15,
64 CubeToOctahedralAlpha = 16,
65 CubeToOctahedralRed = 17,
66 BilinearQuadLuminance = 18,
67 BilinearQuadAlpha = 19,
68 BilinearQuadRed = 20,
69 NearestCubeToOctahedralPadding = 21,
70 BilinearCubeToOctahedralPadding = 22,
71 }
72
73 enum BlitColorAndDepthPassNames
74 {
75 ColorOnly = 0,
76 ColorAndDepth = 1,
77 }
78
79 // This maps the requested shader indices to actual existing shader indices. When running in a build, it's possible
80 // that some shader pass are stripped or removed, causing a shift in all shader pass index. In this case, hardcoded
81 // shader passes become invalid. This array prevent this error from happening.
82 static int[] s_BlitShaderPassIndicesMap;
83 static int[] s_BlitColorAndDepthShaderPassIndicesMap;
84
85 /// <summary>
86 /// Initialize Blitter resources. Must be called once before any use
87 /// </summary>
88 /// <param name="blitPS">Blit shader</param>
89 /// <param name="blitColorAndDepthPS">Blit shader</param>
90 public static void Initialize(Shader blitPS, Shader blitColorAndDepthPS)
91 {
92 if (s_Blit != null)
93 {
94 throw new Exception("Blitter is already initialized. Please only initialize the blitter once or you will leak engine resources. If you need to re-initialize the blitter with different shaders destroy & recreate it.");
95 }
96
97 // NOTE NOTE NOTE NOTE NOTE NOTE
98 // If you create something here you must also destroy it in Cleanup()
99 // or it will leak during enter/leave play mode cycles
100 // NOTE NOTE NOTE NOTE NOTE NOTE
101 s_Copy = CoreUtils.CreateEngineMaterial(GraphicsSettings.GetRenderPipelineSettings<RenderGraphUtilsResources>().coreCopyPS);
102 s_Blit = CoreUtils.CreateEngineMaterial(blitPS);
103 s_BlitColorAndDepth = CoreUtils.CreateEngineMaterial(blitColorAndDepthPS);
104
105 s_DecodeHdrKeyword = new LocalKeyword(blitPS, "BLIT_DECODE_HDR");
106
107 // With texture array enabled, we still need the normal blit version for other systems like atlas
108 if (TextureXR.useTexArray)
109 {
110 s_Blit.EnableKeyword("DISABLE_TEXTURE2D_X_ARRAY");
111 s_BlitTexArray = CoreUtils.CreateEngineMaterial(blitPS);
112 s_BlitTexArraySingleSlice = CoreUtils.CreateEngineMaterial(blitPS);
113 s_BlitTexArraySingleSlice.EnableKeyword("BLIT_SINGLE_SLICE");
114 }
115
116 /*UNITY_NEAR_CLIP_VALUE*/
117 float nearClipZ = -1;
118 if (SystemInfo.usesReversedZBuffer)
119 nearClipZ = 1;
120 if (SystemInfo.graphicsShaderLevel < 30)
121 {
122 if (!s_TriangleMesh)
123 {
124 s_TriangleMesh = new Mesh();
125 s_TriangleMesh.vertices = GetFullScreenTriangleVertexPosition(nearClipZ);
126 s_TriangleMesh.uv = GetFullScreenTriangleTexCoord();
127 s_TriangleMesh.triangles = new int[3] { 0, 1, 2 };
128 }
129 }
130 if (!s_QuadMesh)
131 {
132 s_QuadMesh = new Mesh();
133 s_QuadMesh.vertices = GetQuadVertexPosition(nearClipZ);
134 s_QuadMesh.uv = GetQuadTexCoord();
135 s_QuadMesh.triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
136 }
137
138 // Should match Common.hlsl
139 static Vector3[] GetFullScreenTriangleVertexPosition(float z /*= UNITY_NEAR_CLIP_VALUE*/)
140 {
141 var r = new Vector3[3];
142 for (int i = 0; i < 3; i++)
143 {
144 Vector2 uv = new Vector2((i << 1) & 2, i & 2);
145 r[i] = new Vector3(uv.x * 2.0f - 1.0f, uv.y * 2.0f - 1.0f, z);
146 }
147 return r;
148 }
149
150 // Should match Common.hlsl
151 static Vector2[] GetFullScreenTriangleTexCoord()
152 {
153 var r = new Vector2[3];
154 for (int i = 0; i < 3; i++)
155 {
156 if (SystemInfo.graphicsUVStartsAtTop)
157 r[i] = new Vector2((i << 1) & 2, 1.0f - (i & 2));
158 else
159 r[i] = new Vector2((i << 1) & 2, i & 2);
160 }
161 return r;
162 }
163
164 // Should match Common.hlsl
165 static Vector3[] GetQuadVertexPosition(float z /*= UNITY_NEAR_CLIP_VALUE*/)
166 {
167 var r = new Vector3[4];
168 for (uint i = 0; i < 4; i++)
169 {
170 uint topBit = i >> 1;
171 uint botBit = (i & 1);
172 float x = topBit;
173 float y = 1 - (topBit + botBit) & 1; // produces 1 for indices 0,3 and 0 for 1,2
174 r[i] = new Vector3(x, y, z);
175 }
176 return r;
177 }
178
179 // Should match Common.hlsl
180 static Vector2[] GetQuadTexCoord()
181 {
182 var r = new Vector2[4];
183 for (uint i = 0; i < 4; i++)
184 {
185 uint topBit = i >> 1;
186 uint botBit = (i & 1);
187 float u = topBit;
188 float v = (topBit + botBit) & 1; // produces 0 for indices 0,3 and 1 for 1,2
189 if (SystemInfo.graphicsUVStartsAtTop)
190 v = 1.0f - v;
191
192 r[i] = new Vector2(u, v);
193 }
194 return r;
195 }
196
197 // Build shader pass map:
198 var passNames = Enum.GetNames(typeof(BlitShaderPassNames));
199 s_BlitShaderPassIndicesMap = new int[passNames.Length];
200 for (int i = 0; i < passNames.Length; i++)
201 s_BlitShaderPassIndicesMap[i] = s_Blit.FindPass(passNames[i]);
202
203 passNames = Enum.GetNames(typeof(BlitColorAndDepthPassNames));
204 s_BlitColorAndDepthShaderPassIndicesMap = new int[passNames.Length];
205 for (int i = 0; i < passNames.Length; i++)
206 s_BlitColorAndDepthShaderPassIndicesMap[i] = s_BlitColorAndDepth.FindPass(passNames[i]);
207 }
208
209 /// <summary>
210 /// Release Blitter resources.
211 /// </summary>
212 public static void Cleanup()
213 {
214 CoreUtils.Destroy(s_Copy);
215 s_Copy = null;
216 CoreUtils.Destroy(s_Blit);
217 s_Blit = null;
218 CoreUtils.Destroy(s_BlitColorAndDepth);
219 s_BlitColorAndDepth = null;
220 CoreUtils.Destroy(s_BlitTexArray);
221 s_BlitTexArray = null;
222 CoreUtils.Destroy(s_BlitTexArraySingleSlice);
223 s_BlitTexArraySingleSlice = null;
224 CoreUtils.Destroy(s_TriangleMesh);
225 s_TriangleMesh = null;
226 CoreUtils.Destroy(s_QuadMesh);
227 s_QuadMesh = null;
228 }
229
230 /// <summary>
231 /// Returns the default blit material.
232 /// </summary>
233 /// <param name="dimension">Dimension of the texture to blit, either 2D or 2D Array.</param>
234 /// <param name="singleSlice">Blit only a single slice of the array if applicable.</param>
235 /// <returns>The default blit material for specified arguments.</returns>
236 static public Material GetBlitMaterial(TextureDimension dimension, bool singleSlice = false)
237 {
238 var material = (dimension == TextureDimension.Tex2DArray)
239 ? (singleSlice ? s_BlitTexArraySingleSlice : s_BlitTexArray)
240 : null;
241 return material == null ? s_Blit : material;
242 }
243
244 static internal void DrawTriangle(RasterCommandBuffer cmd, Material material, int shaderPass)
245 {
246 DrawTriangle(cmd.m_WrappedCommandBuffer, material, shaderPass);
247 }
248
249 static internal void DrawTriangle(CommandBuffer cmd, Material material, int shaderPass)
250 {
251 DrawTriangle(cmd, material, shaderPass, s_PropertyBlock);
252 s_PropertyBlock.Clear();
253 }
254
255 static internal void DrawTriangle(CommandBuffer cmd, Material material, int shaderPass, MaterialPropertyBlock propertyBlock)
256 {
257 if (SystemInfo.graphicsShaderLevel < 30)
258 cmd.DrawMesh(s_TriangleMesh, Matrix4x4.identity, material, 0, shaderPass, propertyBlock);
259 else
260 cmd.DrawProcedural(Matrix4x4.identity, material, shaderPass, MeshTopology.Triangles, 3, 1, propertyBlock);
261 }
262
263 static internal void DrawQuadMesh(CommandBuffer cmd, Material material, int shaderPass, MaterialPropertyBlock propertyBlock)
264 {
265 cmd.DrawMesh(s_QuadMesh, Matrix4x4.identity, material, 0, shaderPass, propertyBlock);
266 }
267
268 static internal void DrawQuad(RasterCommandBuffer cmd, Material material, int shaderPass, MaterialPropertyBlock propertyBlock)
269 {
270 DrawQuad(cmd.m_WrappedCommandBuffer, material, shaderPass, propertyBlock);
271 }
272
273 static internal void DrawQuad(CommandBuffer cmd, Material material, int shaderPass)
274 {
275 DrawQuad(cmd, material, shaderPass, s_PropertyBlock);
276 s_PropertyBlock.Clear();
277 }
278
279 static internal void DrawQuad(CommandBuffer cmd, Material material, int shaderPass, MaterialPropertyBlock propertyBlock)
280 {
281 if (SystemInfo.graphicsShaderLevel < 30)
282 cmd.DrawMesh(s_QuadMesh, Matrix4x4.identity, material, 0, shaderPass, propertyBlock);
283 else
284 cmd.DrawProcedural(Matrix4x4.identity, material, shaderPass, MeshTopology.Quads, 4, 1, propertyBlock);
285 }
286
287 internal static bool CanCopyMSAA()
288 {
289 return s_Copy.passCount == 2;
290 }
291
292 /// <summary>
293 /// Copy a texture to another texture using framebuffer fetch.
294 /// </summary>
295 /// <param name="cmd">Command Buffer used for rendering.</param>
296 internal static void CopyTexture(RasterCommandBuffer cmd, bool isMSAA)
297 {
298 DrawTriangle(cmd, s_Copy, isMSAA ? 1 : 0);
299 }
300
301 /// <summary>
302 /// Blit a RTHandle texture.
303 /// </summary>
304 /// <param name="cmd">Command Buffer used for rendering.</param>
305 /// <param name="source">Source RTHandle.</param>
306 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
307 /// <param name="sourceMipLevel">Mip level to blit from source.</param>
308 /// <param name="sourceDepthSlice">Source texture slice index.</param>
309 /// <param name="bilinear">Enable bilinear filtering.</param>
310 internal static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, float sourceMipLevel, int sourceDepthSlice, bool bilinear)
311 {
312 BlitTexture(cmd, source, scaleBias, GetBlitMaterial(TextureDimension.Tex2D), s_BlitShaderPassIndicesMap[bilinear ? 1 : 0], sourceMipLevel, sourceDepthSlice);
313 }
314
315 /// <summary>
316 /// Blit a RTHandle texture.
317 /// </summary>
318 /// <param name="cmd">Command Buffer used for rendering.</param>
319 /// <param name="source">Source RTHandle.</param>
320 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
321 /// <param name="sourceMipLevel">Mip level to blit from source.</param>
322 /// <param name="sourceDepthSlice">Source texture slice index.</param>
323 internal static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, Material material, int pass, float sourceMipLevel, int sourceDepthSlice)
324 {
325 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, sourceMipLevel);
326 s_PropertyBlock.SetInt(BlitShaderIDs._BlitTexArraySlice, sourceDepthSlice);
327 BlitTexture(cmd, source, scaleBias, material, pass);
328 }
329
330 /// <summary>
331 /// Blit a RTHandle texture.
332 /// </summary>
333 /// <param name="cmd">Command Buffer used for rendering.</param>
334 /// <param name="source">Source RTHandle.</param>
335 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
336 /// <param name="mipLevel">Mip level to blit.</param>
337 /// <param name="bilinear">Enable bilinear filtering.</param>
338 public static void BlitTexture(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear)
339 {
340 BlitTexture(cmd.m_WrappedCommandBuffer, source, scaleBias, mipLevel, bilinear);
341 }
342
343 /// <summary>
344 /// Blit a RTHandle texture.
345 /// </summary>
346 /// <param name="cmd">Command Buffer used for rendering.</param>
347 /// <param name="source">Source RTHandle.</param>
348 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
349 /// <param name="mipLevel">Mip level to blit.</param>
350 /// <param name="bilinear">Enable bilinear filtering.</param>
351 public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear)
352 {
353 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevel);
354 BlitTexture(cmd, source, scaleBias, GetBlitMaterial(TextureXR.dimension), s_BlitShaderPassIndicesMap[bilinear ? 1 : 0]);
355 }
356
357 /// <summary>
358 /// Blit a RTHandle texture 2D.
359 /// </summary>
360 /// <param name="cmd">Command Buffer used for rendering.</param>
361 /// <param name="source">Source RTHandle.</param>
362 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
363 /// <param name="mipLevel">Mip level to blit.</param>
364 /// <param name="bilinear">Enable bilinear filtering.</param>
365 public static void BlitTexture2D(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear)
366 {
367 BlitTexture2D(cmd.m_WrappedCommandBuffer, source, scaleBias, mipLevel, bilinear);
368 }
369
370 /// <summary>
371 /// Blit a RTHandle texture 2D.
372 /// </summary>
373 /// <param name="cmd">Command Buffer used for rendering.</param>
374 /// <param name="source">Source RTHandle.</param>
375 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
376 /// <param name="mipLevel">Mip level to blit.</param>
377 /// <param name="bilinear">Enable bilinear filtering.</param>
378 public static void BlitTexture2D(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, float mipLevel, bool bilinear)
379 {
380 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevel);
381 BlitTexture(cmd, source, scaleBias, GetBlitMaterial(TextureDimension.Tex2D), s_BlitShaderPassIndicesMap[bilinear ? 1 : 0]);
382 }
383
384 /// <summary>
385 /// Blit a 2D texture and depth buffer.
386 /// </summary>
387 /// <param name="cmd">Command Buffer used for rendering.</param>
388 /// <param name="sourceColor">Source Texture for color.</param>
389 /// <param name="sourceDepth">Source RenderTexture for depth.</param>
390 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
391 /// <param name="mipLevel">Mip level to blit.</param>
392 /// <param name="blitDepth">Enable depth blit.</param>
393 public static void BlitColorAndDepth(RasterCommandBuffer cmd, Texture sourceColor, RenderTexture sourceDepth, Vector4 scaleBias, float mipLevel, bool blitDepth)
394 {
395 BlitColorAndDepth(cmd.m_WrappedCommandBuffer, sourceColor, sourceDepth, scaleBias, mipLevel, blitDepth);
396 }
397
398 /// <summary>
399 /// Blit a 2D texture and depth buffer.
400 /// </summary>
401 /// <param name="cmd">Command Buffer used for rendering.</param>
402 /// <param name="sourceColor">Source Texture for color.</param>
403 /// <param name="sourceDepth">Source RenderTexture for depth.</param>
404 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
405 /// <param name="mipLevel">Mip level to blit.</param>
406 /// <param name="blitDepth">Enable depth blit.</param>
407 public static void BlitColorAndDepth(CommandBuffer cmd, Texture sourceColor, RenderTexture sourceDepth, Vector4 scaleBias, float mipLevel, bool blitDepth)
408 {
409 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevel);
410 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias);
411 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, sourceColor);
412 if (blitDepth)
413 s_PropertyBlock.SetTexture(BlitShaderIDs._InputDepth, sourceDepth, RenderTextureSubElement.Depth);
414 DrawTriangle(cmd, s_BlitColorAndDepth, s_BlitColorAndDepthShaderPassIndicesMap[blitDepth ? 1 : 0]);
415 }
416
417 /// <summary>
418 /// Blit a RTHandle texture
419 /// </summary>
420 /// <param name="cmd">Command Buffer used for rendering.</param>
421 /// <param name="source">Source RTHandle.</param>
422 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
423 /// <param name="material">Material to invoke when blitting.</param>
424 /// <param name="pass">Pass idx within the material to invoke.</param>
425 public static void BlitTexture(RasterCommandBuffer cmd, RTHandle source, Vector4 scaleBias, Material material, int pass)
426 {
427 BlitTexture(cmd.m_WrappedCommandBuffer, source, scaleBias, material, pass);
428 }
429
430 /// <summary>
431 /// Blit a RTHandle texture
432 /// </summary>
433 /// <param name="cmd">Command Buffer used for rendering.</param>
434 /// <param name="source">Source RTHandle.</param>
435 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
436 /// <param name="material">Material to invoke when blitting.</param>
437 /// <param name="pass">Pass idx within the material to invoke.</param>
438 public static void BlitTexture(CommandBuffer cmd, RTHandle source, Vector4 scaleBias, Material material, int pass)
439 {
440 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias);
441 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
442 DrawTriangle(cmd, material, pass);
443 }
444
445 /// <summary>
446 /// Blit a RTHandle texture
447 /// </summary>
448 /// <param name="cmd">Command Buffer used for rendering.</param>
449 /// <param name="source">Source render target.</param>
450 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
451 /// <param name="material">Material to invoke when blitting.</param>
452 /// <param name="pass">Pass idx within the material to invoke.</param>
453 public static void BlitTexture(RasterCommandBuffer cmd, RenderTargetIdentifier source, Vector4 scaleBias, Material material, int pass)
454 {
455 BlitTexture(cmd.m_WrappedCommandBuffer, source, scaleBias, material, pass);
456 }
457
458 /// <summary>
459 /// Blit a RTHandle texture
460 /// </summary>
461 /// <param name="cmd">Command Buffer used for rendering.</param>
462 /// <param name="source">Source render target.</param>
463 /// <param name="scaleBias">Scale and bias for sampling the input texture.</param>
464 /// <param name="material">Material to invoke when blitting.</param>
465 /// <param name="pass">Pass idx within the material to invoke.</param>
466 public static void BlitTexture(CommandBuffer cmd, RenderTargetIdentifier source, Vector4 scaleBias, Material material, int pass)
467 {
468 s_PropertyBlock.Clear();
469 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias);
470
471 // Unfortunately there is no function bind a RenderTargetIdentifier with a property block so we have to bind it globally.
472 cmd.SetGlobalTexture(BlitShaderIDs._BlitTexture, source);
473 DrawTriangle(cmd, material, pass);
474 }
475
476 /// <summary>
477 /// Blit a Texture with a specified material. The reference name "_BlitTexture" will be used to bind the input texture.
478 /// </summary>
479 /// <param name="cmd">Command Buffer used for rendering.</param>
480 /// <param name="source">Source render target.</param>
481 /// <param name="destination">Destination render target.</param>
482 /// <param name="material">Material to invoke when blitting.</param>
483 /// <param name="pass">Pass idx within the material to invoke.</param>
484 public static void BlitTexture(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, Material material, int pass)
485 {
486 s_PropertyBlock.Clear();
487 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, Vector2.one);
488
489 // Unfortunately there is no function bind a RenderTargetIdentifier with a property block so we have to bind it globally.
490 cmd.SetGlobalTexture(BlitShaderIDs._BlitTexture, source);
491 cmd.SetRenderTarget(destination);
492 DrawTriangle(cmd, material, pass);
493 }
494
495 /// <summary>
496 /// Blit a Texture with a specified material. The reference name "_BlitTexture" will be used to bind the input texture.
497 /// </summary>
498 /// <param name="cmd">Command Buffer used for rendering.</param>
499 /// <param name="source">Source render target.</param>
500 /// <param name="destination">Destination render target.</param>
501 /// <param name="loadAction">Load action.</param>
502 /// <param name="storeAction">Store action.</param>
503 /// <param name="material">Material to invoke when blitting.</param>
504 /// <param name="pass">Pass idx within the material to invoke.</param>
505 public static void BlitTexture(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, Material material, int pass)
506 {
507 s_PropertyBlock.Clear();
508 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, Vector2.one);
509
510 // Unfortunately there is no function bind a RenderTargetIdentifier with a property block so we have to bind it globally.
511 cmd.SetGlobalTexture(BlitShaderIDs._BlitTexture, source);
512 cmd.SetRenderTarget(destination, loadAction, storeAction);
513 DrawTriangle(cmd, material, pass);
514 }
515
516 /// <summary>
517 /// Blit a quad with a given Material. Set the destination parameter before using this method.
518 /// </summary>
519 /// <param name="cmd">Command Buffer used for rendering.</param>
520 /// <param name="scaleBias">Scale and bias values for sampling the input texture.</param>
521 /// <param name="material">Material to invoke when blitting.</param>
522 /// <param name="pass">Pass index within the Material to invoke.</param>
523 public static void BlitTexture(CommandBuffer cmd, Vector4 scaleBias, Material material, int pass)
524 {
525 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias);
526 DrawTriangle(cmd, material, pass);
527 }
528
529 /// <summary>
530 /// Blit a quad with a given Material. Set the destination parameter before using this method.
531 /// </summary>
532 /// <param name="cmd">Command Buffer used for rendering.</param>
533 /// <param name="scaleBias">Scale and bias values for sampling the input texture.</param>
534 /// <param name="material">Material to invoke when blitting.</param>
535 /// <param name="pass">Pass index within the Material to invoke.</param>
536 public static void BlitTexture(RasterCommandBuffer cmd, Vector4 scaleBias, Material material, int pass)
537 {
538 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBias);
539 DrawTriangle(cmd, material, pass);
540 }
541
542 /// <summary>
543 /// Blit a RTHandle to another RTHandle.
544 /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport.
545 /// </summary>
546 /// <param name="cmd">Command Buffer used for rendering.</param>
547 /// <param name="source">Source RTHandle.</param>
548 /// <param name="destination">Destination RTHandle.</param>
549 /// <param name="mipLevel">Mip level to blit.</param>
550 /// <param name="bilinear">Enable bilinear filtering.</param>
551 public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, float mipLevel = 0.0f, bool bilinear = false)
552 {
553 Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
554 // Will set the correct camera viewport as well.
555 CoreUtils.SetRenderTarget(cmd, destination);
556 BlitTexture(cmd, source, viewportScale, mipLevel, bilinear);
557 }
558
559 /// <summary>
560 /// Blit a RThandle Texture2D RTHandle to another RTHandle.
561 /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport.
562 /// </summary>
563 /// <param name="cmd">Command Buffer used for rendering.</param>
564 /// <param name="source">Source RTHandle.</param>
565 /// <param name="destination">Destination RTHandle.</param>
566 /// <param name="mipLevel">Mip level to blit.</param>
567 /// <param name="bilinear">Enable bilinear filtering.</param>
568 public static void BlitCameraTexture2D(CommandBuffer cmd, RTHandle source, RTHandle destination, float mipLevel = 0.0f, bool bilinear = false)
569 {
570 Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
571 // Will set the correct camera viewport as well.
572 CoreUtils.SetRenderTarget(cmd, destination);
573 BlitTexture2D(cmd, source, viewportScale, mipLevel, bilinear);
574 }
575
576 /// <summary>
577 /// Blit a RTHandle to another RTHandle.
578 /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport.
579 /// This overloads allows the user to override the default blit shader
580 /// </summary>
581 /// <param name="cmd">Command Buffer used for rendering.</param>
582 /// <param name="source">Source RTHandle.</param>
583 /// <param name="destination">Destination RTHandle.</param>
584 /// <param name="material">The material to use when blitting</param>
585 /// <param name="pass">pass to use of the provided material</param>
586 public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Material material, int pass)
587 {
588 Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
589 // Will set the correct camera viewport as well.
590 CoreUtils.SetRenderTarget(cmd, destination);
591 BlitTexture(cmd, source, viewportScale, material, pass);
592 }
593
594 /// <summary>
595 /// Blit a RTHandle to another RTHandle.
596 /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport.
597 /// This overloads allows the user to override the default blit shader
598 /// </summary>
599 /// <param name="cmd">Command Buffer used for rendering.</param>
600 /// <param name="source">Source RTHandle.</param>
601 /// <param name="destination">Destination RTHandle.</param>
602 /// <param name="loadAction">Load action.</param>
603 /// <param name="storeAction">Store action.</param>
604 /// <param name="material">The material to use when blitting</param>
605 /// <param name="pass">pass to use of the provided material</param>
606 public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, RenderBufferLoadAction loadAction, RenderBufferStoreAction storeAction, Material material, int pass)
607 {
608 Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
609 // Will set the correct camera viewport as well.
610 CoreUtils.SetRenderTarget(cmd, destination, loadAction, storeAction, ClearFlag.None, Color.clear);
611 BlitTexture(cmd, source, viewportScale, material, pass);
612 }
613
614 /// <summary>
615 /// Blit a RTHandle to another RTHandle.
616 /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport.
617 /// This overload allows user to override the scale and bias used when sampling the input RTHandle.
618 /// </summary>
619 /// <param name="cmd">Command Buffer used for rendering.</param>
620 /// <param name="source">Source RTHandle.</param>
621 /// <param name="destination">Destination RTHandle.</param>
622 /// <param name="scaleBias">Scale and bias used to sample the input RTHandle.</param>
623 /// <param name="mipLevel">Mip level to blit.</param>
624 /// <param name="bilinear">Enable bilinear filtering.</param>
625 public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Vector4 scaleBias, float mipLevel = 0.0f, bool bilinear = false)
626 {
627 // Will set the correct camera viewport as well.
628 CoreUtils.SetRenderTarget(cmd, destination);
629 BlitTexture(cmd, source, scaleBias, mipLevel, bilinear);
630 }
631
632 /// <summary>
633 /// Blit a RTHandle to another RTHandle.
634 /// This will properly account for partial usage (in term of resolution) of the texture for the current viewport.
635 /// This overload allows user to override the viewport of the destination RTHandle.
636 /// </summary>
637 /// <param name="cmd">Command Buffer used for rendering.</param>
638 /// <param name="source">Source RTHandle.</param>
639 /// <param name="destination">Destination RTHandle.</param>
640 /// <param name="destViewport">Viewport of the destination RTHandle.</param>
641 /// <param name="mipLevel">Mip level to blit.</param>
642 /// <param name="bilinear">Enable bilinear filtering.</param>
643 public static void BlitCameraTexture(CommandBuffer cmd, RTHandle source, RTHandle destination, Rect destViewport, float mipLevel = 0.0f, bool bilinear = false)
644 {
645 Vector2 viewportScale = source.useScaling ? new Vector2(source.rtHandleProperties.rtHandleScale.x, source.rtHandleProperties.rtHandleScale.y) : Vector2.one;
646 CoreUtils.SetRenderTarget(cmd, destination);
647 cmd.SetViewport(destViewport);
648 BlitTexture(cmd, source, viewportScale, mipLevel, bilinear);
649 }
650
651 /// <summary>
652 /// Blit a texture using a quad in the current render target.
653 /// </summary>
654 /// <param name="cmd">Command buffer used for rendering.</param>
655 /// <param name="source">Source texture.</param>
656 /// <param name="scaleBiasTex">Scale and bias for the input texture.</param>
657 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
658 /// <param name="mipLevelTex">Mip level to blit.</param>
659 /// <param name="bilinear">Enable bilinear filtering.</param>
660 public static void BlitQuad(CommandBuffer cmd, Texture source, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear)
661 {
662 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
663 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBiasTex);
664 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
665 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
666
667 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[bilinear ? 3 : 2]);
668 }
669
670 /// <summary>
671 /// Blit a texture using a quad in the current render target.
672 /// </summary>
673 /// <param name="cmd">Command buffer used for rendering.</param>
674 /// <param name="source">Source texture.</param>
675 /// <param name="textureSize">Source texture size.</param>
676 /// <param name="scaleBiasTex">Scale and bias for sampling the input texture.</param>
677 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
678 /// <param name="mipLevelTex">Mip level to blit.</param>
679 /// <param name="bilinear">Enable bilinear filtering.</param>
680 /// <param name="paddingInPixels">Padding in pixels.</param>
681 public static void BlitQuadWithPadding(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels)
682 {
683 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
684 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBiasTex);
685 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
686 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
687 s_PropertyBlock.SetVector(BlitShaderIDs._BlitTextureSize, textureSize);
688 s_PropertyBlock.SetInt(BlitShaderIDs._BlitPaddingSize, paddingInPixels);
689 if (source.wrapMode == TextureWrapMode.Repeat)
690 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[bilinear ? 7 : 6]);
691 else
692 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[bilinear ? 5 : 4]);
693 }
694
695 /// <summary>
696 /// Blit a texture using a quad in the current render target, by performing an alpha blend with the existing content on the render target.
697 /// </summary>
698 /// <param name="cmd">Command buffer used for rendering.</param>
699 /// <param name="source">Source texture.</param>
700 /// <param name="textureSize">Source texture size.</param>
701 /// <param name="scaleBiasTex">Scale and bias for sampling the input texture.</param>
702 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
703 /// <param name="mipLevelTex">Mip level to blit.</param>
704 /// <param name="bilinear">Enable bilinear filtering.</param>
705 /// <param name="paddingInPixels">Padding in pixels.</param>
706 public static void BlitQuadWithPaddingMultiply(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels)
707 {
708 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
709 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBiasTex);
710 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
711 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
712 s_PropertyBlock.SetVector(BlitShaderIDs._BlitTextureSize, textureSize);
713 s_PropertyBlock.SetInt(BlitShaderIDs._BlitPaddingSize, paddingInPixels);
714 if (source.wrapMode == TextureWrapMode.Repeat)
715 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[bilinear ? 12 : 11]);
716 else
717 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[bilinear ? 10 : 9]);
718 }
719
720 /// <summary>
721 /// Blit a texture (which is a Octahedral projection) using a quad in the current render target.
722 /// </summary>
723 /// <param name="cmd">Command buffer used for rendering.</param>
724 /// <param name="source">Source texture.</param>
725 /// <param name="textureSize">Source texture size.</param>
726 /// <param name="scaleBiasTex">Scale and bias for sampling the input texture.</param>
727 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
728 /// <param name="mipLevelTex">Mip level to blit.</param>
729 /// <param name="bilinear">Enable bilinear filtering.</param>
730 /// <param name="paddingInPixels">Padding in pixels.</param>
731 public static void BlitOctahedralWithPadding(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels)
732 {
733 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
734 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBiasTex);
735 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
736 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
737 s_PropertyBlock.SetVector(BlitShaderIDs._BlitTextureSize, textureSize);
738 s_PropertyBlock.SetInt(BlitShaderIDs._BlitPaddingSize, paddingInPixels);
739 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[8]);
740 }
741
742 /// <summary>
743 /// Blit a texture (which is a Octahedral projection) using a quad in the current render target, by performing an alpha blend with the existing content on the render target.
744 /// </summary>
745 /// <param name="cmd">Command buffer used for rendering.</param>
746 /// <param name="source">Source texture.</param>
747 /// <param name="textureSize">Source texture size.</param>
748 /// <param name="scaleBiasTex">Scale and bias for sampling the input texture.</param>
749 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
750 /// <param name="mipLevelTex">Mip level to blit.</param>
751 /// <param name="bilinear">Enable bilinear filtering.</param>
752 /// <param name="paddingInPixels">Padding in pixels.</param>
753 public static void BlitOctahedralWithPaddingMultiply(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels)
754 {
755 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
756 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBiasTex);
757 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
758 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
759 s_PropertyBlock.SetVector(BlitShaderIDs._BlitTextureSize, textureSize);
760 s_PropertyBlock.SetInt(BlitShaderIDs._BlitPaddingSize, paddingInPixels);
761 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[13]);
762 }
763
764 /// <summary>
765 /// Blit a cube texture into 2d texture as octahedral quad. (projection)
766 /// </summary>
767 /// <param name="cmd">Command buffer used for rendering.</param>
768 /// <param name="source">Source cube texture.</param>
769 /// <param name="mipLevelTex">Mip level to sample.</param>
770 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
771 public static void BlitCubeToOctahedral2DQuad(CommandBuffer cmd, Texture source, Vector4 scaleBiasRT, int mipLevelTex)
772 {
773 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitCubeTexture, source);
774 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
775 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, new Vector4(1, 1, 0, 0));
776 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
777 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[14]);
778 }
779
780 /// <summary>
781 /// Blit a cube texture into 2d texture as octahedral quad with padding. (projection)
782 /// </summary>
783 /// <param name="cmd">Command buffer used for rendering.</param>
784 /// <param name="source">Source cube texture.</param>
785 /// <param name="textureSize">Source texture size.</param>
786 /// <param name="mipLevelTex">Mip level to sample.</param>
787 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
788 /// <param name="bilinear">Enable bilinear filtering.</param>
789 /// <param name="paddingInPixels">Padding in pixels.</param>
790 /// <param name="decodeInstructions">The purpose of this parameter is to blit HDR-encoded values to a non HDR texture. Use values from API that produce HDR-encoded values, for example <see cref="ReflectionProbe.textureHDRDecodeValues"/>. If this parameter is null, HDR decoding is disabled.</param>
791 public static void BlitCubeToOctahedral2DQuadWithPadding(CommandBuffer cmd, Texture source, Vector2 textureSize, Vector4 scaleBiasRT, int mipLevelTex, bool bilinear, int paddingInPixels, Vector4? decodeInstructions = null)
792 {
793 var material = GetBlitMaterial(source.dimension);
794
795 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitCubeTexture, source);
796 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
797 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, new Vector4(1, 1, 0, 0));
798 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
799 s_PropertyBlock.SetVector(BlitShaderIDs._BlitTextureSize, textureSize);
800 s_PropertyBlock.SetInt(BlitShaderIDs._BlitPaddingSize, paddingInPixels);
801
802 cmd.SetKeyword(material, s_DecodeHdrKeyword, decodeInstructions.HasValue);
803 if (decodeInstructions.HasValue)
804 {
805 s_PropertyBlock.SetVector(BlitShaderIDs._BlitDecodeInstructions, decodeInstructions.Value);
806 }
807
808 DrawQuad(cmd, material, s_BlitShaderPassIndicesMap[bilinear ? 22 : 21]);
809 cmd.SetKeyword(material, s_DecodeHdrKeyword, false);
810 }
811
812 /// <summary>
813 /// Blit a cube texture into 2d texture as octahedral quad. (projection)
814 /// Conversion between single and multi channel formats.
815 /// RGB(A) to YYYY (luminance).
816 /// R to RRRR.
817 /// A to AAAA.
818 /// </summary>
819 /// <param name="cmd">Command buffer used for rendering.</param>
820 /// <param name="source">Source texture.</param>
821 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
822 /// <param name="mipLevelTex">Mip level to blit.</param>
823 public static void BlitCubeToOctahedral2DQuadSingleChannel(CommandBuffer cmd, Texture source, Vector4 scaleBiasRT, int mipLevelTex)
824 {
825 int pass = 15;
826 uint sourceChnCount = GraphicsFormatUtility.GetComponentCount(source.graphicsFormat);
827 if (sourceChnCount == 1)
828 {
829 if (GraphicsFormatUtility.IsAlphaOnlyFormat(source.graphicsFormat))
830 pass = 16;
831 if (GraphicsFormatUtility.GetSwizzleR(source.graphicsFormat) == FormatSwizzle.FormatSwizzleR)
832 pass = 17;
833 }
834
835 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitCubeTexture, source);
836 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
837 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, new Vector4(1, 1, 0, 0));
838 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
839 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[pass]);
840 }
841
842 /// <summary>
843 /// Bilinear Blit a texture using a quad in the current render target.
844 /// Conversion between single and multi channel formats.
845 /// RGB(A) to YYYY (luminance).
846 /// R to RRRR.
847 /// A to AAAA.
848 /// </summary>
849 /// <param name="cmd">Command buffer used for rendering.</param>
850 /// <param name="source">Source texture.</param>
851 /// <param name="scaleBiasTex">Scale and bias for the input texture.</param>
852 /// <param name="scaleBiasRT">Scale and bias for the output texture.</param>
853 /// <param name="mipLevelTex">Mip level to blit.</param>
854 public static void BlitQuadSingleChannel(CommandBuffer cmd, Texture source, Vector4 scaleBiasTex, Vector4 scaleBiasRT, int mipLevelTex)
855 {
856 int pass = 18;
857 uint sourceChnCount = GraphicsFormatUtility.GetComponentCount(source.graphicsFormat);
858 if (sourceChnCount == 1)
859 {
860 if (GraphicsFormatUtility.IsAlphaOnlyFormat(source.graphicsFormat))
861 pass = 19;
862 if (GraphicsFormatUtility.GetSwizzleR(source.graphicsFormat) == FormatSwizzle.FormatSwizzleR)
863 pass = 20;
864 }
865
866 s_PropertyBlock.SetTexture(BlitShaderIDs._BlitTexture, source);
867 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBias, scaleBiasTex);
868 s_PropertyBlock.SetVector(BlitShaderIDs._BlitScaleBiasRt, scaleBiasRT);
869 s_PropertyBlock.SetFloat(BlitShaderIDs._BlitMipLevel, mipLevelTex);
870
871 DrawQuad(cmd, GetBlitMaterial(source.dimension), s_BlitShaderPassIndicesMap[pass]);
872 }
873 }
874}