http://fargesportfolio.com/unity-texture-texture2d-rendertexture/
(1) Texture 基于GPU
(2) RenderTexture基于GPU
(3)Texture2D基于CPU Texture2D.Apply将CPU数据传递给GPU
------------------------------------------------------------------------2020年4月20更---------------------------------------------------------------------------
这里说一下 Texture2D
的Apply
操作,当我们使用SetPixel
或SetPixels
一定要调用Apply方法,不然显示的还是原来的图,这里有个链接具体看下:https://blog.csdn.net/carefreeq/article/details/52635524
图片存在内存中,CPU指向这个图片地址,GPU根据CPU拿过来的地址来显示,如果更改了图片数据,没用调用Apply. 那么GPU没用接收到CPU发来的指令就不会更改这个图的显示.下面的代码,当我没调用Apply的操作时,显示的还是原图,当我调用之后显示的就是纯红色了
private void BtnClick()
{
Texture2D tex = new Texture2D(0, 0);
tex.LoadImage(File.ReadAllBytes(desktopPath + "/111.jpg"));
Color[] colors = tex.GetPixels();
for (int i = 0; i < colors.Length; i++)
colors[i] = Color.red;
tex.SetPixels(colors);
//tex.Apply(); 这里更改
rawImg.texture = tex;
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/// Pass a GPU RenderTexture to CPU Texture2D
/// This opperation has heavy cost (ReadPixels)
/// We reduice the RenderTexture size first to be more efficient
void RenderTextureToTexture2D()
{
// Please, be power of 2 for performance issue (2, 4, 8, ...)
int downSize = 2;
RenderTexture textureToDownsizeAndCopyToCPU = new RenderTexture(1920, 1080, 0);
Texture2D newTexture2DToBeLoadedTo = new Texture2D(textureToDownsizeAndCopyToCPU.width / downSize, textureToDownsizeAndCopyToCPU.height / downSize, TextureFormat.ARGB32, false);
// Load textureToDownsizeAndCopyToCPU from something you like...
// Create a temporary downsized texture
RenderTexture textureDownsized = RenderTexture.GetTemporary(textureToDownsizeAndCopyToCPU.width / downSize, textureToDownsizeAndCopyToCPU.height / downSize);
// Remember currently active render texture
RenderTexture currentActiveRT = RenderTexture.active;
RenderTexture.active = textureDownsized;
// Copy textureToDownsizeAndCopyToCPU to textureDownsized
Graphics.Blit(textureToDownsizeAndCopyToCPU, textureDownsized);
// Read the RenderTexture image into it
// Pass GPU bytes to CPU
// Very performance consuming
newTexture2DToBeLoadedTo.ReadPixels(new Rect(0, 0, textureDownsized.width, textureDownsized.height), 0, 0, false);
// Debug.Log(tex2D.width + " " + tex2D.height);
// Restorie previously active render texture
RenderTexture.active = currentActiveRT;
RenderTexture.ReleaseTemporary(textureDownsized);
}
void RenderTextureFromShader()
{
Graphics.Blit(null, RenderTextureDestination, materialShader);
}
1: 赋值图片是灰色
Graphics.CopyTexture(或Graphics.Blit)在GPU端工作,而ReadPixels在CPU上工作。这就是为什么CPU上的EncodetoJPG在ReadPixels而不是CopyTexture之后工作的原因。
您必须使用此程序将JPG保存到磁盘
https://answers.unity.com/questions/1479723/encodetojpg-creates-gray-image-after-using-copytex.html
2:将RenderTexture转换为Texture2D
RenderTexture.active = myRenderTexture;
myTexture2D.ReadPixels(new Rect(0, 0, myRenderTexture.width, myRenderTexture.height), 0, 0);
myTexture2D.Apply();
3:Texture2D到RenderTexture
// texRef is your Texture2D
// You can also reduice your texture 2D that way
RenderTexture rt = new RenderTexture(texRef.width / 2, texRef.height / 2, 0);
RenderTexture.active = rt;
// Copy your texture ref to the render texture
Graphics.Blit(texRef, rt);
// Now you can read it back to a Texture2D if you care
if (tex2D == null)
tex2D = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, true);
tex2D.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0, false);