質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

1回答

14042閲覧

Unityでスプライトの重ね合わせで覆い焼きと乗算を適用したい

yrema

総合スコア286

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2018/12/11 17:27

編集2022/01/12 10:55

タイトルの通りですが、
Photoshopで言うところのレイヤー構成が、
レイヤー1 ・・・ キャラクターの明るい部分(覆い焼きレイヤー)
レイヤー2 ・・・ キャラクターの暗い部分(乗算レイヤー)
レイヤー3 ・・・ キャラクターのベースになる部分(通常レイヤー)
という状態をUnityのスプライトを重ねて実現したいです。
スプライト1・・・覆い焼き用のスプライト
スプライト2・・・乗算用のスプライト
スプライト3・・・ベース用のスプライト (プレイヤーはここの色は自由に変えられる)

ビルトインシェーダーというものを使うとできるらしいと思い込み、
Unity公式から builtin_shaders-2017.1.3f1 をダウンロードしてきましたが、
どのファイルが覆い焼きなのか分からないのですが、そもそもこのやり方が合っているでしょうか?

◆環境
Unity2017 3.1f1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ビルトインシェーダーの中の使えそうなファイルをコピーして、さらにそれを改造する必要があるのではないでしょうか?

「DefaultResourcesExtra/Sprites-Default.shader」をコピーして「Sprites-Multiply.shader」などと別名を付けて開いてみますと、先頭部分にShader "Sprites/Default"とシェーダー名を付けている部分がありますが、それをShader "Sprites/Multiply"とでも変えて新しい名前を付け、さらに真ん中あたりにBlend ...と書かれた行があるかと思いますので、ShaderLab: Blending - Unity マニュアルなどをご参考に変更してみてください。
新しいシェーダーをプロジェクトにインポートして、それを使ったマテリアルを作り、それをスプライトにセットすればカスタマイズされた独自の描画モードで合成されるはずです。

「乗算」はBlend DstColor Zero、「覆い焼き (リニア) - 加算」はBlend SrcAlpha Oneである程度再現できると思います。「覆い焼き (リニア) - 加算」を例示しますと、下記のようになるでしょう。

ShaderLab

1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3Shader "Sprites/LinearDodge" 4{ 5 Properties 6 { 7 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 8 _Color ("Tint", Color) = (1,1,1,1) 9 [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 10 [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1) 11 [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1) 12 [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {} 13 [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0 14 } 15 16 SubShader 17 { 18 Tags 19 { 20 "Queue"="Transparent" 21 "IgnoreProjector"="True" 22 "RenderType"="Transparent" 23 "PreviewType"="Plane" 24 "CanUseSpriteAtlas"="True" 25 } 26 27 Cull Off 28 Lighting Off 29 ZWrite Off 30 Blend SrcAlpha One 31 32 Pass 33 { 34 CGPROGRAM 35 #pragma vertex SpriteVert 36 #pragma fragment SpriteFrag 37 #pragma target 2.0 38 #pragma multi_compile_instancing 39 #pragma multi_compile _ PIXELSNAP_ON 40 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 41 #include "UnitySprites.cginc" 42 ENDCG 43 } 44 } 45}

ですが、「乗算」を同じようにやるとアルファチャンネルを持つスプライトの乗算が気に入らなかったり、あるいはリニアでない方の「覆い焼き」を再現したい...といったことがあるかもしれません。その場合はフラグメントシェーダーのカスタマイズも必要になるでしょう。

例えば「乗算」は、下記のようにするとPhotoshopの乗算に近づくと思います。

ShaderLab

1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3Shader "Sprites/Multiply" 4{ 5 Properties 6 { 7 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 8 _Color ("Tint", Color) = (1,1,1,1) 9 [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 10 [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1) 11 [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1) 12 [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {} 13 [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0 14 } 15 16 SubShader 17 { 18 Tags 19 { 20 "Queue"="Transparent" 21 "IgnoreProjector"="True" 22 "RenderType"="Transparent" 23 "PreviewType"="Plane" 24 "CanUseSpriteAtlas"="True" 25 } 26 27 Cull Off 28 Lighting Off 29 ZWrite Off 30 Blend DstColor Zero 31 32 Pass 33 { 34 CGPROGRAM 35 #pragma vertex SpriteVert 36 #pragma fragment frag 37 #pragma target 2.0 38 #pragma multi_compile_instancing 39 #pragma multi_compile _ PIXELSNAP_ON 40 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 41 #include "UnitySprites.cginc" 42 43 fixed4 frag(v2f IN) : SV_Target 44 { 45 fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color; 46 return fixed4((1.0 - c.a) + c.rgb * c.a, 1.0); 47 } 48 ENDCG 49 } 50 } 51}

また、「覆い焼き」は多分下記のような感じでいかがでしょうか?こちらはバーテックスシェーダーにも手を加えて複雑になってしまい、グラブパスも使っているので実行コストも少し上がってしまいました。「覆い焼き (リニア) - 加算」で表現上問題なければ、そちらの方がおすすめです...

ShaderLab

1// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt) 2 3Shader "Sprites/ColorDodge" 4{ 5 Properties 6 { 7 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 8 _Color ("Tint", Color) = (1,1,1,1) 9 [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 10 [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1) 11 [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1) 12 [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {} 13 [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0 14 } 15 16 SubShader 17 { 18 Tags 19 { 20 "Queue"="Transparent" 21 "IgnoreProjector"="True" 22 "RenderType"="Transparent" 23 "PreviewType"="Plane" 24 "CanUseSpriteAtlas"="True" 25 } 26 27 Cull Off 28 Lighting Off 29 ZWrite Off 30 Blend SrcAlpha OneMinusSrcAlpha 31 32 GrabPass{} 33 34 Pass 35 { 36 CGPROGRAM 37 #pragma vertex vert 38 #pragma fragment frag 39 #pragma target 2.0 40 #pragma multi_compile_instancing 41 #pragma multi_compile _ PIXELSNAP_ON 42 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 43 #include "UnitySprites.cginc" 44 45 struct v2fCustom 46 { 47 float4 vertex : SV_POSITION; 48 fixed4 color : COLOR; 49 float2 texcoord : TEXCOORD0; 50 UNITY_VERTEX_OUTPUT_STEREO 51 float4 grabcoord : TEXCOORD1; 52 }; 53 54 v2fCustom vert(appdata_t IN) 55 { 56 v2fCustom OUT; 57 58 UNITY_SETUP_INSTANCE_ID (IN); 59 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); 60 61 OUT.vertex = UnityFlipSprite(IN.vertex, _Flip); 62 OUT.vertex = UnityObjectToClipPos(OUT.vertex); 63 OUT.texcoord = IN.texcoord; 64 OUT.color = IN.color * _Color * _RendererColor; 65 66 #ifdef PIXELSNAP_ON 67 OUT.vertex = UnityPixelSnap (OUT.vertex); 68 #endif 69 70 OUT.grabcoord = ComputeGrabScreenPos(OUT.vertex); 71 72 return OUT; 73 } 74 75 sampler2D _GrabTexture; 76 77 fixed4 frag(v2fCustom IN) : SV_Target 78 { 79 fixed4 c = SampleSpriteTexture (IN.texcoord) * IN.color; 80 fixed3 d = tex2Dproj(_GrabTexture, IN.grabcoord).rgb; 81 return fixed4(d / (1.0 - c.rgb * c.a), c.a); 82 } 83 ENDCG 84 } 85 } 86}

投稿2018/12/11 22:43

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yrema

2018/12/11 22:51

回答有り難うございます。どうもハードルが高そうですね・・・。試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問