利用GPU处理大量繁琐的计算,以图像抠图为例(入门级)

       文章最开始先致敬几位大佬的文章,有他们的无私奉献才有这篇入门级的文章,大家可以一起看看,瞻仰一下大佬们的风采:

文章1文章2文章3文章4

      如果通过以上4篇文章大家可以理解了ComputeShader并且满足了需求,那现在你就可以关闭页面了,接下来是针对不太理解的萌新的。

      言归正传,在看了上述几位大佬的文章以后,问我也照着写以一个抠图的脚本,结果有报错,并且其中的一些参数也不是太了解,后来经过苦苦思索倒是想通了某些关键和几个需要注意的点,现在写出来给可能用到的各位。

       先贴我的抠图代码吧:

       C#:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MattingTexture : MonoBehaviour
{
    public Texture2D inputTexture;//输入图片
    public RawImage outputImage;//输出显示框
    public ComputeShader shader;
    int k;
    RenderTexture t;//输出图片
    // Use this for initialization
    void Start ()
    {
        t = new RenderTexture(inputTexture.width, inputTexture.height, 24);
        t.enableRandomWrite = true;
        t.Create();
        outputImage.texture = t;

        k = shader.FindKernel("CSMain");
        
    }
	
	// Update is called once per frame
	void Update () {
		
	}

    public void StartChange()
    {
        shader.SetTexture(k, "inputTexture", inputTexture);
        shader.SetTexture(k, "outputTexture", t);
        shader.Dispatch(k, inputTexture.width / 8, inputTexture.height / 8, 1);
    }
}

     shader:

// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain
Texture2D inputTexture;

RWTexture2D <float4> outputTexture;
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
	// TODO: insert actual code here!
	//for (int a = 0;a < dataCount;a++) {
	//	if (textureData[a].intR > minR) {
	//		if (textureData[a].intG < maxG) {
	//			if (textureData[a].intB < maxB) {

	//				continue;
	//			}
	//		}
	//	}
	//	textureData[a].intA = 0;//不满足条件设为透明
	//}
	float R = inputTexture[id.xy].r;
	float G = inputTexture[id.xy].g;
	float B = inputTexture[id.xy].b;
	float A = 1;
	if (R > 0.5) {
		if (G < 0.1) {
			if (B < 0.2) {
				R = G = B = 1;
				//A = 1;
			}
		}
	}
	outputTexture[id.xy] = float4(R, G, B, A); //过滤RGB
	
}

第一:问:C#中Dispatch中我为什么要除8呢?答案:因为在shader中我把线程分为了(8,8,1),这个什么意思呢?参考文章1说通俗点(可能不太对)就是有三个“核心”X、Y、Z,X分成了8个线程,Y分成8个,Z还是1个,每一个线程又分成一个 数组,那每个线程数组就有inputTexture.width / 8个需要处理的 项。

第二:问shader中的main的ID是什么?答:就是这个三维数组中的索引,在本例中就是像素的编号。

第三:注意:在shader中不要给小数后边加f,亲测,定义中加f会报错:Shader error in 'ChangeTexture.compute': syntax error: unexpected token 'f' at kernel CSMain at ChangeTexture.compute

然后就是输出结果,随便写的 ,给红色换成白色的:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章