【Unity】ShaderでWaterMarkを任意位置に合成する
2020-10-08 2021-01-19
画面の任意の位置にメインのテクスチャの上に半透明でサブテクスチャを合成する方法.
Env.
Windows 10
Unity2019.3.3f1
Source
以下のShaderを作成.マテリアルを作成して,CustomRenderTextureにアタッチして使う.
CustomRenderTextureをRawImageなどに貼り付けると合成した結果が得られる.
MainTexにRenderTextureなどで画面の映像を入力し,
SubTexにWaterMarkなどの合成した画像を入力する.
UVPositionとSizeの値を変化させることでSubTexの位置と大きさを変化させ,
ThresholdとAlphaの値を変化させることで透明度と表示するピクセルを調整できる.
CRTUpdate.shader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
Shader "CRTUpdate" { Properties{ _MainTex("MainTexture", 2D) = "white" {} _SubTex("SubTexture", 2D) = "white" {} _UVPosition("UV Position", VECTOR) = (0.5, 0.5, 0, 0)//合成するTextureの中心座標 _Size("PaintSize", Range(0.001, 0.5)) = 0.1//合成するTextureの大きさ _Threshold("Threshold",Range(0, 1)) = 1 _Alpha("Alpha",Range(0, 1)) = 1 } SubShader { Cull Off ZWrite Off ZTest Always Pass { Name "Update" CGPROGRAM sampler2D _MainTex; sampler2D _SubTex; float4 _UVPosition; float _Size; float _Threshold; float _Alpha; #include "UnityCG.cginc" #include "UnityUI.cginc" #include "UnityCustomRenderTexture.cginc" #pragma vertex CustomRenderTextureVertexShader #pragma fragment frag half4 frag(v2f_customrendertexture i) : SV_Target { fixed4 color = tex2D(_MainTex, i.localTexcoord); float com; com = step(_UVPosition.x - _Size, i.localTexcoord.x); com = step(i.localTexcoord.x, _UVPosition.x + _Size) * com; com = step(_UVPosition.y - _Size, i.localTexcoord.y) * com; com = step(i.localTexcoord.y, _UVPosition.y + _Size) * com; fixed4 sub = tex2D(_SubTex, (i.localTexcoord - _UVPosition) * 0.5 / _Size + 0.5); if (sub.a > _Threshold) { color = color + (color * sub * _Alpha); } return color; } ENDCG } } } |
また,CustomRenderTextureにスクリプトからアタッチするときは
以下のように初期化しないと更新されなかった.
1 2 3 4 5 6 7 8 |
var customRenderTexture = new CustomRenderTexture(width, height, RenderTextureFormat.ARGBHalf); customRenderTexture.initializationMode = CustomRenderTextureUpdateMode.Realtime; customRenderTexture.updateMode = CustomRenderTextureUpdateMode.Realtime; customRenderTexture.material = CRTUpdateMaterial; customRenderTexture.material.SetTexture("_MainTex", mainTexRenderTexture); targetRawImage.texture = customRenderTexture; |
合成するとこのような感じになる.
今回の執筆時にRenderTexuterをNDIで送出する必要があったので,CustomRenderTexutureを使ったが,直接RawImageにマテリアルでセットしてもよい.
以下はマテリアルの設定.