文章最開始先致敬幾位大佬的文章,有他們的無私奉獻纔有這篇入門級的文章,大家可以一起看看,瞻仰一下大佬們的風采:
如果通過以上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
然後就是輸出結果,隨便寫的 ,給紅色換成白色的: