使用computeShader加速Texture2D叠加处理
2019-01-05 本文已影响0人
Kasug
对于Texture2D,Unity提供了Texture2D.SetPixels(x,y,Color)来设置每个像素的RGBA值,但这种方法效率较低。
我这里使用一张2048x1024的背景图,和一张256x256的前景图进行合并
public Texture2D characterTex;
public Texture2D inputTexture;
public RawImage outputImage;
void Start () {
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
Texture2D tex = new Texture2D(inputTexture.width, inputTexture.height);
int inputWidth = inputTexture.width;
int inputHeight = inputTexture.height;
int characterWidth = characterTex.width;
int characterHeight = characterTex.height;
//定位到左下角
for (int x = 0; x < inputWidth; x++)
{
for (int y = 0; y < inputHeight; y++)
{
if (x < characterWidth && y < characterHeight)
tex.SetPixel(x, y, characterTex.GetPixel(x, y));
else
tex.SetPixel(x, y, inputTexture.GetPixel(x, y));
}
}
tex.Apply();
outputImage.texture = tex;
watch.Stop();
print(watch.Elapsed.TotalMilliseconds);
}
结果显示为大约550ms
图片.png
再来看看ComputeShader的加速效果
新建立ComputerShader输入以下代码
#pragma kernel CSMain
RWTexture2D<float4> outputTexture;
Texture2D inputTexture;
Texture2D characterTex;
int x;
int y;
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
// TODO: insert actual code here!
float R = (id.x >= x || id.y >= y) ? inputTexture[id.xy].r : characterTex[id.xy].r;
float G = (id.x >= x || id.y >= y) ? inputTexture[id.xy].g : characterTex[id.xy].g;
float B = (id.x >= x || id.y >= y) ? inputTexture[id.xy].b : characterTex[id.xy].b;
float A = 1;
outputTexture[id.xy] = float4(R, G, B, A);
}
再建立一个cs脚本
public Texture2D inputTexture;
public RawImage outputImage;
public ComputeShader shader;
public Texture2D characterTex;
void Start () {
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
RenderTexture tex = new RenderTexture(inputTexture.width, inputTexture.height, 24);
tex.enableRandomWrite = true;
tex.Create();
outputImage.texture = tex;
int kernel = shader.FindKernel("CSMain");
shader.SetInt("x", characterTex.width);
shader.SetInt("y", characterTex.height);
shader.SetTexture(kernel, "inputTexture", inputTexture);
shader.SetTexture(kernel, "characterTex", characterTex);
shader.SetTexture(kernel, "outputTexture", tex);
shader.Dispatch(kernel, inputTexture.width, inputTexture.height, 1);
watch.Stop();
print(watch.Elapsed.TotalMilliseconds);
}
大约1ms左右,确实降低不少
图片.png