在Unity中,如何在卸载场景时从内存中删除RenderTexture

时间:2017-08-25 10:08:49

标签: c# unity3d memory textures render-to-texture

我有一个统一场景,我​​在其中使用着色器和RenderTextures进行一些计算。

为此,我有一个脚本,用于实例化渲染纹理和我需要的材质,然后将材质应用于现有的渲染纹理,并将结果写入实例渲染纹理。

这基本上就是我所拥有的:

public RenderTexture dstTex;
public RenderTexture srcTex1;
public RenderTexture srcTex2;
public Shader myComputeShader;
public Material myMaterial;

void Awake()
{

    //Create result render Texture
    dstTex = new RenderTexture(textureSizeX, textureSizeY, 16, RenderTextureFormat.ARGB32);
    dstTex.Create();

    //Create material
    myMaterial = new Material(myComputeShader);     
    myMaterial.SetTexture("_srcTex2", srcTex2);
}

void Update()
{
    //Apply material to srcTex1 and write result in dstTex
    Graphics.Blit(srcTex1, dstTex, myMaterial);
}    

现在这很好用。 我的问题是,当我重新加载场景或加载使用相同脚本的另一个场景时,dstTex不会重新初始化。

我的脚本实际上是用当前测量的高度图(srcTex)更新房间的高度图(dstTex)。因此,srcTex值会随着时间的推移而变化,并且dstTex会随着时间的推移而得到填充。

然后,当我重新加载我的场景时,我希望dstTex再次全黑,因为它再次与dstTex = new RenderTexture(textureSizeX, textureSizeY, 16, RenderTextureFormat.ARGB32);进行了实例化。但事实并非如此,前一场景的价值仍然存在于纹理中。

我尝试在我的脚本中添加以下行来解决此问题,但它不起作用:

void OnDestroy()
{   srcTex1.Release();
    srcTex2.Release();  
    dstTex.Release();

    srcTex1.DiscardContents();
    srcTex2.DiscardContents();
    dstTex.DiscardContents();
}

如何从内存中删除这些纹理?

1 个答案:

答案 0 :(得分:0)

我没有确切的答案,但这有一些可能的原因,您的RenderTexture并未如您所愿地重置为全黑。

This GameDev SE post暗示不一定要清除RenderTextures,并且如果要重置纹理,则应该clear it explicitly

根据RenderTexture documentation,当您加载新关卡时,您的RenderTexture可能会丢失

  

请记住,渲染纹理内容在某些情况下可能会“丢失”   事件,例如加载新关卡,系统进入屏保模式,   进入和退出全屏模式等等。发生这种情况时,您现有的   渲染纹理将再次变为“尚未创建”,您可以检查   带有IsCreated函数。

这是我不确定的部分,但是似乎在重新加载场景之后,您的RenderTexture在重新创建时最终会使用相同的硬件纹理。


关于您尝试的修复:

  1. RenderTexture.Release的文档说,它只是释放资源(没有说已被明确清除):
  

RenderTexture.Release

     

此函数释放渲染器使用的硬件资源   质地。纹理本身不会被破坏,并且会被破坏   使用时会自动重新创建。

  1. RenderTexture.DiscardContents的文档未指定确切的行为,这是对GPU驱动程序的优化提示:
  

RenderTexture.DiscardContents

     

提示GPU驱动程序不要将RenderTexture的内容   使用。

     

在某些平台上,如果您指出何时   RenderTexture的当前内容不再需要。这个   可以节省将其从一种内存复制到另一种   纹理被重用。 Xbox 360,XBox One和许多移动GPU受益   从这里。

     

此调用通常仅在给定的RenderTexture为   当前是活动的渲染目标。通话后,内容   RenderTexture是未定义的,因此用户不应尝试   在清除RenderTexture或   绘制到它的每个像素中。