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

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

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

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

Unity

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

Q&A

解決済

1回答

2612閲覧

CG,Unity:webm動画をChromaKeyshaderで透明背景にしたい

zenobread

総合スコア44

Unity3D

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

Unity

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

0グッド

0クリップ

投稿2020/02/15 13:59

編集2020/02/16 01:18

やりたいこと

webm形式の動画で黒背景部分を透明化させたい

###問題点
Unityでクロマキーシェーダーを作ってみた(凹)
此方の方のクロマキーシェーダーを適用させると、背景が透明になるものの全体の色が黒基調になる


イメージ説明
(元の動画)

イメージ説明
(クロマキー適用後)

なぜかすごくちらつきがあるのと、元のカラフルな色合いが真っ黒になってしまうのでそちらを修正したいです

追記 materialとshaderの設定のスクショ

material
イメージ説明

ChromaKey_Standard_Transparent(テクスチャにつけているshader)

shader

1Shader "ChromaKey/Standard/Transparent" 2{ 3 4Properties 5{ 6 [Header(Material)] 7 _Color ("Color", Color) = (1, 1, 1, 1) 8 _MainTex ("Albedo (RGB)", 2D) = "white" {} 9 _Glossiness ("Smoothness", Range(0, 1)) = 0.5 10 _Metallic ("Metallic", Range(0, 1)) = 0.0 11 [Enum(UnityEngine.Rendering.CullMode)] _Cull("Culling", Int) = 2 12 13 [Header(Chroma Key)] 14 _ChromaKeyColor("Color", Color) = (0.0, 0.0, 1.0, 0.0) 15 _ChromaKeyHueRange("Hue Range", Range(0, 1)) = 0.1 16 _ChromaKeySaturationRange("Saturation Range", Range(0, 1)) = 0.5 17 _ChromaKeyBrightnessRange("Brightness Range", Range(0, 1)) = 0.5 18} 19 20SubShader 21{ 22 Tags 23 { 24 "Queue" = "Transparent" 25 "RenderType" = "Transparent" 26 "IgnoreProjector" = "True" 27 "PreviewType" = "Plane" 28 } 29 30 Cull [_Cull] 31 32 CGPROGRAM 33 #pragma surface surf Standard alpha:blend addshadow fullforwardshadows 34 #pragma target 3.0 35 #define CHROMA_KEY_ALPHA 36 #include "./ChromaKey_Standard.cginc" 37 ENDCG 38 39 Pass 40 { 41 Tags { "LightMode" = "ShadowCaster" } 42 ZWrite On 43 ZTest LEqual 44 Cull Off 45 46 CGPROGRAM 47 #include "./Chromakey_Shadow.cginc" 48 #pragma vertex vert 49 #pragma fragment frag 50 #pragma multi_compilecaster 51 ENDCG 52 } 53} 54 55FallBack "Diffuse" 56 57}

ChromaKey_Standard(ChromaKey_Standard_TransParentで使われているcgincファイル)

cginc

1#ifndef CHROMA_KEY_STANDARD_CGINC 2#define CHROMA_KEY_STANDARD_CGINC 3 4#include "UnityCG.cginc" 5#include "./ChromaKey.cginc" 6 7sampler2D _MainTex; 8 9struct Input 10{ 11 float2 uv_MainTex; 12}; 13 14half _Glossiness; 15half _Metallic; 16fixed4 _Color; 17 18void surf(Input IN, inout SurfaceOutputStandard o) 19{ 20 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 21#ifdef CHROMA_KEY_ALPHA 22 ChromaKeyApplyAlpha(c); 23#else 24 ChromaKeyApplyCutout(c); 25#endif 26 o.Albedo = c.rgb; 27 o.Metallic = _Metallic; 28 o.Smoothness = _Glossiness; 29 o.Alpha = c.a; 30} 31 32#endif

ChromaKey.cginc(ChromaKey_Standardで使われているcgincファイル)

cginc

1#ifndef CHROMA_KEY_COMMON_CGINC 2#define CHROMA_KEY_COMMON_CGINC 3 4// Refer to the following website regarding conversions between RGB and HSV: 5// https://www.laurivan.com/rgb-to-hsv-to-rgb-for-shaders/ 6 7float4 _ChromaKeyColor; 8float _ChromaKeyHueRange; 9float _ChromaKeySaturationRange; 10float _ChromaKeyBrightnessRange; 11 12inline float3 ChromaKeyRGB2HSV(float3 rgb) 13{ 14 float4 k = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); 15 float4 p = lerp(float4(rgb.bg, k.wz), float4(rgb.gb, k.xy), step(rgb.b, rgb.g)); 16 float4 q = lerp(float4(p.xyw, rgb.r), float4(rgb.r, p.yzx), step(p.x, rgb.r)); 17 float d = q.x - min(q.w, q.y); 18 float e = 1e-10; 19 return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); 20} 21 22inline float3 ChromaKeyHSV2RGB(float3 hsv) 23{ 24 float4 k = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); 25 float3 p = abs(frac(hsv.xxx + k.xyz) * 6.0 - k.www); 26 return hsv.z * lerp(k.xxx, clamp(p - k.xxx, 0.0, 1.0), hsv.y); 27} 28 29inline float3 ChromaKeyCalcDiffrence(float4 col) 30{ 31 float3 hsv = ChromaKeyRGB2HSV(col); 32 float3 key = ChromaKeyRGB2HSV(_ChromaKeyColor); 33 return abs(hsv - key); 34} 35 36inline float3 ChromaKeyGetRange() 37{ 38 return float3(_ChromaKeyHueRange, _ChromaKeySaturationRange, _ChromaKeyBrightnessRange); 39} 40 41inline void ChromaKeyApplyCutout(float4 col) 42{ 43 float3 d = ChromaKeyCalcDiffrence(col); 44 if (all(step(0.0, ChromaKeyGetRange() - d))) discard; 45} 46 47inline void ChromaKeyApplyAlpha(inout float4 col) 48{ 49 float3 d = ChromaKeyCalcDiffrence(col); 50 if (all(step(0.0, ChromaKeyGetRange() - d))) discard; 51 col.a *= saturate(length(d / ChromaKeyGetRange()) - 1.0); 52} 53 54#endif

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

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

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

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

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

Bongo

2020/02/15 16:51

マテリアルの設定はどうなっているでしょうか? インスペクターのスクリーンショットをご提示いただけると手がかりになるかもしれません。
zenobread

2020/02/16 01:12

ご質問ありがとうございます。マテリアルのインスペクターと、shaderのソースコードを載せますのでご覧ください。
guest

回答1

0

ベストアンサー

真っ黒になってしまう原因としては、光の向きが不適切である可能性が挙げられそうです。
マテリアルのシェーダーにChromaKey/Standard/Transparentを使用されているようですが、これはライトの影響を受けるタイプのはずですので、もしライトが裏面から当たっていたとすると暗くなってしまうということもありそうな気がします。
光の向きに依存せず本来の色で描画させたい場合、シェーダーをChromaKey/Unlit/Transparentに切り替えてみてはいかがでしょうか。

ちらつきについては、マテリアルのパラメーター調整で何とかなるかもしれません。
今回抜きたい色は黒ですが、スクリーンショットを拝見しますと「Hue Range」が0.193と小さく設定されています。黒は無彩色で色相を持たないはずですので、許容するピクセルの色はどの色相に対しても均等であるべき...つまり「Hue Range」を1にしてしまうのがいいんじゃないでしょうか。
そして暗い色では彩度の精度も悪くなりますので、彩度による色判定も不正確になると思われます。この際「Saturation Range」も1にしてしまって、「Brightness Range」の調整だけで色判定するのがいいかもしれません。

投稿2020/02/16 02:08

Bongo

総合スコア10807

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

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

zenobread

2020/02/16 02:34

ご回答ありがとうございます。 仰ったとおり調整するとうまくいきました!本当にありがとうございます。 ベストアンサーに選択させていただきたいのですが、その前にもういくつか質問させてください。 私はHueRangeやSaturationRangeがどんな役割があるのかも全く分かりませんでした。後学のためにどのように勉強されて今回のご回答をすることが出来たのか、よろしければ使われたサイトや本をお教えください。
Bongo

2020/02/16 03:39

色相・彩度・明度による色指定はけっこういろんな分野で登場するかと思いますので、どのような本やサイトがいいのか挙げるのは難しいところです。「HSV色空間 - Wikipedia」(https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93 )だと「グラフィックデザイナーはRGBやCMYKのようなモデルよりHSVカラーモデルを用いることを好むことがある」などと書かれていますので、グラフィックデザイン関連の書籍でしょうかね? Unityのインスペクター上で色を設定するとき、色ボックスをクリックするとカラーピッカーが現れるかと思います。 ここに「RGB 0-255」とか「RGB 0-1.0」と表示されているプルダウンメニューがあるはずですが、これを「HSV」に切り替えると色相・彩度・明度による色選択ができます。これらのスライダーを操作するとカラーピッカーの上半分に図示されている現在の色の位置も移動しますので、色相・彩度・明度の値が色にどのような影響を及ぼすかが掴みやすいんじゃないでしょうか。 カラーピッカーでは色相が0~360、彩度と明度が0~100で設定するような作りになっていますが、凹みTipsさんのシェーダーではこれらを0.0~1.0の範囲として扱い、「~Range」のパラメーターでそれらの許容幅を設定するようになっているようです。たとえば「Hue Range」が0.1なら「Color」にセットした色に対して色相が±36°なら同じ色と判定され、同じく彩度・明度も許容範囲内に入っていれば色抜き対象にする感じですね。 ただし、コードをざっと見た感じ、凹みTipsさんのコードは色相が360°で一周することを考慮していない様子ですのでちょっと注意が必要かもしれません。たとえば色相350°(かなり赤っぽい紫)と色相10°(かなり赤っぽいオレンジ)は色相差20°でけっこう近い色のはずですが、このシェーダーだとかなり離れた色と判定されて色抜きされない可能性があります。
zenobread

2020/02/16 05:41

コメントありがとうございます。未熟なためおっしゃったことがなんとなくのレベルでしかまだわかりませんが、今回の件だと、色相と彩度が同じであるかどうか(HueRangeとSaturationRange)の許容範囲を最大にして、明度の違いで透明化させた、ということでよろしいでしょうか?
Bongo

2020/02/16 06:18

そうですね。「Color」で指定した色とピクセルの色の色相や彩度がどれだけずれていても無視して、明度だけで色判定を行うことになります。 先のコメントで申し上げたUnityのカラーピッカーだと、上半分のHSB図は虹色のリングとグラデーションのかかった正方形で表現されています。黒色は正方形部分の下の辺に位置しており、Hueをいくら回転させても、あるいはSaturationを左右にどれだけ動かしても、やはり黒色は黒色であって変化がないわけです。黒色の場合は色を区別するのに色相や彩度があてになりませんので、正方形の縦軸...つまり明度だけを使って黒さを区別しようというわけですね。
zenobread

2020/02/16 08:43

ありがとうございます。まだまだ理解が足りないとは思いますが、ある程度は達したと思います。長い間お付き合いいただきありがとうございました。
zenobread

2020/02/17 08:18

Bongoさん大変申し訳ございません。この質問の関連で新しく発生した此方の質問にもお答え願えますでしょうか。ご迷惑かと思いますがどうぞよろしくお願いします。https://teratail.com/questions/241646
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問