Created
January 4, 2020 14:14
-
-
Save zwcloud/5fe7f912ec7353d206bb0c1c15e34742 to your computer and use it in GitHub Desktop.
A unility class with functions to scale Texture2D Data, by petersvp from http://answers.unity.com/answers/987332/view.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
/// A unility class with functions to scale Texture2D Data. | |
/// | |
/// Scale is performed on the GPU using RTT, so it's blazing fast. | |
/// Setting up and Getting back the texture data is the bottleneck. | |
/// But Scaling itself costs only 1 draw call and 1 RTT State setup! | |
/// WARNING: This script override the RTT Setup! (It sets a RTT!) | |
/// | |
/// Note: This scaler does NOT support aspect ratio based scaling. You will have to do it yourself! | |
/// It supports Alpha, but you will have to divide by alpha in your shaders, | |
/// because of premultiplied alpha effect. Or you should use blend modes. | |
public class TextureScaler | |
{ | |
/// <summary> | |
/// Returns a scaled copy of given texture. | |
/// </summary> | |
/// <param name="tex">Source texure to scale</param> | |
/// <param name="width">Destination texture width</param> | |
/// <param name="height">Destination texture height</param> | |
/// <param name="mode">Filtering mode</param> | |
public static Texture2D scaled(Texture2D src, int width, int height, FilterMode mode = FilterMode.Trilinear) | |
{ | |
Rect texR = new Rect(0,0,width,height); | |
_gpu_scale(src,width,height,mode); | |
//Get rendered data back to a new texture | |
Texture2D result = new Texture2D(width, height, TextureFormat.ARGB32, true); | |
result.Resize(width, height); | |
result.ReadPixels(texR,0,0,true); | |
return result; | |
} | |
/// <summary> | |
/// Scales the texture data of the given texture. | |
/// </summary> | |
/// <param name="tex">Texure to scale</param> | |
/// <param name="width">New width</param> | |
/// <param name="height">New height</param> | |
/// <param name="mode">Filtering mode</param> | |
public static void scale(Texture2D tex, int width, int height, FilterMode mode = FilterMode.Trilinear) | |
{ | |
Rect texR = new Rect(0,0,width,height); | |
_gpu_scale(tex,width,height,mode); | |
// Update new texture | |
tex.Resize(width, height); | |
tex.ReadPixels(texR,0,0,true); | |
tex.Apply(true); //Remove this if you hate us applying textures for you :) | |
} | |
// Internal unility that renders the source texture into the RTT - the scaling method itself. | |
static void _gpu_scale(Texture2D src, int width, int height, FilterMode fmode) | |
{ | |
//We need the source texture in VRAM because we render with it | |
src.filterMode = fmode; | |
src.Apply(true); | |
//Using RTT for best quality and performance. Thanks, Unity 5 | |
RenderTexture rtt = new RenderTexture(width, height, 32); | |
//Set the RTT in order to render to it | |
Graphics.SetRenderTarget(rtt); | |
//Setup 2D matrix in range 0..1, so nobody needs to care about sized | |
GL.LoadPixelMatrix(0,1,1,0); | |
//Then clear & draw the texture to fill the entire RTT. | |
GL.Clear(true,true,new Color(0,0,0,0)); | |
Graphics.DrawTexture(new Rect(0,0,1,1),src); | |
} | |
} |
This code leaks memory! You need to dispose the RT when done.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This GPU approach won't work for a texture with alpha channel.
CPU version:
http://wiki.unity3d.com/index.php/TextureScale