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

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

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

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

1808閲覧

[Unity]sprite shape controllerでの、半透明の重なりを無くすマテリアルを作りたい

kurokurota

総合スコア1

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

1グッド

0クリップ

投稿2022/12/10 19:45

編集2022/12/10 19:49

実現したいこと・発生している問題

UnityのSprite Shape Controllerを使って、半透明のグラデーション画像で様々な形状を作ろうとしています。

ですが、下の画像の中央ノード部分のように、半透明が重なることでグラデーションが崩れてしまいます。
この半透明の重なりを消し、きれいなグラデーションを実現したいです。
イメージ説明

試したこと

・「2度塗り防止」のシェーダ(URLの回答の「案1」)を使ってみたが、下の画像のように、不自然な線が見えてしまう。
https://teratail.com/questions/217117
イメージ説明

・spriteを真っ黒な画像に変更し、縁をぼかすシェーダ(URLのもの)を使ってみたが、現状と同様に半透明が重なって線が出てしまう。
https://qiita.com/T_Tao/items/1005fe02490c552f7a54

kurokurota👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

Sprite Shape Rendererの「Edge Material」を、下記のようなシェーダーを使ったマテリアルにするというのはどうでしょうか。

ShaderLab

1Shader "Sprites/MinTransparency" 2{ 3 Properties 4 { 5 [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} 6 _Color ("Tint", Color) = (1,1,1,1) 7 [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 8 [HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1) 9 [HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1) 10 [PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {} 11 [PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0 12 } 13 14 SubShader 15 { 16 Tags 17 { 18 "Queue"="Transparent" 19 "IgnoreProjector"="True" 20 "RenderType"="Transparent" 21 "PreviewType"="Plane" 22 "CanUseSpriteAtlas"="True" 23 } 24 25 Cull Off 26 Lighting Off 27 ZWrite Off 28 29 // スプライト描画前の映像をキャプチャーしておく 30 GrabPass {} 31 32 // まずスプライト図形内をRGBAすべて白色で塗りつぶしておく 33 Pass 34 { 35 Blend One Zero 36 37 CGPROGRAM 38 #pragma vertex SpriteVert 39 #pragma fragment frag 40 #pragma target 2.0 41 #pragma multi_compile_instancing 42 #pragma multi_compile_local _ PIXELSNAP_ON 43 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 44 #include "UnitySprites.cginc" 45 fixed4 frag(v2f IN) : SV_Target 46 { 47 return 1.0; 48 } 49 ENDCG 50 } 51 52 // ここにスプライトを重ね描きするが、重なったときは値が小さい方を採用する 53 Pass 54 { 55 Blend One One 56 BlendOp Min 57 58 CGPROGRAM 59 #pragma vertex SpriteVert 60 #pragma fragment frag 61 #pragma target 2.0 62 #pragma multi_compile_instancing 63 #pragma multi_compile_local _ PIXELSNAP_ON 64 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 65 #include "UnitySprites.cginc" 66 fixed4 frag(v2f IN) : SV_Target 67 { 68 return SampleSpriteTexture(IN.texcoord) * IN.color; 69 } 70 ENDCG 71 } 72 73 // 最初に保存しておいたスプライト描画前の映像を重ねることで透明にする 74 // 通常のアルファブレンディングとは逆に、描画先の映像が描画元の映像に重ね合わさるような形にする 75 Pass 76 { 77 Blend OneMinusDstAlpha DstAlpha, OneMinusDstAlpha One 78 79 CGPROGRAM 80 #pragma vertex vert 81 #pragma fragment frag 82 #pragma target 2.0 83 #pragma multi_compile_instancing 84 #pragma multi_compile_local _ PIXELSNAP_ON 85 #pragma multi_compile _ ETC1_EXTERNAL_ALPHA 86 #include "UnitySprites.cginc" 87 struct v2fGrab 88 { 89 float4 vertex : SV_POSITION; 90 fixed4 color : COLOR; 91 float2 texcoord : TEXCOORD0; 92 float4 grabCoord : TEXCOORD1; 93 UNITY_VERTEX_OUTPUT_STEREO 94 }; 95 v2fGrab vert(appdata_t IN) 96 { 97 v2fGrab OUT; 98 UNITY_SETUP_INSTANCE_ID (IN); 99 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT); 100 OUT.vertex = UnityFlipSprite(IN.vertex, _Flip); 101 OUT.vertex = UnityObjectToClipPos(OUT.vertex); 102 OUT.texcoord = IN.texcoord; 103 OUT.color = IN.color * _Color * _RendererColor; 104 OUT.grabCoord = ComputeGrabScreenPos(OUT.vertex); 105 #ifdef PIXELSNAP_ON 106 OUT.vertex = UnityPixelSnap(OUT.vertex); 107 #endif 108 return OUT; 109 } 110 sampler2D _GrabTexture; 111 fixed4 frag(v2fGrab IN) : SV_Target 112 { 113 return tex2Dproj(_GrabTexture, IN.grabCoord); 114 } 115 ENDCG 116 } 117 } 118}

通常のSprites-Defaultだと下図のように見えるところ...

図1

MinTransparencyの場合は下図のようになりました。

図2

ただし、この方法はご質問者さんがご提示いただいた図のような「スプラインに近い部分ほど透明な単色グラデーション」みたいな形にしか通用しないだろうと思います。また、レンダリングパスもグラブパスを含めて合計4回もありますので、ちょっと非効率的かもしれません。
他には「なるべく皺が生じないようなメッシュを生成するSpriteShapeGeometryCreatorを作る」という手もありそうです。MinTransparencyのやり方だと不十分でしたら、まだ構想段階ではありますがこっちの方面での対処法も検討してみようかと思います。

投稿2022/12/12 22:33

Bongo

総合スコア10807

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

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

kurokurota

2022/12/21 12:04

迅速な回答ありがとうございました…! 2度塗りの際、アルファ値の小さいほうを採用するという手段は思いついたものの、自分の力では実装できずイチからシェーダの勉強をしているところでした。勉強させていただきます! SpriteShapeGeometryCreatorも知らなかったので調べてみようと思います。本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問