Texture Format全解析

本文解析了不同平台上TextureFormat的选择与应用,包括DXT、PVRTC及ETC1等压缩格式,并探讨了它们对内存占用与渲染性能的影响。

Texture Format全解析

  What internal representation is used for the texture. This is a tradeoff between size and quality.

  纹理的压缩方式取决于大小和质量的平衡。

  

  由上图可以看到:

  1)RGB Compressed DXT1  >   RGB 16 bit

    2)RGBA Compressed DXT5 >   RGBA 16 bit

  3)非 Normal 情况下,RGBA Compressed DXT5 > RGBA 32 bit

iOS平台

  

  上图可以看到,前一节中的DXT压缩无法应用于iOS设备上,取而代之的理PVRTC技术。从上图可以看出:

    RGB Compressed PVRTC 4 bits > RGB 16 bit

        RGB Compressed PVRTC 4 bits > RGB Compressed PVRTC 2 bits

    RGBA Compressed PVRTC 4 bits > RGBA 16 bit

    RGBA Compressed PVRTC 4 bits > RGBA Compressed PVRTC 2 bits

    RGBA Compressed PVRTC 4 bits > RGBA 32 bit

Android

  

  Unless you’re targeting a specific hardware, like Tegra, we’d recommend using ETC1 compression. If needed you could store an external alpha channel and still benefit from lower texture footprint.

  If you absolutely want to store an alpha channel in a texture, RGBA16 bit is the compression supported by all hardware vendors.

  RGB Compressed ETC 4 bits 适合于diffuse-map,如果图像有alpha通道,为了全平台使用,必须使用RGBA16。

  If your app utilizes an unsupported texture compression, the textures will be uncompressed to RGBA 32 and stored in memory along with the compressed ones. So in this case you lose time decompressing textures and lose memory storing them twice. It may also have a very negative impact on rendering performance.

  如果使用了不支持的压缩技术,那么带带来浪费解压时间,以及花费双倍内存的情况,有极大的负面影响。

Texture Size

  If the platform or GPU does not support NPOT texture sizes, then Unity will scale and pad the texture up to next power of two size, which will use even more memory and make loading slower.

  如果纹理不是2的次幂,Unity会scale、pad纹理,以使得达到2的次幂,这样会花费更多内存,让加载更慢。所以良好的建议是,所有的纹理都必须是2的次幂

Mip Maps

  Using mip maps uses 33% more memory, but not using them can be a huge performance loss. You should always use mipmaps for in-game textures.

  Mip Map会多花费33%的内存

Anisotropic filtering

  Anisotropic filtering increases texture quality when viewed from a grazing angle, at some expense of rendering cost (the cost is entirely on the graphics card). Increasing anisotropy level is usually a good idea for ground and floor textures. 

  anisotropic filtering只花费gpu时间

参考:file:///C:/Program%20Files%20(x86)/Unity/Editor/Data/Documentation/html/en/Manual/class-TextureImporter.html

<think>嗯...用户这次聚焦在Unity的Texture2D.CreateExternalTexture方法上,看来是在处理原生纹理交互。从引用内容看,用户之前应该尝试过WebCamTexture和移动端视频方案,现在需要深入理解这个底层API。 用户提供的引用很有价值:引用1展示了WebCamTextureTexture2D的典型用法,引用3直接关联Android平台的CreateExternalTexture问题。不过用户明确表示这些引用只是背景参考,核心需求是了解这个特定API的功能和使用细节。 考虑到用户能贴出带IntPtr的代码,应该有一定Unity开发经验。但CreateExternalTexture属于较高级功能,容易引发平台兼容性问题,需要重点解释参数含义和注意事项。特别是那个mipChain参数,很多开发者会忽略它对内存的影响。 用户可能遇到的具体场景或许是:在Android/iOS原生插件中生成纹理,然后传给Unity渲染。这个过程中容易踩的坑包括纹理格式不匹配、内存泄漏、多线程问题等,都需要在注意事项里强调。另外从引用3看,用户似乎被Android平台的特殊性困扰,要单独说明平台差异。 示例代码部分应该保持简洁但完整,演示从创建到销毁的流程。特别要展示updateCallback的使用方式,因为动态更新外部纹理是这个API的核心价值。销毁流程必须强调,很多开发者会忘记手动Destroy导致资源泄漏。 最后考虑要不要提替代方案?不过用户明确指定了这个API,暂时不需要发散。但可以提示下性能风险——频繁更新外部纹理可能引发GPU同步等待。 </think>以下是关于 `Texture2D.CreateExternalTexture` 方法的详细说明,包含核心功能、参数解析、使用示例及注意事项: --- ### **一、方法功能** `Texture2D.CreateExternalTexture` 是Unity用于**创建与原生平台共享的纹理对象**的底层API。它允许: 1. **直接引用外部原生纹理**(如Android的OpenGL ES纹理ID/iOS的Metal纹理) 2. **零拷贝数据共享** - 避免纹理数据在原生层与Unity层间复制 3. **实时更新** - 原生端修改纹理后,Unity端通过 `UpdateExternalTexture` 同步更新 --- ### **二、参数说明** ```csharp public static Texture2D CreateExternalTexture( int width, // 纹理宽度(像素) int height, // 纹理高度(像素) TextureFormat format, // 纹理格式(如RGBA32) bool mipChain, // 是否生成mipmap链 bool linear, // true=线性空间, false=sRGB空间 IntPtr nativeTex // 原生平台纹理指针 ); ``` --- ### **三、典型使用场景** #### 示例1:对接Android原生摄像头 ```csharp // Android原生层返回纹理指针(JNI调用获取) IntPtr androidTexturePtr = GetNativeTextureFromAndroid(); // Unity层创建共享纹理 Texture2D sharedTex = Texture2D.CreateExternalTexture( 1920, 1080, TextureFormat.RGBA32, false, false, androidTexturePtr ); // 将纹理赋给RawImage GetComponent<RawImage>().texture = sharedTex; ``` #### 示例2:iOS Metal纹理共享 ```csharp // 从Metal获取纹理ID(Objective-C桥接) IntPtr metalTexturePtr = GetMetalTexturePointer(); Texture2D sharedTex = Texture2D.CreateExternalTexture( 1024, 1024, TextureFormat.BGRA32, // iOS常用BGRA格式 true, true, // 启用mipmap+线性空间 metalTexturePtr ); ``` --- ### **四、关键注意事项** 1. **平台兼容性** - Android:需使用 `OpenGL ES` 纹理ID(`glGenTextures` 生成) - iOS:仅支持 `Metal` 纹理(`MTLTexture` 对象) - Windows/Mac:支持 `DirectX/Metal/OpenGL` 纹理 2. **生命周期管理** ```csharp // 销毁Unity纹理时,需手动释放原生纹理 void OnDestroy() { if (sharedTex != null) { Destroy(sharedTex); // 销毁Unity对象 ReleaseNativeTexture(); // 原生层释放纹理(如glDeleteTextures) } } ``` 3. **纹理更新同步** ```csharp void Update() { // 原生端修改纹理后调用 sharedTex.UpdateExternalTexture(nativeTexPtr); } ``` 4. **格式限制** - 必须使用平台支持的格式(Android常用 `RGBA32`/`RGB565`,iOS常用 `BGRA32`) - 格式不匹配会导致渲染异常或崩溃 --- ### **五、常见问题解决** - **黑屏/粉屏**:检查原生纹理指针有效性及格式匹配性 - **内存泄漏**:确保双端(Unity+原生)正确释放资源 - **线程安**:纹理操作需在渲染线程执行(Android的 `GLThread`) > ⚠️ 重要提示:此API适用于 **高级跨平台交互** 场景,常规开发建议使用 `WebCamTexture` 或插件方案(如 ARFoundation)[^1][^3]。 --- ### **
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值