こんにちは、ちゃらいプログラマです。 弊社で開発/運用しているスマートフォンアプリの「ポケットずかん」に塗り絵機能が追加されました。
技術研究の名目で2回ほど記事を書かさせて頂きましたが製品版にするにあたり色々試行錯誤をしました。
以前は
1.画面タッチした箇所の色を塗りつぶしたい色で塗りつぶす (塗りつぶし機能)
2.画面ドラッグ開始した箇所の色のみを指定した色で指定した太さで塗る(塗り機能)
でしたが製品版にするにあたり
3.消しゴム機能の追加
を行いました。
また、以前は画面タッチした座標の現在のピクセルカラーを基準としていましたが 製品版では、画面タッチした座標の基礎画像のピクセルカラーを基準とするように変更しています。
以前記事で書いたシェーダーと基礎部分は大きく変わっていませんが消しゴム機能が追加になったので拡張されています。
Shader "Custom/PaintShader" { Properties { // RenderTextureが割り当てられる _MainTex("Texture", 2D) = "white" {} // 基礎画像が割り当てられる _BaseTex("Texture", 2D) = "white" {} // 出力カラー _OutColor("OutColor", Color) = (1,1,1,1) // 開始ブラシ情報 // xy値:ブラシ座標 // z値:ブラシ種類(0:太い線,1:細い線,2:塗りつぶし,3:消しゴム) // w値:1で塗る _StartBrush("StartBrush", Vector) = (0,0,0,0) _CurrentBrush("CurrentBrush", Vector) = (0,0,0,0) // ブラシ半径 _BrushRadius("BrushRadius", Range(0.01, 0.1)) = 0 } SubShader { Tags { "Queue" = "Transparent" "RenderType" = "Transparent" } Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata_t { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; sampler2D _BaseTex; fixed4 _OutColor; fixed4 _StartBrush; fixed4 _CurrentBrush; float _BrushRadius; // 頂点シェーダー v2f vert( appdata_t v ) { v2f o; o.vertex = UnityObjectToClipPos( v.vertex ); o.uv = v.uv; return o; } // フラグメントシェーダー fixed4 frag( v2f i ) : SV_Target { fixed4 col = tex2D( _MainTex, i.uv ); fixed4 baseCol = tex2D( _BaseTex, i.uv ); fixed4 uvCol = tex2D( _BaseTex, _StartBrush.xy ); // 塗る/塗らない判定 float inCol = (1.0 - abs(sign( uvCol.g - baseCol.g ))) - baseCol.r; inCol = _StartBrush.w == 1.0 ? inCol : 0.0; inCol = _CurrentBrush.z != 2.0 ? step(distance(i.uv, _CurrentBrush.xy), _BrushRadius) * inCol : inCol; // 出力カラー設定 float fill = 1.0 - abs(sign( 1.0 - col.a )); fixed4 outLineCol = fixed4( 0,0,0,1 ); fixed4 outBaseCol = fill == 1.0 ? col : fixed4( 1,1,1,1 ); fixed4 outBrushCol = _CurrentBrush.z == 3.0 ? fixed4( 1,1,1,1 ) : _OutColor; return ((baseCol.r >= 1.0) ? outLineCol : outBaseCol) * abs(1.0 - inCol) + outBrushCol * inCol; } ENDCG } } }
実行するとInspecterは以下のようになります。
無事製品版に落とし込めてよかった・・・
ではまた次回!