前言 :
可以先看這篇文章 ( CPU 版本 ) :
https://blog.csdn.net/weixin_38884324/article/details/80457594
相同原理,只是改成GPU版本,加快計算速度 ( 百倍以上性能提升 )。
C # :
using System.IO;
using UnityEngine;
using UnityEngine.UI;
public class GPU_RAW_To_RGB : MonoBehaviour {
public RawImage outputImage;
public ComputeShader shader;
int[] a;
void Start()
{
// 計算執行秒數
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
time.Start();
a = ByteArray_To_IntArray(File.ReadAllBytes("C:/FFMPEG/Hello.raw"));
time.Stop();
print("檔案讀取 " + time.Elapsed.TotalSeconds + " 秒");
Run();
}
int [] ByteArray_To_IntArray(byte [] b) {
int[] i = new int[b.Length];
for (int x = 0; x < b.Length; x++)
{
i[x] = b[x];
}
return i;
}
public void Run()
{
// 計算執行秒數
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
time.Start();
// 預先必須要先知道圖片寬高,因為 RAW 檔案沒有寬高的資訊
int width = 4208;
int height = 3120;
RenderTexture t = new RenderTexture(width, height, 24);
t.enableRandomWrite = true;
t.Create();
outputImage.texture = t;
int k = shader.FindKernel("CSMain");
ComputeBuffer buffer = new ComputeBuffer(a.Length, 4);
buffer.SetData(a);
shader.SetBuffer(k, "a", buffer);
shader.SetInt("width", width);
shader.SetInt("height", height);
shader.SetTexture(k, "outputTexture", t);
shader.Dispatch(k, width, height, 1);
// 釋放
buffer.Dispose();
time.Stop();
print("GPU 執行 " + time.Elapsed.TotalSeconds + " 秒");
}
}
ComputeShader :
#pragma kernel CSMain
int width;
int height;
// ( CPU -> GPU )
StructuredBuffer<int> a;
// ( GPU -> CPU )
RWTexture2D <float4> outputTexture;
[numthreads(1, 1, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
int i = ((width * id.y) + id.x) * 2; // 因為 RAW 10bit 佔用 2 個 byte 所以要乘二
int L = a[i];
int H = a[i + 1];
int D = (H << 8) + L;
float C = D / 1024.0f;
float4 color;
if (id.y % 2 == 0)
{
if (id.x % 2 == 0)
{
color = float4(0, C, 0, 1);
}
else
{
color = float4(C, 0, 0, 1);
}
}
else
{
if (id.x % 2 == 0)
{
color = float4(0, 0, C, 1);
}
else
{
color = float4(0, C, 0, 1);
}
}
float2 pos = float2(id.x, height - 1 - id.y);
outputTexture[pos] = color; // 丟回 CPU
}