はじめに
今回は、Blender4.1で半透明が正しく表示されない理由と対処法を紹介します。

まず、この動作を確認するためにBlenderでの半透明の作り方から解説。
その後、原因 → 対処法(描画順の設定)という流れで解説していきます。
下準備:半透明の設定方法
Blenderを立ち上げ。
Shift+Aキー → メッシュ「UV球」などの適当なオプジェクトを作成。

右クリック → 「スムーズシェード」で見た目を滑らかにします。

そしたら、画面上部の「Shading」を選択。

画面下部のシェーダーエディターで「+新規」を押します。

アルファの値を0.32などに設定。
この数値が半透明度合いです。

これで半透明が表示… されないのがBlenderです。
半透明にするには「ブレンドモード」の設定が必要になります。

ブレンドモードの設定
シェーダーエディターの所にマウスを移動。
Nキーを押して右側の画面を表示。
オプション → 設定 → ブレンドモードを「アルファブレンド」に設定。

Blender4.3からはブレンドモードは「レンダーメゾット」の表記になったようです。
・ディザー → アルファハッシュに相当
・ブレンド → アルファブレンドに相当

これで、半透明が正しく表示されます。

これで終わりと思うかもしれませんが… もう1工程必要です。
現在、透過は正しく表示されてません。
その事が分かりやすいようにShift+Aキー → メッシュ → 「トーラス」を作成。
違いが分かりやすいようにトーラスを追加

3Dビューでトーラス形状を選択。
この状態でマテリアルプロパティを表示。

マテリアルマークから、既存の半透明設定を入れたマテリアルを表示。

そして、3Dビューを回してよく見てください。
表示が上手く行ってない事が分かります。


これは、この記事で解説したい『描画順』とは別文脈のエラーです。
なので、次の工程で手早くこちらを修正します。
このエラーを治すために、「裏面/背面の表示」を調整します。
裏面を表示/背面を表示を調整
シェーダーエディターを確認。
試しに「裏面を非表示」のチェックを有効化。

すると、綺麗な見た目の半透明が表示できます。

もしくは、背面を表示のチェックを解除。
(裏面を非表示は有効/無効どちらでも同じ挙動です)

これでも、半透明を綺麗に表示できます。

違いは半透明が重なった部分の描画です。
「裏面を非表示を有効化」+「背面を表示の有効化」の組み合わせだと…
1オプジェクト上で重なった部分まで綺麗に表示されます。

2オプジェクト間であれば、背面が非表示でも重なりは表示できます。

ただし、オプジェクト統合などをして1つにまとめると崩れます。

裏面を表示+背面を表示は裏面まで正しく見えます。

が… 細かな表示エラーが起こりやすいです。
特に、半透明に半透明のモノを重ねた時に崩れます。

↓のような挙動になります。

まとめると下記。
【裏面を表示/背面を表示による挙動の差】
・裏面を非表示/背面を非表示
→ 半透明で重なった部分は表示さない
→ しかし、半透明に半透明を重ねてもバグらない(◎)
・裏面を非表示/背面を表示
→ 表示バグが発生する、NGな組み合わせ(×)
・裏面を表示/背面を非表示
→ 半透明で重なった部分は表示さない
→ しかし、半透明に半透明を重ねてもバグらない(◎)
・裏面を表示/背面を表示
→ 半透明で重なった部分まで表示される
→ 半透明に半透明を重ねると、少しバグる(〇)
→ 条件によってはこれが一番いい結果になる事がある
なので、ここでの結論は下記。
・「背面を非表示」にするのが無難
・「裏面は表示」にして、は間違って背面を非表示にした際のエラー対策をする

実際の所は、時と場合によるなのですが…
それだと説明にならないので、このような文章を残しました。
以上が、裏面を表示/背面を表示を調整です。
これで、Blenderでの半透明設定が完了です。
そしたら、本題の描画順エラーに進みます。
半透明バグの原因
半透明がバグる理由は「描画順の問題」です。
まず、3DCGの不透明オプジェクトについて考えます。
3DCGの不透明のモノは、前から順に描かれます。
そして、重なって見えない部分は描画が省略されます。(Zバッファ法の影響)

そして不透明のモデルであれば、描画順が前後しても形の崩れは発生しません。
重なった部分が無駄になりますが…
前後関係を見て、手前の所は上から描くという調整が入ります。


なので、あなたはこれまで描画順を気にしなくても
不透明オプジェクトなら、正しい形で表現できてました。
具体的に言うと下記の2つのアプローチを組み合わせて使ってます。
・手前で隠れてる所を書かない
・奥にある、手間のモデルで隠れた所を消す
↓絵で描くと、このような形になります。

そしたら、次は半透明オプジェクトの事を考えてきます。
不透明は前から順に描かれ、重なって見えない部分は描画が省略される事を紹介しました。

では、半透明のモノも同じ要領で「手前 → 後ろ」の順に描いた場合はどうなるでしょうか…?
正解は、裏側の描画が省略された部分が透けて見えるです。

これが、半透明のモノ越しで3Dモデルを見ると一部画消える不具合の発生原因です。

また、ソフトの設定によっては奥のモデルの描画が貫通することもあります。
(Unityでデータ的に半透明なモノを2つ重ねた時の挙動(Render Queue2501以上))


UnityのRender Queue「2501」以上の設定は…
裏面の描画省略を行わないようです。
なので「手前 → 後ろ」の順で描くと…
そのまま、後ろのオプジェクトが描画されて手前の描画を貫通します。
いずれにせよ、半透明バグの原因は…・
半透明オプジェクトの描画順が「前 → 後ろ」になったことです。
↓詳細はこちらにまとめてます。
以上が、半透明バグの原因です。
半透明バグの対処法
半透明のバクの原因は描画順です。
半透明のモノが「前 → 後ろ」の順で描かると、奥の省略された部分が見てしまいます。

では、どうすればいいか。
それは、半透明部分だけ「後ろ → 前」の順に描くと解決します。

つまり…
半透明バグの対処法は、この描画順を設定する事になります。
そう、半透明の部分だけ「後ろ → 前」の順になるよう設定すれば解決します。

そして、この設定を行うためにBlender描画順は何処で決まるのか?
を知る必要が出てきます。

この描画順が決まるポイントが分かれば、あとはそれを正しく設定するだけです。

以上が、半透明バグの対処法です。
Blenderの描画順が決まるポイント
BlenderにはUnityのRender Queueような描画順を数値設定できる機能はありません。
ですが、下記の要素で描画順が決まってます。
【オプジェクトが分かれてる場合】
・ブレンドモード設定
・原点位置
・Collectionの順
・オプジェクトが生まれた順
ーーーーー
【オプジェクトが同じ場合】
・マテリアルスロットの順番
・視点から近い面(Zバッファ法と同じ挙動)
こちらについて解説していきます。
ブレンドモードの設定
Blenderの半透明は「アルファブレンド」という設定で表示されます。
このモード自体に描画順があります。
試しに、2つのアルファブレンドを並べて見ました。

すると、2つのアルファブレンドはZバッファ法と同じ要領で「前 → 後ろ」の順に描かれます。
これは、正しくない順番なので表示エラーが発生します。(②の描画が欠損)

このように、半透明越しで見たオプジェクトの描画が消えます。

では、手前を「アルファブレンド」に設定。
奥を「不透明」もしくは「アルファクリップ」に設定。
すると… 正しく表示されます。

つまり、ブレンドモードには描画順を決める要素があります。
【ブレンドモードでの描画順決定】
・不透明 or アルファクリップを先に描く
・アルファブレンドはその後で描く
(描画範囲はZバッファ法で削られる)

先に描いた不透明 + アルファクリップが、アルファブレンドの描画範囲を削ります。
なので、手前に不透明がある場合は半透明を後で描いても正しい形で見えます。

仕組みはコレと同じです。
↓の2の削れた領域を半透明として、上から描画してます。

そして、このブレンドモードの設定が最も効果が強い描画順決定です。
なので、一番の対策は半透明エラー対策は「アルファブレンド」に「アルファブレンド」を重ねないになります。


基本的に、このルールを守っていれば半透明エラーは起きません。
ですが、どうしても「アルファブレンド」に「アルファブレンド」を重ねる場面は出てきます。
なので、次以降はアルファブレンドが重なった時の描画順の決定方法を見ていきます。

別オプジェクトなら原点位置
アルファブレンドが2つ重なった場合、描画順を決めるのは “原点位置”です。

これはオプジェクトモードで、オプジェクトを動かすと操作できます。
(Gキーで移動)

原点の詳細はこちらで解説してます。
この原点を試しに「水色が手前」で「白色が後ろ」という物理的に正しい形に置いてみました。

すると… 正しい形で描画されます。
つまり、2つのアルファブレンドオプジェクトが重なった場合は…
視点から原点までの距離が遠い順に描画されます。


普通に考えると、原点が近い方が先ですが…
ここは透過の仕組みを分かった上で、
Blender制作者側の配慮が入って近い方が後という挙動になったと考えられます。
今度は「水色が後ろ」で「白色が手前」という物理的に正しくない形に置いてみました。

すると… 描画順が変わり、半透明の表示エラーが発生します。

ちなみに、この状態で奥の白い箱のブレンドモードを「不透明 or アルファクリップ」に設定。
すると… 正しく表示されます。

つまり、描画順決定の優先度は…
「ブレンドモード」 >「原点位置」になります。
原点位置が同じ場合は「Collection」の順
では、次は2つのアルファクリップオプジェクトの原点位置が完全に同じ場合を見ます。
これは「Collection」の並び順で決まります。

Blenderの右上にある、アウトライナーのココの話です。

今、とある事情で正しく表示されてない半透明があります。
(Collectionが同じ場合の順位決定は後で解説します)

この状態でアウトライナーを操作。
水色をCollectionの外に出すようにドラッグ&ドロップ。

もしくは右クリックでコレクション作成。
それぞれのコレクションにオプジェクトを分けて入れて、ドラッグ&ドロップで操作。

すると… 正しく表示されます。

つまり、このCollectionの並び順で描画順が変わります。
Collectionは上から下の順に描画されます。

あと、Collectionの順番が逆でも原点位置を動かせば正しい表示になります。
つまり、描画順決定の優先度は…
「ブレンドモード」 >「原点位置」 > 「Collectionの順」です。

あと、同一Collection内、もしくはCollectionが無い場合は…
アウトライナーの並び順では変わらないので注意。


オプジェクトだけの場合、並び順は「名前」で変わります。
…が、コレは描画順に影響を与えません。
では「Collection」が同じ場合は… 何処で描画順が決まるのか?
それは “オプジェクト” が生まれた順です。
「Collection」も同じならオプジェクトが生まれた順
Blenderはオプジェクトが生まれた順を記録しているようです。
たとえば…
・Shift+Aキーで作成 → 1番目に生まれたオプジェクト
・作成した立方体をCtrl+Dキー複製 → 2番目に生まれたオプジェクト
…といった具合に、この生まれた順番を見えない場所に記録しているようです。


色々試してみましたが…
この生まれ順に対応する設定項目は無さそうでした。
なので、私たちが操作できない見えない場所。
メモリーの中に、この番号の刻印があると思います。
これを証明するために、1番目に作ったオプジェクトを選択。
Ctrl+Dキーで複製し「3番目に生まれたオプジェクト」にします。
この状態で、編集モードで原点位置を変えないように移動。

すると、複製した立方体は正しい形で表示されます。
こうなった理由は、生まれ順によって決まった描画順の関係です。
① → ②は間違った「前 → 後ろ」の描画順で、②の描画が欠損しましたが…
② → ➂の時だけ正しく「後ろ → 前」の描画になったので正しく見えます。

では、この生まれ順はどうやったら調整できるか。
1つ例は下記。
【オプジェクトの生まれ順の調整方法】
① → 2つ以上のオプジェクトを「Ctrl+J」で統合
② → 点前のオプジェクトを、編集モードでリンク選択
➂ → 「P」キーで分離
④ → 分離した方が、後で生まれたオプジェクトになる
(ただし、統合した結果マテリアルスロッドに余計な情報が入るので注意)
この方法で生まれ順を調整できます。

ただし、1度2つ以上のマテリアルを統合すると…
マテリアルスロッドに、2つのマテリアルが記録されます。
→ 余計なマテリアルが増えます。

ただ、この方法を使うと「生まれた順」を操作できて、正しい描画順を設定できます。

実際に動かした時の様子はこちら。
この操作だけで、描画順が変わったことが確認できます。

あとは、余計なマテリアルを増やしたくない場合は…
下記の方法でも生まれ順を操作できます。
【オプジェクトの生まれ順の調整方法 - ②】
① → 描画順が正しくないオプジェクトを選択
② → ①をCtrl+Dキーで複製 → Hキーで非表示
➂ → 元の①オプジェクトをXキーで削除。
④ → Alt+Hキーで②で作ったオプジェクトを表示する
↓ようするに、下図の「1番目」を消す方法です。

あと、生まれ順が逆でも、Collectionの順を変えれば、描画順が変わります。

つまり、描画順決定の優先度は…
「ブレンドモード」 >「原点位置」 > 「Collectionの順」 > 「生まれた順」です。

生まれた順は同一にはならないので…
分離したオプジェクトでの描画順設定の解説はこれで完了です。
同じオプジェクトならマテリアルスロット
次は、オプジェクトが同じ形状の場合を考えます。
オプジェクトが同じ場合、基本はZバッファ要領で視点から近い方が先に描かれます。
なので、↓の図のような重なったモノの裏側は消えます。

手前が強い半透明メッシュ、奥が弱い半透明メッシュなので…
点前の描画が奥の描画を消してるような、表示エラーが発生します。

ちなみに、消え方はZバッファと同じ挙動のようです。
下gifのように、交差したモデルは視点からの距離を見て、手前の面から描画されていきます。

↓キャラの顔で、ほほの赤みパーツで消えるのはこれが原因です。
(実務だと、この現象がよく発生して問題になります)

では、これはどうすることもできないのか?
いいえ、1つ対処法があります。
それは、「マテリアルスロッド」による描画順決定です。

マテリアルプロパティの「+」ボタンで、マテリアルスロッドを増やせます。

そして、任意のマテリアルを設定。
編集モードで、マテリアルを割当てたい部分を選択。
「割り当てを」実行。

そして「後ろ → 手前」の順になるよう、マテリアルスロットを並び替えます。

マテリアルスロッドは「▲」と「▼」で並び順を変えれます。

白 → 水色の順に並べることで、
同一オプジェクトの半透明を正しく描画できます。

今度はわざとエラーを出すように「水色」 → 「白」の順で並べました。
すると… 半透明部分の描画順が「手前 → 後ろ」の順になるので表示エラーが発生します。

先ほどの球も、同じ要領でマテリアルスロッドを調整すれば治せます。

↓のようなに、1オプジェクト綺麗に半透明に半透明を重ねた様子を表現できます。

実践:キャラのほほの赤み奥が消える原因と対処法
最後に、透過問題解決の実践編として、ほほの赤みで顔が消えた時の解決事例を紹介して締めます。

キャラクターのほほの赤みを表示すると、顔が消えことがあります。
この原因も半透明の透過順問題です。

何も設定して無ければ「ほほの赤み(前) → 顔(後ろ)」の順に描かれます。
そして、ほほの赤みの面で裏側の「顔」部分が消されるので背景が透過します。

↓と同じ現象が起こってます。
(水色の立方体をほほの赤みだと思ってください)

ではどうすればいいか。
それは、Blenderならマテリアルスロッド追加。
2つ目のスロッドに同じマテリアルを割当てて、ほほの赤みだけ別マテリアルにする事です。

これで、ほほの赤みを正しく表示できます。

ただ、半透明のメッシュは処理が重く、動作が不安定なので…
理想は顔のマテリアルを複製。
ほほの赤み(アルファブレンド)とそれ以外(不透明)のように設定を分ける事をおすすめします。


「不透明」と「アルファブレンド(半透明)」には絶対的な描画順の指定があるので…
この2つをきちんと設定すれば、ほとんどの場合で表示エラーが発生しなくなります。
マテリアルの複製は、任意のマテリアルを2スロッド目に挿入。
その後、マテリアルの名前横の数字をクリックで複製できます。

画像のフチが目立つ場合の対処法
このような透過テクスチャを用意。(別件で作ったイラストの一部です)

下図のように設定すると、画像の透過情報を読み込ませれます。

…が、フチが目立ちます。

こちらは画像の方のアルファを「プリマルチプライ」にすると治ります。

このようにフチが目立たなくなりました。

ただ、この設定は別の場所だと上手くいかなくなります…
半透明系の所で大きく崩れます。

こちらの対処法としてできることは…2マテリアル作成。
そして、2画像読み込み(同一画像のコピー)してアルファの設定を変える。
この2つの割り当て方を変えるぐらいです。


同じ画像だとテクスチャの「アルファ」設定が共通してしまうようで…
うまく2つのアルファ設定を用意できませんでした。
もうちょっと何とかしてほしい、Blenderの半透明問題…。
おまけ:アルファクリップを使うという解決策
透過素材を扱う上で「アルファクリップ」という処理があります。
これは“透過”できますが “半透明” には使えません。

半透明には使えないので “おまけ” として解説します。
アルファクリップは透明な部分をぶつ切りで消す処理です。
↓の黒い所が透明部分です。

これに、アルファクリップを使うと…
綺麗に切り抜けます。
そして、最大の特徴が、これまで紹介した「半透明エラー」が発生しません。
描画順を気にせず、透過素材を設定できます。

この方法は、アルファクリップは半透明を表現できないという弱点があります。
↓試しに下図の様な半透明の素材を用意。

そしてアルファクリップを設定。
すると「しきい値」で、どこからを透過、どこから表示という事は調整できます。
が… 半透明部分は下図のように、ぶつ切りになります。

半透明は表現できませんが… 描画順によるエラーが出ないのが最大の魅力。
なので、透明/不透明がぶつ切りで良いなら「アルファクリップ」を使う。
半透明の表現を使うなら「アルファブレンド」を使うのがおすすめ。

あと、処理的な事を言えば…
「アルファブレンド」より「アルファクリップ」の方が高負荷です。
が、半透明の描画順エラーが出ない事のメリットが大きいので…
普通に使って良いと思います。
(使いすぎ注意、透過が無いなら不透明に設定するのが一番軽量です)
あと、Unityで使えるlilToonシェーダーでは下記のような表記になってます。
・アルファクリップ → カットアウト
・アルファブレンド → 半透明
このような表記の違いはありますが…
基本的な中の構造や仕組みは同じです。
以上が、半透明表現がバグりやすい理由と対処法です。
まとめ
今回は、Blender4.1で半透明が正しく表示されない理由と対処法を紹介しました。
・ブレンドモードを「アルファブレンド」にすると半透明を表示できる
・Blenderの半透明は「背面を非表示」に設定すると、高確率で綺麗に出る
・その上で、半透明に半透明の面を重ねると表示エラーが起こる
・半透明を重ねた時の表示エラーの原因は「描画順」
・半透明を描く場合、描画順を「後ろ → 前」に設定する必要がある
・描画順の変更は、原点位置、Collectionの順、オプジェクトが生まれた順、マテリアルスロットなどで行える
また、他にも3DCGについて解説してます。
ぜひ、こちらもご覧ください。
コメント
はじめまして。質問させて頂きたくコメント失礼いたします。
>下gifのように、交差したモデルは視点からの距離を見て、手前の面から描画されていきます。
のgifについて、こちらを正しく表示する方法はありますでしょうか?
2枚の板が交互にあるためマテリアルスロットの順序で解決できなさそうだなと…
お手すきでお返事いただけますと幸いです。
基本的には無いですね… 真ん中にループカットを入れてマテリアルを分けたり、厚みを作って裏と表でマテリアルを分けたり、テクスチャに透過っぽく見えるように色を入れたり、Cyclesレンダー使ったり、独自のプログラム組んだりみたいな力業の選択肢になると思います。
一番はこのような形を作らない事だと思います。
ただ透けるだけでいいのにと思いつつ仕組みを知らないと躓いてしまいますね。
ありがとうございました。
3DCGの透過は結構落とし穴ですよね。 よほどのことが無い限りメッシュでモデリングしたり、テクスチャに下地の色を混ぜて疑似的に透過させるのが良いと思います。