Unity RenderTexture的保存和多线程

unity图像处理 GraphicsBlit纹理通过材质渲染到目标,纹理设为材质的 _MainTex 属性将 dest 设置为渲染目标,为null时直接渲染到屏幕,使用后RenderTexture.active变成dest该操作在GPU上复制纹理,速度很快在 android 上如果不生效,尝试创建 RenderTexture 时深度值设为0Blit是纹理操作,所有参数都是针对纹理坐标,scale 和 offset 用来设置uv偏移和缩放, 阅读详情

在Unity中如果要保存相机图片,我们最常用的方法是首先把RenderTexture转化成Texture2D,如下:

Texture2D texture2D = null;
texture2D = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
var previous = RenderTexture.active;
RenderTexture.active = renderTexture;
texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
RenderTexture.active = previous;
texture2D.Apply();
void Awake()
{
        targetRenderTexture = new RenderTexture((int)(normalSize), (int)(normalSize), 0 , RenderTextureFormat.ARGB32);//, RenderTextureFormat.Default
        
        int quality = QualitySettings.GetQualityLevel();
        if (quality > 0)
            targetRenderTexture.antiAliasing = 4;
        else
            targetRenderTexture.antiAliasing = 1;
}

RenderTexture创建部分

然后再把图片保存成二进制格式进行保存,如下:

byte[] bytes = txtureSmall.EncodeToPNG();
try
{
	string forder = GetFileDirectory(path);
	bool exists = System.IO.Directory.Exists(forder);
	if (!exists)
		System.IO.Directory.CreateDirectory(forder);

	System.IO.File.WriteAllBytes(path, data);
}
catch (Exception ee)
{
	Debug.Log("文件写入失败:" + path + " Error:" + ee.Message);
}

如果是在保存进度,场景切换等允许卡顿的地方操作是没有问题的。

如果是在不允许有卡顿感的操作中就是大问题了。

经过分析主要来自EncodeToPNG函数,耗费了大量CPU。

那么如果我们让他在别的进程运行,游戏就不会有卡顿感了。

马上进行测试:

		new System.Threading.Thread(() =>
        {
            这里处理上面的逻辑。
            
        }).Start();

发现不能在其他进程里处理RenderTexture,txtureSmall.EncodeToPNG,会报出
…… can only be called from the main thread.

那么怎么做呢,其实Unity提供了其他的方法来做这样事情。

下面做一个记录

		int nw = rendertxture.width;
        int nh = rendertxture.height;
        //filesavepath = filename;
        GraphicsFormat format = rendertxture.graphicsFormat;
        UnityEngine.Rendering.AsyncGPUReadbackRequest request = UnityEngine.Rendering.AsyncGPUReadback.Request(rendertxture, 0 );
        yield return 0;


        while (!request.done)
        {
            yield return new WaitForEndOfFrame();
        }

        if (request.hasError)
        {
            Debug.Log("GPU readback error detected.");
            yield break;
        }

        byte[] array = request.GetData<byte>().ToArray();

        Task.Run(() =>
        {
#if UNITY_EDITOR
            Debug.Log("保存进度图:" + filename);
#endif
            byte[] datas = ImageConversion.EncodeArrayToPNG(array, format, (uint)nw, (uint)nh);
            CFunc.StreamWriter(filename, datas);

        });

这样主线程就不会卡顿了。

经过一段时间测试后发现
AsyncGPUReadbackRequest的函数,可能会出现报错 This GfxDevice does not support asynchronous readback
发现报错了图片也能显示出来。匪夷所思
然后通过SystemInfo.supportsAsyncGPUReadback函数来判断发现也是False,说明不支持,不支持为说明图可以显示出来呢。

所以研究了下,直接可以通过拿出RenderText的Texture2D,获取到GetPixeds32,然后再放入多线程处理。代码如下,可能速度稍微慢一些。

	Texture2D saveToTexture(RenderTexture renderTexture)
    {
        Texture2D texture2D = null;
        texture2D = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.ARGB32, false);
        var previous = RenderTexture.active;
        RenderTexture.active = renderTexture;
        texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
        RenderTexture.active = previous;
        texture2D.Apply();
        return texture2D;
    }
	
	 		Texture2D txture = saveToTexture(targetRenderTexture);
	 		Color32[] array = txture.GetPixels32();
	 		//这里如果renderTexture不是RenderTextureFormat.ARGB32,在IOS中好像是BGRA,会导致获取保存的颜色变色,原因未知.
            GameObject.DestroyImmediate(txture);
            Task.Run(() =>
            {
#if UNITY_EDITOR
                Debug.Log("保存进度图:" + filename);
#endif
                byte[] bytes = ImageConversion.EncodeArrayToPNG(array, format, (uint)nw, (uint)nh);

                CFunc.StreamWriter(filename, bytes);
                pone.ok = true;



            });

相关技术资料
https://docs.unity3d.com/ScriptReference/ImageConversion.EncodeArrayToPNG.html
https://forum.unity.com/threads/asyncgpureadbackrequest-and-encodetopng.551314/
https://forum.unity.com/threads/using-the-job-system-to-save-images.522837/

解决Unity3D中RenderTexture转存png文件,颜色变暗的问题 关于在Unity3D当中截屏内容,或者某个相机的内容,保存到图片文件的方法。 一般的做法是将Camera的targetTexture指定一个RenderTexture,然后将这个RenderTexture转成PNG文件。下面是代码,一般搞Unity应该都能看懂。但是会有一个问题,就是输出的PNG文件会变暗。 Texture2D CaptureCamera(Camera camera, Rect rect, RenderTexture rt, string fname) { 阅读详情

相关推荐

Unity3d 技巧(6) -将RenderTexture保存成一张png图片

将RenderTexture保存成一张png图片

qq_20589257的博客 4801

unity RenderTexture小知识

为啥要为临时生成的图片添加名字? 方便查看内存的时候观察有没删除干净啊   缩放图片 private Texture2D ScaleTexture(Texture2D target, int width, int height) { RenderTexture rt = new RenderTexture(width, height, 24); ...

小鱼游戏开发的博客 3539

Unity相机截图优化:从RenderTexture到PNG的高性能异步保存方案

在游戏开发与图形渲染中,将GPU渲染结果高效保存为图像文件是一个常见且关键的技术需求,尤其在需要处理高分辨率画面或频繁截图的场景下。其核心原理涉及GPU与CPU之间的数据交换、内存管理以及图像编码压缩。传统同步读取方式(如Texture2D.ReadPixels)易造成主线程阻塞,导致帧率下降,影响游戏流畅度。通过引入异步GPU数据读取(如AsyncGPUReadback)与后台线程文件写入,可以显著优化性能,实现无卡顿的截图体验。这项技术的价值在于平衡了渲染质量与运行效率,广泛应用于游戏内拍照系统、宣传素

weixin_29016865的博客 324

【Unity】使用RenderTexture为物体生成快照

版权声明:本文为博主原创文章,未经博主允许不得转载。 作者:Jimm 邮箱:junmingz@foxmail.com RenderTexture的定义和作用 RenderTexture are textures that can be rendered to. RenderTexture(下文简称RTT)是可以被渲染的纹理,简称渲染纹理。一般来说...

ayuyq7610的博客 1196

微信小程序云开发订单微信支付与小票和标签打印的完整高效流程

本片文章全文12000字,细致讲述从申请账户到小程序注册到打印机的选型最后到实现微信小程序云开发订单支付更新与小票,标签打印完整的高效流程。客户A在我们的点餐平台上点了一杯咖啡,所以客户要在选好后付款,在付款完成后商家的小票打印机和标签打印机打印出本订单的相关信息。

weixin_52312427的博客 3649

Computer Networks 和 Computer & Security投稿经验

论文投稿

qq_50604294的博客 9229

Unity相机截图的多场景应用:从游戏截图到AR内容保存

本文全面解析Unity相机截图技术,从基础实现到多场景创新应用。详细介绍了使用RenderTexture和Texture2D实现截图功能的核心原理,并探讨了在游戏动态相册系统和AR内容保存中的高级应用。文章还提供了性能优化和平台适配的实用技巧,帮助开发者高效实现Unity相机截图功能并保存到本地。

b0c1d2的博客 540

YOLO模型在STM32微控制器上的部署:1.98M参数如何塞进嵌入式设备?

<think>我们根据内容生成不超过150字的摘要。内容主要是关于YOLO模型在STM32微控制器上的部署,包括STM32N6 NPU、模型量化、工具链、开源方案和架构设计。摘要需要简洁概括主要点。 字数限制:≤150字。需要包含关键信息:STM32N6运行YOLO,困难,方案(NPU、INT8量化、工具链),性能(34 FPS 9.4mJ)。结尾可能提到开源和生态。 写中文摘要。注意不超过150字。</think>本文探讨YOLO模型在STM32微控制器上的部署。集成NPU的STM32N6搭配轻量化YOL

2601_95807009的博客 255

Unity中RenderTexture详解以及它的用途

什么是RenderTexture? RenderTexture是unity定义的一种特殊的Texture类型,它连接着一个FrameBufferObject的存在于GPU端的Texture(Server-Side Texture)从上面对RenderTexture的解释我们了解到要先知道Texture和FrameBufferObject是什么 什么是Texture? 中文翻译叫纹理,先说一下...

weixin_39106746的博客 2万+

ruoyi-nbcio基于ruoyi的flowable前端支持自定义表单组件的自动获取方法

ruoyi-nbcio基于ruoyi的flowable前端支持自定义表单组件的自动获取方法

宁波阿成的博客 607

RT-DETR 模型剪枝优化:结构化剪枝对 R18/R50 性能的影响

本文提出分层结构化剪枝策略R18:参数量减少 42%(28M→16.2M),推理速度提升 35%(15→20.3 FPS@Jetson Nano),mAP@0.5 仅降 1.2%;R50:参数量减少 55%(170M→76.5M),推理速度提升 48%(42→62.2 FPS@T4),mAP@0.5 仅降 2.1%。核心价值:为 RT-DETR 提供“精度-效率-部署”平衡的轻量化方案,推动其在边缘设备、工业质检等场景的大规模落地。部署建议。

走向CTO的路上... 464

Unity Camera与RenderTexture

一、RenderTexture类属性及函数 首先提供官方参考文档:API-Reference-RenderTexture 概述:RenderTexture类继承自Texture类;它是Textures的一种特殊类型,它的内容是在游戏运行的时候被创建和更新的,如果需要更新RenderTexture,就需要为其指定一个相机; static属性 active:获取当前的RenderTextur...

mozhi 4536

使用Python爬虫抓取旅游景点评价数据并进行热度可视化

景点热度通常由景点的评分、评论数以及游客的热情度来决定。高热度的景点通常意味着更高的游客评分和更多的游客评论。热度不仅反映了景点的受欢迎程度,还可以揭示某些景点的潜力和存在的问题。评分:游客对景点的综合评分,通常是0到5分。评论数:景点的评论数量,反映了游客对景点的关注程度。热度变化:在一定时间内,景点的评价和评论数量变化,能够反映景点的热度波动。通过使用Python爬虫技术抓取旅游景点的评价和评论数据,我们能够深入分析景点的热度,并通过数据可视化工具将这些信息展示给用户。

2201_76125261的博客 1282

Unity使用RenderTexture实现裁切3D模型

文章目录一、前言二、实现步骤1 UGUI的Mask裁切2 使用独立摄像机渲染3D模型3 使用RenderTexture存储摄像机的渲染4 使用RawImage显示RenderTexture 一、前言 游戏项目中,可能需要实现3D模型的裁切显示,比如让3D模型在一个圆形的裁切区域内显示,如下效果 原理就是使用RenderTexture保存摄像机的画面,然后再使用UGUI的Mask对RenderTexture进行裁切。 二、实现步骤 1 UGUI的Mask裁切 UGUI中,有一个MaskI组件,可以方便的实现

linxinfa的专栏 4225

基于 Simulink 的 PFC + LLC 级联系统联合仿真与优化实战教程

摘要:本教程详细介绍了2kW级AC-DC变换器建模方法,采用"BoostPFC+LLC谐振变换器"组合架构。重点解析了双级系统的核心控制策略:前级BoostPFC实现功率因数校正(PF>0.95),后级LLC通过变频调制(PFM)实现高效能量传输。教程包含四大关键步骤:PFC建模与控制、LLC参数计算与实现、母线电容优化设计以及系统联合调试,特别针对级联系统常见的母线电容震荡问题提供了解决方案。同时给出了仿真波形分析指南和避坑建议,包括代数环处理、仿真步长设置等实用技巧,为新能源车

MHD0815的博客 118

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

[Unity3d]保存相机当前渲染内容或者RenderTexture到本地小工具

项目中,遇到需要将相机当前渲染的内容或者是RenderTexture保存到本地的需求,查看渲染结果是否正确。因此,写了一个简单的小工具,按F4就可以保存到Assets上一级目录。 先直接贴代码,有时间再详细解释 使用方式是直接将脚本挂在需要的camera上,按F4保存截图。 using UnityEngine; using System; using System.IO; public cla...

延澈左的专栏 5106

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Unity3d中渲染到RenderTexture的原理,几种方式以及一些问题

虽然RenderTexture这个技术是个普遍使用的技术,但是用好它还是要理解他的底层原理和避免一些使用的问题。这里就UNITY3d中的RenderTexure介绍Rendertexture的底层原理和使用时可能遇到的坑和效率问题。

leon 7万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Unity将RenderTexture转成一张图片并剪裁保存到本地

//将RenderTexture保存成一张png图片 public bool SaveRenderTextureToPNG(RenderTexture rt, string contents, string pngName) { RenderTexture prev = RenderTexture.active; RenderTexture.act

海涛高软 1万+

Unity的RenderTexture上不显示粒子效果

Unity的RenderTexture上不显示粒子效果问题描述解决参考链接 问题描述 项目中,用一个相机将图像渲染到Render Texture上面,然后将这个Render Texture给UI中的Raw Image显示出来,发现粒子效果没有出现。 如图: 实际的样子: Raw Image中显示的样子: 解决 其中,粒子使用的Shader是Legacy Shaders/Particles/Alpha Blended。在其中可以看到如下代码: Tags { "QUEUE"="Transparent" "

天富儿的博客 3916

Unity CommandBuffer渲染MTR到自定义的RenderTexture

目标: 延迟渲染技术下,有时我们要先把模型的Diffuse、Normal、Depth、Roughness等数据先渲到自定义的RenderTexture中(CPU中,以几张贴图的形式保存到Disk),然后进行后面的延迟光照等计算。 思路: 方法一 可以用Camera直接渲,只要将自定义的RT设置为相机的target即可(MRT要使用Camera的SetTargetBuffers (RenderBu...

Mr_厚厚的博客 5902

保存一个RenderTexture到一个png

using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.Rendering; public class RTDemo2 : MonoBehaviour { public GameObject m_cube; public Camera m_camera; public Shader m_shader; p

小孔明的专栏 577

file转byte数组_unity截图保存-RenderTexture转Texture2D

使用unity项目开发过程中需要用到系统截图功能时,其实主要的做法是将RenderTexture转换为Texture2D,然后再转为byte数组,最后创建图片文件,写入内存。下面是代码演示:public static bool SaveRenderTextureToPNG(RenderTexture rt, string contents, string pngName) { Debug.Log(...

weixin_35988311的博客 974

保存RenderTexture类型的图片

项目中需要在Unity用到了视频播放

4010

Unity 保存 Texture转换RT

保存 Texture2D 到硬盘 public bool SaveRenderTextureToPNG(Texture2D spng, string contents, string pngName) { Debug.Log($"save {contents}"); Texture2D png = new Texture2D(spng.width, spng.height, ...

若风 1748

Unity之将Texture保存成png

using UnityEngine; using System.Collections; using System.IO; public class SaveToPng : MonoBehaviour { public Shader outShader; public Texture inputTex; // Use this for initialization void ...

chh19941125的专栏 2017
上一篇: Unity Shader 颜色混合
下一篇: Unity异步多线程调用 -Task
Thinbug
博客等级 码龄22年 2万+粉丝 187原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Thinbug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值