RenderTexture, Textrue2D的一些用法
RenderTexture或Texture2D -> RenderTexture
public static RenderTexture TextureRenderToRT(Texture srcTex) { var srcTempRT = RenderTexture.GetTemporary(srcTex.width, srcTex.height); Graphics.Blit(srcTex, srcTempRT); //贴图数据填充RT return srcTempRT; }
active RenderTexture -> Texture2D
public static Texture2D CreateTexture2DByFullRT(RenderTexture srcRT, TextureFormat texFormat) { var oldActiveRT = RenderTexture.active; RenderTexture.active = srcRT; var resultTex = new Texture2D(srcRT.width, srcRT.height, texFormat, false); resultTex.ReadPixels(new Rect(0, 0, srcRT.width, srcRT.height), 0, 0); resultTex.Apply(); RenderTexture.active = oldActiveRT; return resultTex; } ///从srcRT的rtArea区域生成Texture2D, rtArea的(x, y)为左上角 public static Texture2D CreateTexture2DByRTArea(RenderTexture srcRT, Rect rtArea, TextureFormat texFormat) { var oldActiveRT = RenderTexture.active; RenderTexture.active = srcRT; //RenderTexture: (0, 0)为左上角, x向右为正, y向下为正. //Texture2D: (0, 0)为左下角, x向右为正, y向上为正. var resultTex = new Texture2D((int)rtArea.width, (int)rtArea.height, texFormat, false); resultTex.ReadPixels(rtArea, 0, 0); //读取RT的rtArea区域, 写到Texture2D的(0, 0)处 resultTex.Apply(); RenderTexture.active = oldActiveRT; return resultTex; }
Camera -> RenderTexture
///相机画面渲染到RT上,如果RT宽高小于相机宽高,则只渲染相机画面的RT那部分大小 public static void CameraRenderToRT(Camera cam, RenderTexture tempRT) { /* if (cameraList[i].targetTexture != null) Graphics.Blit(cameraList[i].targetTexture, tempRT); //RT不一样大小的情况没考虑 */ var oldTargetTexture = cam.targetTexture; cam.targetTexture = tempRT; cam.Render(); cam.targetTexture = oldTargetTexture; }
Texture2D裁剪
///裁剪贴图某块区域, texArea的(x, y)为左上角 public static Texture2D CropTexture2D(Texture2D srcTex, Rect texArea, TextureFormat texFormat) { var srcTempRT = RenderTexture.GetTemporary(srcTex.width, srcTex.height); Graphics.Blit(srcTex, srcTempRT); //用贴图数据填充RT var oldActiveRT = RenderTexture.active; Graphics.SetRenderTarget(srcTempRT); var resultTex = new Texture2D((int)texArea.width, (int)texArea.height, texFormat, false); resultTex.ReadPixels(texArea, 0, 0); //读取RT的rtArea区域, 写到Texture2D的(0, 0)处 resultTex.Apply(); Graphics.SetRenderTarget(oldActiveRT); RenderTexture.ReleaseTemporary(srcTempRT); return resultTex; }
法2
public static Texture2D CropTextrue2D2(Texture2D srcTex, Rect texArea, TextureFormat texFormat) { var srcTempRT = RenderTexture.GetTemporary(srcTex.width, srcTex.height); var oldActiveRT = RenderTexture.active; Graphics.SetRenderTarget(srcTempRT); //用贴图数据填充RT { GL.LoadPixelMatrix(0, 1, 1, 0); var black = new Color(0, 0, 0, 0); //透明黑色 GL.Clear(true, true, black); Graphics.DrawTexture(new Rect(0, 0, 1, 1), srcTex2d); } var resultTex = new Texture2D((int)texArea.width, (int)texArea.height, texFormat, false); resultTex.ReadPixels(texArea, 0, 0); //读取RT的rtArea区域, 写到Texture2D的(0, 0)处 resultTex.Apply(); Graphics.SetRenderTarget(oldActiveRT); RenderTexture.ReleaseTemporary(srcTempRT); return result; }
设置Active RenderTexture的2种方式
第1种,上面的CreateTexture2DByFullRT就用了这种
public static void SetActiveRT1(RenderTexture rt) { var oldActiveRT = RenderTexture.active; RenderTexture.active = rt; //使用active RT执行相关操作 RenderTexture.active = oldActiveRT; }
第2种,上面的CropTexture2D就用了这种
public static void SetActiveRT2(RenderTexture rt) { var oldActiveRT = RenderTexture.active; Graphics.SetRenderTarget(srcTempRT); //使用active RT执行相关操作 Graphics.SetRenderTarget(oldActiveRT); }
SetRenderTarget(RenderTexture rt)和 RenderTexture.active = rt作用一样,都是把渲染的结果存到rt中,如果为null则输出到屏幕
///测试RenderTexture.active和Graphics.SetRenderTarget的作用是否一样 public static void test() { var rt = RenderTexture.GetTemporary(128, 128); Graphics.SetRenderTarget(rt); if (RenderTexture.active == rt) { Debug.Log($"eq"); } }
【参考】
几个Graphics函数 - Tearix - 博客园 (cnblogs.com)