版本:Unity 6 (6000.0)
语言中文
  • C#

Graphics.CopyTexture

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们不能采纳所有提交内容,但我们会阅读用户提出的所有建议更改,并在合适的情况下进行更新。

关闭

提交失败

由于某些原因,无法提交您的建议更改。请在几分钟后再 尝试。非常感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

声明

public static void CopyTexture(Texture src, Texture dst);

声明

public static void CopyTexture(Texture src, int srcElement, int srcMip, Texture dst, int dstElement, int dstMip);

声明

public static void CopyTexture(Texture src, int srcElement, int srcMip, int srcX, int srcY, int srcWidth, int srcHeight, Texture dst, int dstElement, int dstMip, int dstX, int dstY);

声明

public static void CopyTexture(Rendering.GraphicsTexture src, Rendering.GraphicsTexture dst);

声明

public static void CopyTexture(Rendering.GraphicsTexture src, int srcElement, int srcMip, Rendering.GraphicsTexture dst, int dstElement, int dstMip);

声明

public static void CopyTexture(Rendering.GraphicsTexture src, int srcElement, int srcMip, int srcX, int srcY, int srcWidth, int srcHeight, Rendering.GraphicsTexture dst, int dstElement, int dstMip, int dstX, int dstY);

参数

src 源纹理。
dst 目标纹理。
srcElement 要从中进行复制的源纹理中的元素。例如,Cubemap 中的 CubemapFace 或纹理数组中的切片。如果 src 是 2D 纹理,则将该值设置为 0
srcMip 要从中进行复制的 mipmap 级别。范围从 0 到纹理的 Texture.mipmapCountGraphicsTextureDescriptor.mipCount。默认值为 0
dstElement 要进行复制的目的地纹理中的元素。例如,Cubemap 中的 CubemapFace 或纹理数组中的切片。如果 `dst` 是 2D 纹理,则将该值设置为 0
dstMip 要写入的 mipmap 级别。范围从 0 到纹理的 Texture.mipmapCountGraphicsTextureDescriptor.mipCount。默认值为 0
srcX 要从中进行复制的 src 的起始 x 坐标。 0 是纹理的左侧。
srcY 要从中进行复制的 src 的起始 y 坐标。 0 是纹理的底部。
srcWidth 要进行复制的 src 的宽度。
srcHeight 要进行复制的 src 的高度。
dstX 要进行复制的 dst 的 x 坐标。
dstY 要进行复制的 dst 的 y 坐标。

描述

将像素数据从一个纹理复制到另一个纹理。

此方法在 GPU 上将像素数据从一个纹理复制到另一个纹理。如果为 srcdst Texture 参数均将 Texture.isReadable 设置为 true,该方法还会尝试通过在 dst 纹理上运行 CopyPixels 来在 CPU 上复制像素数据。

如果您将 Texture.isReadable 设置为 false 或将 GraphicsTexture 用于 srcdst,则像素数据将不会在 CPU 上复制,并且 CopyTexture 将成为复制纹理最快的方法之一。但是,要使用 CopyTexture,源纹理区域和目标纹理区域中以下内容必须相同

根据图形 API,你也许能够在不兼容的格式之间进行复制。例如,在某些 API 上,你可以在具有相同位宽的格式之间进行复制。

根据图形 API,你也许无法在不同类型的纹理之间进行复制。有关兼容性的详细信息,请参阅 SystemInfo.copyTextureSupportCopyTextureSupport

如果 src 是仅限深度的渲染目标,则必须复制整个纹理,而不是部分内容。仅限深度的渲染纹理将其颜色缓冲区设置为 颜色格式None,并将其深度缓冲区设置为有效的 RenderTexture.depthStencilFormat。深度图形纹理将其 格式 设置为具有深度组件的有效 GraphicsFormat

当你使用 QualitySettings.globalTextureMipmapLimitTexture2D.mipmapLimitGroupTexture2D.ignoreMipmapLimit 时,纹理可以有各种各样的渐进贴图限制设置。这意味着你可能无法从一个渐进贴图等级复制到另一个等级,因为源纹理限制到一半分辨率,而目标纹理限制到四分之一分辨率。注意,这在 srcdst 设置为图形纹理时不适用,因为图形纹理的渐进贴图数有限制,并且只表示当前加载的渐进贴图等级。

如果你需要在具有不同渐进贴图限制设置的纹理之间复制渐进贴图,请使用基于区域的重载。此重载根据源纹理的渐进贴图限制设置调整源矩形,根据目标的渐进贴图限制设置调整目标偏移。例如,从位置 16,16 向位置 32,32 复制 128x128 的区域,基于全局纹理渐进贴图限制、源纹理类型和目标纹理类型,会出现各种各样的行为。

  • 当全局纹理渐进贴图限制为 0,且两个纹理均接受此限制时,Unity 会按预期执行所有复制。
  • 当全局纹理渐进贴图限制为 2,且两个纹理均接受此限制时,Unity 会将源矩形调整到 32x32,并将其偏移调整到 4,4,然后将目标偏移更改为 8x8。然后,Unity 会按预期执行所有复制,并忽略所有渐进贴图限制设置。
  • 当全局纹理渐进贴图限制为 2,源是接受此限制的纹理,而目标是不接受此限制的纹理时,Unity 会将源矩形调整到 32x32,并将其偏移调整到 4,4,但不会更改目标偏移,目标偏移仍保持为 32x32。

以下示例演示了在 Texture2Ds 具有渐进贴图限制时,如何从 Texture2DArray 复制或向 Texture2DArray 复制

using UnityEngine;

public class CopyTextureSample : MonoBehaviour { // Sample to copy all available mips: inTex -> outArray (no mipmap limits) -> outTex [SerializeField] Texture2D inTex; [SerializeField] Texture2DArray outArray; [SerializeField] Texture2D outTex; [SerializeField] bool considerMipmapLimits;

void Start() { int width = inTex.width; int height = inTex.width;

outArray = new Texture2DArray(width, height, 1, inTex.format, true); outTex = new Texture2D(width, height, inTex.format, true);

if (!considerMipmapLimits) { // Texture2D -> Texture2DArray // Global Mipmap Limit: "1: Half Resolution" => copies into mips that are now too large; will copy each mip of inTex into a quarter of outArray for (int mip = 0; mip < inTex.mipmapCount; ++mip) { int copyWidth = width >> mip; int copyHeight = height >> mip; Graphics.CopyTexture(inTex, 0, mip, 0, 0, copyWidth, copyHeight, outArray, 0, mip, 0, 0); }

// Texture2DArray -> Texture2D // Global Mipmap Limit: "1: Half Resolution" => errors, since we try to copy into mips that are now too small for (int mip = 0; mip < outArray.mipmapCount; ++mip) { int copyWidth = width >> mip; int copyHeight = height >> mip; Graphics.CopyTexture(outArray, 0, mip, 0, 0, copyWidth, copyHeight, outTex, 0, mip, 0, 0); } } else // considering mipmap limits { int globalMipmapLimit = QualitySettings.globalTextureMipmapLimit;

// Texture2D -> Texture2DArray // Global Mipmap Limit: "1: Half Resolution" => mip0 of outArray is not written to, other mips copy as expected // (ALTERNATIVE: if outArray creation already considered globalMipmapLimit for its dimensions, // the CopyTexture call can ignore globalMipmapLimit since the mips will line up again) for (int mip = 0; mip < inTex.mipmapCount - globalMipmapLimit; ++mip) { int copyWidth = width >> mip; int copyHeight = height >> mip; int srcMip = mip; int dstMip = mip + globalMipmapLimit; Graphics.CopyTexture(inTex, 0, srcMip, 0, 0, copyWidth, copyHeight, outArray, 0, dstMip, 0, 0); }

// Texture2DArray -> Texture2D // Global Mipmap Limit: "1: Half Resolution" => mip0 of outArray is not copied (but outTex does not upload it to GPU anyway) for (int mip = globalMipmapLimit; mip < outArray.mipmapCount; ++mip) { int copyWidth = width >> mip; int copyHeight = height >> mip; int srcMip = mip; int dstMip = mip - globalMipmapLimit; Graphics.CopyTexture(outArray, 0, srcMip, 0, 0, copyWidth, copyHeight, outTex, 0, dstMip, 0, 0); } } } }

Mipmap 等级参数经常引用纹理当前加载的 mipmap 等级(可通过 GraphicsTextureDescriptor.mipCount 找到该纹理的 Texture.graphicsTexture)。例如,如果全局纹理 mipmap 限制设置为 0,256x256 纹理的 mip 1 将引用 128x128 mip。但是,对于相同的纹理,如果全局纹理 mipmap 限制设置为 1,mip 1 将引用一个 64x64 mip。如果全局纹理 mipmap 限制设置为 2,则该相同纹理的 mip 1 将引用一个 32x32 mip(以此类推)。

这意味着你在使用 `CopyTexture` 时,多数情况下无需考虑 mipmap 限制设置。但是,如果你使用 纹理,并且源与目标的 mipmap 限制设置不同,你将需要调整这些设置。请记住,非 2D 纹理类型总是以完整分辨率上传到 GPU,因为它们不支持任何种类的 mipmap 限制设置。

已压缩纹理格式添加了一些限制来使用具有区域变体的 CopyTexture。例如,不适用 PVRTC 格式,因为它们不是基于块的(对于这些格式,你只能复制完整纹理或完整 mip 等级)。对于基于块的格式(例如 DXT、BCn、ETC),区域大小和坐标必须是压缩块大小(对于 DXT 为 4 个像素)的倍数。

即使你将 Texture.isReadable 设置为 true,此方法在仅复制已压缩纹理的一个区域时也不会复制 CPU 上的像素数据。

不要在 CopyTexture 之后使用 Texture2D.ApplyApply 方法,因为你可能会将旧的或未定义的 CPU 纹理数据复制到 GPU。

附加资源:CopyTextureSupportTexture2D.CopyPixels