使用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
上一篇下一篇

猜你喜欢

热点阅读