如何通过脚本使Texture2D可读

如何通过脚本使Texture2D可读性


又踩了一个Unity比较坑的地方:就是在代码里访问Texture2D的时候,不可读。

看了很多博客,例如:https://blog.csdn.net/emoonight/article/details/18002913,通过设置纹理的导入设置中的Raad/Wtire改为true。

或者:https://blog.csdn.net/qq617119142/article/details/50085677,通过代码设置Texture的可读性。

但是注意了,这都是Texture,并不是Texture2D,那我们改怎么做呢?看到国外的一片文章完美解决这个问题:https://stackoverflow.com/questions/44733841/how-to-make-texture2d-readable-via-script


首先不可读的原因:
Unity将其设置为不可读的原因是因为使它不可读的话,它的访问速度将变得非常快,而使它具有可读性是以牺牲内存和性能为代价的。这样做的原因是,使其不可读那么纹理将在GPU上。如果您使其可读性,CPU也可以访问它,但是操作缓慢。GPU的访问速度是很快的,假如它运行在GPU上的话,那么自然速度会更快。

原文:By making it unreadable, it becomes very very fast. Making it readable comes at a cost of memory and performance. The reason for this is because making it unreadable will make the texture on the GPU. If you make it readable, the CPU can also access it making the operation slow. GPU is extremely fast. That’s the thing. I think you should study “Compute shader” in Unity. You will see how fast you can do stuff with it just because it’s running on the GPU instead of CPU. Note that this is an advanced topic. It’s similar to making Texture2D unreadable.


解决办法

1.使用RenderTexture(建议):

使用RenderTexture。把源Texture2D放进RenderTexture带着Graphics.Blit然后使用Texture2D.ReadPixels若要从RenderTexture进入新的Texture2D.

附上代码:

private Texture2D duplicateTexture(Texture2D source)
{
    RenderTexture renderTex = RenderTexture.GetTemporary(
                source.width,
                source.height,
                0,
                RenderTextureFormat.Default,
                RenderTextureReadWrite.Linear);

    Graphics.Blit(source, renderTex);
    RenderTexture previous = RenderTexture.active;
    RenderTexture.active = renderTex;
    Texture2D readableText = new Texture2D(source.width, source.height);
    readableText.ReadPixels(new Rect(0, 0, renderTex.width, renderTex.height), 0, 0);
    readableText.Apply();
    RenderTexture.active = previous;
    RenderTexture.ReleaseTemporary(renderTex);
    return readableText;
}

使用:

Texture2D copy = duplicateTexture(sourceTextFromPlugin);

这个方法不会报出任何错误,亲测有效。


2.使用Texture2D.GetRawTextureData() + Texture2D.LoadRawTextureData():

你不能用GetPixels32()因为Texture2D是不可读的。你差点就用了GetRawTextureData().

当你用Texture2D.LoadImage()从GetRawTextureData().

Texture2D.LoadImage()是只用于加载PNG/JPG数组字节,而不是Transture2D数组字节。

如果你用Texture2D.GetRawTextureData(),你必须用Texture2D.LoadRawTextureData()不Texture2D.LoadImage()。

附上代码:

private Texture2D duplicateTexture(Texture2D source)
{
    byte[] pix = source.GetRawTextureData();
    Texture2D readableText = new Texture2D(source.width, source.height, source.format, false);
    readableText.LoadRawTextureData(pix);
    readableText.Apply();
    return readableText;
}

编辑器中的代码不会出现错误,但是独立构建时应该会出现错误。此外,即使在独立构建中出现错误,它仍然可以工作。
报的错误为:Texture needs to be marked as Read/Write to be able to GetRawTextureData in player。


建议使用第一种方法,因为它不会报错,第二种方法亲测有的时候会导致Texture2D丢失。

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值