3d object是什么文件_Unity3d | 关于RenderTexture/Texture/2d/3d的创建、赋值、保存

这篇博客介绍了Unity3d中Texture2D、Texture3D、RenderTexture(2D和3D)的创建、赋值方法以及保存为PNG图片的流程。特别讨论了在3D RenderTexture中遇到的问题,如只赋值第一层、数据类型限制和ComputeShader的使用。还提到了纹理的线性空间、mipmap、FilterMode以及数据类型的细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近一直在用visual effect graph ,常常利用贴图来存储数据,再导入vfx采用SampleTexture结点采样使用,因此涉及到数据的保存等问题;此外这两天才真正算是尝试了computeShader的编写,同时用到了renderTexture存储数据;想来可以做个总结以及留几个还未明白的坑。

一、Texture2D

  • Texture2D的创建赋值Setpixel即可,很简单(其他方法请查看官方文档):
Texture2D 
  • Texture2D保存为png图片:
string 

二、Texture3D

  • Texture3D创建其实和2d差不多,但是其中一个point是,当texture所存储的数据类型为“compressed or other non-color texture format ”时,例如本例子中使用的RFloat,就无法使用setPixel来赋值了,此时可用SetPixelData,方法如下:
Texture3D 
  • 分享一个Texture3D预览插件,可以方便查看三维点云数据,排查数据是否出了问题:
https://github.com/raphael-ernaelsten/Texture3DPreview-for-Unity​github.com

v2-edc0855e2c968206fba9f46e862dda0e_b.jpg
预览示例
  • Texure3D的保存:
//debug  将计算前的贴图保存为3DTEXTURE利用上面的插件便于观看

三、RenderTexture(2D)

renderTexture可以用Graphics.Blit(2dtextre,destination rendertexture)方法赋值

RenderTexture  
  • 将renderTexture2D保存为png:
   
 public void saveRenderTexture (RenderTexture renderTexture, string file) {
        RenderTexture.active = renderTexture;
        Texture2D texture = new Texture2D (renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false, false);
        texture.ReadPixels (new Rect (0, 0, renderTexture.width, renderTexture.height), 0, 0);
        texture.Apply ();

        byte[] bytes = texture.EncodeToPNG ();
        UnityEngine.Object.Destroy (texture);

        System.IO.File.WriteAllBytes (file, bytes);
        Debug.Log ("write to File over");
        UnityEditor.AssetDatabase.Refresh (); //自动刷新资源
    }

四、RenderTexture(3D volumetric )

  • 三维RenderTexture 的创建比较特别;
  • 新建时只需要Texture.dimension =UnityEngine.Rendering.TextureDimension.Tex3D;就可以变为3d的;
  • 通常会以为construct的前三个为w,h,d(长、宽、高),但其实不是的,第三个depth指的是z buffer的bit数,一般在2drendertexture中,要将其与相机的rendertarget相关联时,才需要深度缓冲区,用深度来控制不需要render的像素,所以如果利用3d纹理进行数据运算时,depth设置为0即可(当然这也是我的一个猜想)。“高度”的设置用.volumeDepth,代表纹理的切片数。
RenderTexture  
  • 3D renderTexture的赋值:

【坑1】还记得 2drenderTexture 可以通过Texture2D 用bilt方法来赋值吗?于是我在3d时也使用bilt方法,结果发现只bilt了3d纹理的first layer 即第一个切片。后来查看了官方文档,发现了:

v2-ba9be062c68dd61e8a8964e27671c62d_b.png
bilt方法可以指定slice数

于是我以为下面这样就成功了,但是我的结果告诉我,bilt是bilt上了,bilt上去的值却和我原本的值不一样,but I don't know why? 在这里留一个坑。实际上无需在cpu为3d renderTexture赋值,在computeShader中写个函数就可以轻松初始化了。所以上面的坑估计这辈子我也不用踩了。

for 

【坑2】注意cs中如果要引用其他索引的值要这么写my3DRenderTexture[id.xyz+int(0,-1,1)],而my3DRenderTexture[id.x,id.y-1,id.z+1)]是错的~

【坑3】本例中我使用了RenderTextureFormat.RFloat类型的数据,但我本来是想用Rint 或者R8类型(因为我的数据原本是整型的),但是不知为何cs会报错,我理解的是cs不支持这类数据或者在renderTexture 3d 中使用这类整型数据有特定表示或方式(大半是后者的原因),这个问题没搞明白,留着。不过我有个猜想是在unity shader中整型是32bit int ,而R8 是8bit整型所以不可以,但很遗憾的是RenderTextureFormat.RInt也是32bit int,而TextureFormat没有RInt类型,最大只有R16,这个猜想似乎也可以886了。

  • 3D renderTexture的保存:
 AssetDatabase.CreateAsset (stateTexture, "Assets/yourTex3d.asset");

五、一些参数的解释或资料

  • 关于纹理的线性空间和伽马空间:
Unity Shader 伽马空间与线性空间​blog.youkuaiyun.com
v2-28fe879aa1b1a4f727e293b080dc1265_180x120.jpg
https://docs.unity3d.com/ScriptReference/RenderTextureReadWrite.html​docs.unity3d.com
RenderTextureReadWrite

https://docs.unity3d.com/ScriptReference/RenderTexture-sRGB.html​docs.unity3d.comaganztracy:Unity3d | texture2d数据由于伽马变换导致数据变形、不准确(贴图颜色变暗)的深坑​zhuanlan.zhihu.com
v2-57e878777ce9ce1635858d92aaea5040_120x160.jpg
Debug
  • 关于纹理的mipmap:

使用mipmap后,会生成不同大小的多张贴图,贴图会根据和摄像机距离的远近选择使用不同精度的贴图,下面文章解释了mipmap的作用。

优快云-专业IT技术社区-登录​blog.youkuaiyun.com
  • 关于纹理的FiltetMode(平滑处理模式),即采样的方式,由1到3纹理效果越来越好,性能消耗越来越大,纹理变得越来越平滑
  1. point单像素采样,纹理块状化
  2. bilinear 双线性插值采样,纹理变模糊
  3. trilinear三线性插值采样,和2差不多,在不同的miplevel进行了模糊
  • 关于纹理数据类型RenderTextureFormat与TextureFormat:
https://docs.unity3d.com/ScriptReference/RenderTextureFormat.html​docs.unity3d.com
//Note that a particular render texture format might not be supported by the current platform or GPU. 
https://docs.unity3d.com/ScriptReference/SystemInfo.SupportsRenderTextureFormat.html​docs.unity3d.com
  • 关于cg数据类型:
Unity Shader基础篇-Cg语法、数据类型与关键字​gameinstitute.qq.com
v2-0289be19f20129b4df7c5ce6ff60507c_ipico.jpg

六、【题外话】ComputeShader中如何传入四维数组进行计算(同理可得三维数组方法)

//Just use a linear buffer with dimX * dimY * dimZ number of elements. Then index into it using:
感想:因为一些小坑耽误了不少时间,这告诉我们什么道理呢?遇到问题直奔官方文档,官方文档就是圣经啊啊啊!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值