はじめに
相変わらず画像処理100本ノックをしています。
前回 -> 【Unity】ComputeShaderでチャンネル変換(RGB -> BGR)をしてみた【Q1】 - はなちるのマイノート
次回 -> 【Unity】ComputeShaderで2値化(Binarization)してみる【Q3】 - はなちるのマイノート
今回はグレースケールについてみていきましょう。
グレースケールとは
グレースケールとは色の濃淡の明暗を分ける技法のことです。
それを実現するには色の情報を以下の計算式に代入し、白黒のグラデーションで表現させます。
Y = 0.2126 R + 0.7152 G + 0.0722 B
とりあえずこの式にいれとけばよいので、すごい簡単ですよね。
コード
ComputeShader
のコードはこんな感じ。
#pragma kernel GrayScale RWTexture2D<float4> Result; Texture2D<float4> Texture; [numthreads(8,8,1)] void GrayScale (uint3 id : SV_DispatchThreadID) { float gray = 0.2126 * Texture[id.xy].x + 0.7152 * Texture[id.xy].y + 0.0722 * Texture[id.xy].z; Result[id.xy] = float4(gray, gray, gray, 1); }
UnityのCPU側のコードはこんな感じ。
using UnityEngine; using UnityEngine.UI; public class GrayScale : MonoBehaviour { [SerializeField] private ComputeShader _computeShader; [SerializeField] private Texture2D _tex; [SerializeField] private RawImage _renderer; private RenderTexture _result; private void Start() { if(!SystemInfo.supportsComputeShaders) { Debug.LogError("Comppute Shader is not support."); return; } // RenderTextueの初期化 _result = new RenderTexture(_tex.width, _tex.height, 0, RenderTextureFormat.ARGB32); _result.enableRandomWrite = true; _result.Create(); // GreayScaleのカーネルインデックス(0)を取得 var kernelIndex = _computeShader.FindKernel("GrayScale"); // 一つのグループの中に何個のスレッドがあるか ThreadSize threadSize = new ThreadSize(); _computeShader.GetKernelThreadGroupSizes(kernelIndex, out threadSize.x, out threadSize.y, out threadSize.z); // GPUにデータをコピーする _computeShader.SetTexture(kernelIndex, "Texture", _tex); _computeShader.SetTexture(kernelIndex, "Result", _result); // GPUの処理を実行する _computeShader.Dispatch(kernelIndex, _tex.width / (int)threadSize.x, _tex.height / (int)threadSize.y, (int)threadSize.z); // テクスチャを適応する _renderer.texture = _result; } private void OnDestroy() { _result = null; } } struct ThreadSize { public uint x; public uint y; public uint z; public ThreadSize(uint x, uint y, uint z) { this.x = x; this.y = y; this.z = z; } }
さいごに
ComputeShaderも含めてShader全般になんですが、VisualStudioがメモ帳同然になってしまうのはどうすればよいのでしょうか。
一応拡張機能もあるみたいなのですが、よく分かっていません・・・。
もう少し調べてみます。