Unity 3D : RAW 10 bit 轉 RGB ( GPU 版 ) [ 新版本 2 ]
哈哈哈,寫了好多個版本了,這次又有新功能啦
這次可以支持四種拜爾排列方式:GRBG, GBRG, RGGB, BGGR
另外也能統計 R, G1, G2, B 通道的平均值
C # :
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;public class RAW_To_RGB : MonoBehaviour
{public RawImage outputTexture_RAW, outputTexture_RGB;public ComputeShader shader;void Start(){System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();time.Start();// 圖片地址, RAW 格式(bit數&排列方式), 圖片寬, 圖片高ImageData imgData = Read_RAW_RGB("C:/FFMPEG/Hello.raw", "RAW10_GRBG", 4208, 3120);time.Stop();print("執行 " + time.Elapsed.TotalSeconds + " 秒");outputTexture_RAW.texture = imgData.TextureRAW;outputTexture_RGB.texture = imgData.TextureRGB;print("All : " + imgData.AvgColorAll + " AvgG1 : " + imgData.AvgColor1+ " AvgR : " + imgData.AvgColor2 + " AvgB : " + imgData.AvgColor3 + " AvgG2 : " + imgData.AvgColor4);}// format : RAW10_RGGB, RAW10_BGGR, RAW10_GRBG, RAW10_GBRG// format example : RAW10_RGGB = RAW 10bit R:1, G:2, G:3, B:4public ImageData Read_RAW_RGB(string filePath, string format, int width, int height){int ThreadGroupSize_X = 8; // 別亂動,動了統計資訊那邊會有 BUG,也許沒動也會有 ? 哈int ThreadGroupSize_Y = 8; // 別亂動,動了統計資訊那邊會有 BUG,也許沒動也會有 ? 哈int ThreadGroupSize = ThreadGroupSize_X * ThreadGroupSize_Y;RenderTexture texture_RAW = new RenderTexture(width, height, 24);texture_RAW.enableRandomWrite = true;texture_RAW.Create();RenderTexture texture_RGB = new RenderTexture(width, height, 24);texture_RGB.enableRandomWrite = true;texture_RGB.Create();int k = shader.FindKernel(format);shader.SetTexture(k, "outputTexture_RAW", texture_RAW);shader.SetTexture(k, "outputTexture_RGB", texture_RGB);shader.SetInt("width", width);shader.SetInt("height", height);// -----------------------------------------------------------------------------------// 將整個檔案放入 GPUint[] file = ByteArray_To_IntArray(File.ReadAllBytes(filePath));ComputeBuffer file_buffer = new ComputeBuffer(file.Length, sizeof(int));file_buffer.SetData(file);shader.SetBuffer(k, "file", file_buffer);// -----------------------------------------------------------------------------------// 初始化統計資料的參數uint[] SumColor1_Array = new uint[ThreadGroupSize];ComputeBuffer sumColor1_buffer = new ComputeBuffer(SumColor1_Array.Length, sizeof(uint));sumColor1_buffer.SetData(SumColor1_Array);shader.SetBuffer(k, "SumColor1_Array", sumColor1_buffer);uint[] SumColor2_Array = new uint[ThreadGroupSize];ComputeBuffer sumColor2_buffer = new ComputeBuffer(SumColor2_Array.Length, sizeof(uint));sumColor2_buffer.SetData(SumColor2_Array);shader.SetBuffer(k, "SumColor2_Array", sumColor2_buffer);uint[] SumColor3_Array = new uint[ThreadGroupSize];ComputeBuffer sumColor3_buffer = new ComputeBuffer(SumColor3_Array.Length, sizeof(uint));sumColor3_buffer.SetData(SumColor3_Array);shader.SetBuffer(k, "SumColor3_Array", sumColor3_buffer);uint[] SumColor4_Array = new uint[ThreadGroupSize];ComputeBuffer sumColor4_buffer = new ComputeBuffer(SumColor4_Array.Length, sizeof(uint));sumColor4_buffer.SetData(SumColor4_Array);shader.SetBuffer(k, "SumColor4_Array", sumColor4_buffer);// -----------------------------------------------------------------------------------// 執行shader.Dispatch(k, width / ThreadGroupSize_X, height / ThreadGroupSize_Y, 1);// -----------------------------------------------------------------------------------// 取得統計資料並計算sumColor1_buffer.GetData(SumColor1_Array);sumColor2_buffer.GetData(SumColor2_Array);sumColor3_buffer.GetData(SumColor3_Array);sumColor4_buffer.GetData(SumColor4_Array);long SumColor1 = 0, SumColor2 = 0, SumColor3 = 0, SumColor4 = 0;for (int i = 0; i < SumColor1_Array.Length; i++){SumColor1 += SumColor1_Array[i];SumColor2 += SumColor2_Array[i];SumColor3 += SumColor3_Array[i];SumColor4 += SumColor4_Array[i];}ImageData imgData = new ImageData();imgData.Base = (width * height) / 4;imgData.AvgColorAll = ((SumColor1 + SumColor2 + SumColor3 + SumColor4) / 4) / imgData.Base;imgData.AvgColor1 = SumColor1 / imgData.Base;imgData.AvgColor2 = SumColor2 / imgData.Base;imgData.AvgColor3 = SumColor3 / imgData.Base;imgData.AvgColor4 = SumColor4 / imgData.Base;imgData.TextureRAW = texture_RAW;imgData.TextureRGB = texture_RGB;// -----------------------------------------------------------------------------------// 釋放資源file_buffer.Dispose();sumColor1_buffer.Dispose();sumColor2_buffer.Dispose();sumColor3_buffer.Dispose();sumColor4_buffer.Dispose();// -----------------------------------------------------------------------------------return imgData;}int[] ByteArray_To_IntArray(byte[] b){int[] i = new int[b.Length];int thread_count = 8; // 設定線程數量// 如果設定的線程數量可以被整除,那就用多線程,否則用單線程。if (i.Length % thread_count != 0){//單線程for (int x = 0; x < b.Length; x++){i[x] = b[x];}}else{//多線程int thread_size = i.Length / thread_count;using (ManualResetEvent finish = new ManualResetEvent(false)){int currentThreadCount = thread_count;for (int t = 0; t < thread_count; t++){int start = thread_size * t;int end = thread_size * t + thread_size;int[] v = new int[] { start, end };ThreadPool.QueueUserWorkItem((System.Object state) =>{int[] v2 = state as int[];int start2 = v2[0];int end2 = v2[1];for (int x = start2; x < end2; x++){i[x] = b[x];}if (Interlocked.Decrement(ref currentThreadCount) == 0){finish.Set();}}, v);}// 等待所有 Thread 執行完畢finish.WaitOne();}}return i;}public struct ImageData{public Texture TextureRAW;public Texture TextureRGB;public float AvgColorAll;public float AvgColor1;public float AvgColor2;public float AvgColor3;public float AvgColor4;public float Base;}
}
ComputeShader :
#pragma kernel RAW10_RGGB
#pragma kernel RAW10_BGGR
#pragma kernel RAW10_GRBG
#pragma kernel RAW10_GBRGint width, height; // 輸入圖像寬高Buffer <int> file; // 輸入檔案 Byte 流RWTexture2D<float4> outputTexture_RAW; // 輸出 RAW 貼圖RWTexture2D<float4> outputTexture_RGB; // 輸出 RGB 貼圖RWBuffer <uint> SumColor1_Array, SumColor2_Array, SumColor3_Array, SumColor4_Array;[numthreads(8, 8, 1)]
void RAW10_RGGB(uint3 id : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
{//------------------------------------------------------------------------------------------// 只讓左上角的點進入uint x = id.x, y = height - id.y - 1;if (x % 2 != 0 || y % 2 != 0) return;//------------------------------------------------------------------------------------------// 處理 RAW 檔int width_byte = width * 2;int i = ((width * y) + x) * 2; // 因為 RAW 10bit 佔用 2 個 byte 所以要乘二int R = file[i] | (file[i + 1] << 8); // 左上int G1 = file[i + 2] | (file[i + 3] << 8); // 右上int G2 = file[i + width_byte] | (file[i + 1 + width_byte] << 8); // 左下int B = file[i + width_byte + 2] | (file[i + 3 + width_byte] << 8); // 右下float r = R / 1023.0f;float g1 = G1 / 1023.0f;float g2 = G2 / 1023.0f;float b = B / 1023.0f;outputTexture_RAW[uint2(id.x, id.y)] = float4(r, 0, 0, 1); // 左上outputTexture_RAW[uint2(id.x + 1, id.y)] = float4(0, g1, 0, 1); // 右上outputTexture_RAW[uint2(id.x, id.y - 1)] = float4(0, g2, 0, 1); // 左下outputTexture_RAW[uint2(id.x + 1, id.y - 1)] = float4(0, 0, b, 1); // 右下//------------------------------------------------------------------------------------------// 處理 RGB 檔float4 Color = float4(r, (g1 + g2) / 2, b, 1);outputTexture_RGB[uint2(id.x, id.y)] = Color; // 左上outputTexture_RGB[uint2(id.x + 1, id.y)] = Color; // 右上outputTexture_RGB[uint2(id.x, id.y - 1)] = Color; // 左下outputTexture_RGB[uint2(id.x + 1, id.y - 1)] = Color; // 右下//------------------------------------------------------------------------------------------// 統計資訊 InterlockedAdd(SumColor1_Array[groupIndex.x], R); // 左上InterlockedAdd(SumColor2_Array[groupIndex.x], G1); // 右上InterlockedAdd(SumColor3_Array[groupIndex.x], G2); // 左下InterlockedAdd(SumColor4_Array[groupIndex.x], B); // 右下
}[numthreads(8, 8, 1)]
void RAW10_BGGR(uint3 id : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
{//------------------------------------------------------------------------------------------// 只讓左上角的點進入uint x = id.x, y = height - id.y - 1;if (x % 2 != 0 || y % 2 != 0) return;//------------------------------------------------------------------------------------------// 處理 RAW 檔int width_byte = width * 2;int i = ((width * y) + x) * 2; // 因為 RAW 10bit 佔用 2 個 byte 所以要乘二int B = file[i] | (file[i + 1] << 8); // 左上int G1 = file[i + 2] | (file[i + 3] << 8); // 右上int G2 = file[i + width_byte] | (file[i + 1 + width_byte] << 8); // 左下int R = file[i + width_byte + 2] | (file[i + 3 + width_byte] << 8); // 右下float b = R / 1023.0f;float g1 = G1 / 1023.0f;float g2 = G2 / 1023.0f;float r = B / 1023.0f;outputTexture_RAW[uint2(id.x, id.y)] = float4(0, 0, b, 1); // 左上outputTexture_RAW[uint2(id.x + 1, id.y)] = float4(0, g1, 0, 1); // 右上outputTexture_RAW[uint2(id.x, id.y - 1)] = float4(0, g2, 0, 1); // 左下outputTexture_RAW[uint2(id.x + 1, id.y - 1)] = float4(r, 0, 0, 1); // 右下//------------------------------------------------------------------------------------------// 處理 RGB 檔float4 Color = float4(r, (g1 + g2) / 2, b, 1);outputTexture_RGB[uint2(id.x, id.y)] = Color; // 左上outputTexture_RGB[uint2(id.x + 1, id.y)] = Color; // 右上outputTexture_RGB[uint2(id.x, id.y - 1)] = Color; // 左下outputTexture_RGB[uint2(id.x + 1, id.y - 1)] = Color; // 右下//------------------------------------------------------------------------------------------// 統計資訊InterlockedAdd(SumColor1_Array[groupIndex.x], B); // 左上InterlockedAdd(SumColor2_Array[groupIndex.x], G1); // 右上InterlockedAdd(SumColor3_Array[groupIndex.x], G2); // 左下InterlockedAdd(SumColor4_Array[groupIndex.x], R); // 右下
}[numthreads(8, 8, 1)]
void RAW10_GRBG(uint3 id : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
{//------------------------------------------------------------------------------------------// 只讓左上角的點進入uint x = id.x, y = height - id.y - 1;if (x % 2 != 0 || y % 2 != 0) return;//------------------------------------------------------------------------------------------// 處理 RAW 檔int width_byte = width * 2;int i = ((width * y) + x) * 2; // 因為 RAW 10bit 佔用 2 個 byte 所以要乘二int G1 = file[i] | (file[i + 1] << 8); // 左上int R = file[i + 2] | (file[i + 3] << 8); // 右上int B = file[i + width_byte] | (file[i + 1 + width_byte] << 8); // 左下int G2 = file[i + width_byte + 2] | (file[i + 3 + width_byte] << 8); // 右下float g1 = G1 / 1023.0f;float r = R / 1023.0f;float b = B / 1023.0f;float g2 = G2 / 1023.0f;outputTexture_RAW[uint2(id.x, id.y)] = float4(0, g1, 0, 1); // 左上outputTexture_RAW[uint2(id.x + 1, id.y)] = float4(r, 0, 0, 1); // 右上outputTexture_RAW[uint2(id.x, id.y - 1)] = float4(0, 0, b, 1); // 左下outputTexture_RAW[uint2(id.x + 1, id.y - 1)] = float4(0, g2, 0, 1); // 右下//------------------------------------------------------------------------------------------// 處理 RGB 檔float4 Color = float4(r, (g1 + g2) / 2, b, 1);outputTexture_RGB[uint2(id.x, id.y)] = Color; // 左上outputTexture_RGB[uint2(id.x + 1, id.y)] = Color; // 右上outputTexture_RGB[uint2(id.x, id.y - 1)] = Color; // 左下outputTexture_RGB[uint2(id.x + 1, id.y - 1)] = Color; // 右下//------------------------------------------------------------------------------------------// 統計資訊InterlockedAdd(SumColor1_Array[groupIndex.x], G1);InterlockedAdd(SumColor2_Array[groupIndex.x], R);InterlockedAdd(SumColor3_Array[groupIndex.x], B);InterlockedAdd(SumColor4_Array[groupIndex.x], G2);
}[numthreads(8, 8, 1)]
void RAW10_GBRG(uint3 id : SV_DispatchThreadID, uint groupIndex : SV_GroupIndex)
{//------------------------------------------------------------------------------------------// 只讓左上角的點進入uint x = id.x, y = height - id.y - 1;if (x % 2 != 0 || y % 2 != 0) return;//------------------------------------------------------------------------------------------// 處理 RAW 檔int width_byte = width * 2;int i = ((width * y) + x) * 2; // 因為 RAW 10bit 佔用 2 個 byte 所以要乘二int G1 = file[i] | (file[i + 1] << 8); // 左上int B = file[i + 2] | (file[i + 3] << 8); // 右上int R = file[i + width_byte] | (file[i + 1 + width_byte] << 8); // 左下int G2 = file[i + width_byte + 2] | (file[i + 3 + width_byte] << 8); // 右下float g1 = G1 / 1023.0f;float b = R / 1023.0f;float r = B / 1023.0f;float g2 = G2 / 1023.0f;outputTexture_RAW[uint2(id.x, id.y)] = float4(0, g1, 0, 1); // 左上outputTexture_RAW[uint2(id.x + 1, id.y)] = float4(0, 0, b, 1); // 右上outputTexture_RAW[uint2(id.x, id.y - 1)] = float4(r, 0, 0, 1); // 左下outputTexture_RAW[uint2(id.x + 1, id.y - 1)] = float4(0, g2, 0, 1); // 右下//------------------------------------------------------------------------------------------// 處理 RGB 檔float4 Color = float4(r, (g1 + g2) / 2, b, 1);outputTexture_RGB[uint2(id.x, id.y)] = Color; // 左上outputTexture_RGB[uint2(id.x + 1, id.y)] = Color; // 右上outputTexture_RGB[uint2(id.x, id.y - 1)] = Color; // 左下outputTexture_RGB[uint2(id.x + 1, id.y - 1)] = Color; // 右下//------------------------------------------------------------------------------------------// 統計資訊 InterlockedAdd(SumColor1_Array[groupIndex.x], G1);InterlockedAdd(SumColor2_Array[groupIndex.x], B);InterlockedAdd(SumColor3_Array[groupIndex.x], R);InterlockedAdd(SumColor4_Array[groupIndex.x], G2);
}
Unity 3D : RAW 10 bit 轉 RGB ( GPU 版 ) [ 新版本 2 ]相关推荐
- 《Unity 3D 游戏开发技术详解与典型案例》——1.1节Unity 3D基础知识概览
本节书摘来自异步社区<Unity 3D 游戏开发技术详解与典型案例>一书中的第1章,第1.1节Unity 3D基础知识概览,作者 吴亚峰 , 于复兴,更多章节内容可以访问云栖社区" ...
- 使用Unity 3D开发Hololens入门教程
Microsoft已经发布了官方的Hololens SDK,本文将深入介绍使用Emulator(模拟器)开发Hololens,教大家如何使用Visual Studio 和 Unity 3D打造你的第一 ...
- 如何用通过Unity 3D生成真实地形
如何用通过Unity 3D生成真实地形 发布时间:2018-06-27 版权: 相关教程: 1.建筑物轮廓三维立体图生成 其他三维制作视频教程:Bigemap视频教程-支持200多种格式互转kml\s ...
- Unity 3D : ComputeShader 全面詳解
Unity 3D : ComputeShader 全面詳解 https://blog.csdn.net/weixin_38884324/article/details/80570160 前言: 會寫一 ...
- Unity 3D学习视觉脚本无需编码即可创建高级游戏
在本课程中,您将学习如何在Unity中使用可视化脚本(以前称为Bolt)以及如何在不编写一行代码的情况下创建自己的高级游戏所需的一切.本课程将教你如何掌握可视化脚本,即使你以前没有任何关于unity或 ...
- Unity三维游戏开发C#编程大师班 Masterclass In C# Programing Unity 3D Game Development FPS
本课程采用现代游戏开发(Unity 2021)的最新内容和最新技术 学习任何东西的最好方法是以一种真正有趣的方式去做,这就是这门课程的来源.如果你想了解你看到的这些不可思议的游戏是如何制作的,没有比这 ...
- 《Unity 3D 游戏开发技术详解与典型案例》——1.3节第一个Unity 3D程序
本节书摘来自异步社区<Unity 3D 游戏开发技术详解与典型案例>一书中的第1章,第1.3节第一个Unity 3D程序,作者 吴亚峰 , 于复兴,更多章节内容可以访问云栖社区" ...
- Unity 3D网络游戏实战 pdf
Unity 3D网络游戏实战(全) 目录: 掌握Unity3D基本元素 1.1 简单的游戏 1.1.1在场景中创建一个立方体 1.1.2编写可以使立方体运动的程序 1.1.3测试游戏1.1.4总结1. ...
- 在Unity 3D中,shader是何时编译的,在何时加载入显存中的?
在Unity 3D中,shader是何时编译的,在何时加载入显存中的? 是某一对象在实例化时,加载其相关的material与shader还是游戏开始时? 添加评论 分享 按时间排序按投票排序 4 个回 ...
最新文章
- 强化学习笔记:Actor-critic
- 安卓总结 之 OkHttp使用及源码分析(三)
- AtCoder Regular Contest 064
- Core Audio音频基础概述
- 远程访问数据库出错的解决办法
- 16.对极几何——介绍,立体视觉约束,条件_1
- Cuda:invalid device pointer
- java中插入表格_java 集成 pageoffice 实现在 word 中插入表格并赋值
- php 处理eml,PHP读取、解析eml文件及生成网页的方法示例
- C++中常引用的注意事项以及常引用和非常引用之间的转换
- 第32课 - 初探C++ 标准库
- 计算机重启打印服务关闭,电脑打印机消失print spooler服务启动后自动停止
- Unity 3D 特效学习记录
- Android Studio 关于android resource linking failed的报错解决方法
- 医疗器械小程序或手机APP软件开发方案
- 关于vs2022设置默认浏览器
- 【JZOJ3794】【洛谷P1383】高级打字机【主席树】
- 通信之道-傅立叶分析
- 365天挑战LeetCode1000题——Day 117 矩形区域不超过 K 的最大数值和
- Python金融数据分析之路(一)