我有一个统一场景,我在其中使用着色器和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();
}
如何从内存中删除这些纹理?
答案 0 :(得分:0)
我没有确切的答案,但这有一些可能的原因,您的RenderTexture并未如您所愿地重置为全黑。
This GameDev SE post暗示不一定要清除RenderTextures,并且如果要重置纹理,则应该clear it explicitly。
根据RenderTexture documentation,当您加载新关卡时,您的RenderTexture可能会丢失
请记住,渲染纹理内容在某些情况下可能会“丢失” 事件,例如加载新关卡,系统进入屏保模式, 进入和退出全屏模式等等。发生这种情况时,您现有的 渲染纹理将再次变为“尚未创建”,您可以检查 带有IsCreated函数。
这是我不确定的部分,但是似乎在重新加载场景之后,您的RenderTexture在重新创建时最终会使用相同的硬件纹理。
关于您尝试的修复:
RenderTexture.Release
此函数释放渲染器使用的硬件资源 质地。纹理本身不会被破坏,并且会被破坏 使用时会自动重新创建。
RenderTexture.DiscardContents
提示GPU驱动程序不要将RenderTexture的内容 使用。
在某些平台上,如果您指出何时 RenderTexture的当前内容不再需要。这个 可以节省将其从一种内存复制到另一种 纹理被重用。 Xbox 360,XBox One和许多移动GPU受益 从这里。
此调用通常仅在给定的RenderTexture为 当前是活动的渲染目标。通话后,内容 RenderTexture是未定义的,因此用户不应尝试 在清除RenderTexture或 绘制到它的每个像素中。