Unity:将纹理复制到外部纹理2D



我需要向一些本地插件公开一个Unity纹理/渲染纹理,这需要"D3D11_RESOURCE_MISC_SHARED";标志。

unity创建的纹理没有这个标志,所以,我从插件端创建了它,然后使用CreateExternalTexture在unity中创建了一个参考纹理,并使用Graphics.CopyTexture.将内容复制到这个原生纹理

这两个纹理具有相同的维度、相同的大小、相同的格式和相同的mipCount(0(

问题是,当我以统一的方式显示它(用于调试目的(时,我什么也看不到,也不会发生错误。

顺便说一句,如果我通过ReadPixel复制,就会出现错误:

对未定义的图像0调用ReadPixels(有效值为0--1

如果我使用unityAPI创建纹理,CopyTexture就会成功,并且可以看到结果。但后来,我失去了";D3D11_RESOURCE_MISC_SHARED";旗帜

所以,也许我创建的纹理是无效的?我的代码:

D3D11_TEXTURE2D_DESC desc = { 0 };
desc.Width = width;
desc.Height = height;
desc.MipLevels = 0;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;//这里,格式能不能调整?比如,A8是需要的吗?
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;//普通资源
//desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;//应该不需要cpu访问的,不是read也不是write
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;//for "OpenSharedHandle" d3d11 api
HRESULT hr = E_FAIL;
if (FAILED(hr = pDevice->CreateTexture2D(&desc, nullptr, &g_unityEquirectTexture)))
{
Log(" Create Shared Texture Failed!");
return NULL;
}
Log("CreateSharedTexture success");
//return g_unityEquirectTexture;

Unity CopyTexture代码:

if (output == null)
{
Debug.Log($"limit = {QualitySettings.masterTextureLimit}");
//output = new Texture2D(equirect.width, equirect.height, TextureFormat.RGBA32,false);//uncomment this line and then copyTexture below succeeds
IntPtr externalTextureData = CGDKInterOp.cgdk_c_CreateExternalTexture(equirectLeft.GetNativeTexturePtr(), equirectLeft.width * 2, equirectLeft.height);
if (externalTextureData != IntPtr.Zero)
{
output = Texture2D.CreateExternalTexture(equirectLeft.width * 2, equirectLeft.height, TextureFormat.RGBA32, false, true, externalTextureData);
}
}
if (output == null)
{
Debug.LogError("create texture from external failed!");
return;
}
//RenderTexture.active = equirect;
//output.ReadPixels(new Rect(0, 0, equirect.width, equirect.height), 0, 0);
//RenderTexture.active = null;
Graphics.CopyTexture(equirect, output);

好的,我自己解决。

问题是:Miplevel==0。这导致d3d11创建一个分配了0B内存的纹理!将Miplevel更改为1解决了问题

注意:在统一检查器中,我们可以看到由纹理分配的内存。我从检查员那里发现我的纹理有0B内存,然后,我用这个线索搜索,找到了解决方案

可能有更好的解决方案,但上次我需要将纹理数据从本地复制到托管(Unity(时,我是通过数据编组完成的。

本质上,你只需要在原生插件中公开一个方法,将纹理数据作为数组传递给你,然后在C#代码中有一个方法来获取数据(通过调用该方法(,完成后释放指向原生内存的指针。您可以在Microsoft文档中找到有关封送和互操作的信息(例如。https://learn.microsoft.com/en-us/dotnet/framework/interop/marshalling-different-types-of-arrays)。如果你的纹理总是保证具有相同的大小和格式,那就更容易了——但如果你需要知道一些额外的参数,以便知道纹理在管理土地中应该如何表示,你总是可以通过相同的方法向自己传递额外的数据。

最新更新