利用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

然後就是輸出結果,隨便寫的 ,給紅色換成白色的:


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