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

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

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

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

Unity

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

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

Q&A

解決済

1回答

1974閲覧

Unity3Dで描画順を設定できるSpriteをSkyboxより手前に表示したい

bh_evan

総合スコア18

Unity3D

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

Unity

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

HLSL

HLSLは、米マイクロソフト社によって開発された Direct3D APIで使われるプロプライエタリなシェーディング言語です。

0グッド

0クリップ

投稿2022/03/21 19:03

編集2022/03/21 19:19

前提

Unityで3D空間に設置したSpriteが、Skyboxと重なった時に表示されなくなります。(Skyboxが表示される)

キャラクターとして表示しているSpriteで、同じマテリアルを持つオブジェクトを複数重ねて配置しています。
そのため、パーツ毎に表示順を設定する必要があります。

実現したいこと

  • 3D空間に配置されたSpriteが
  • 他オブジェクトの影や光の影響を受け
  • 同一のシェーダーを持った他Spriteとの表示順を設定でき
  • Skyboxと干渉しない

という状況を作りたいです。

発生している問題

ZwriteをOffにすることでOrder in Layerから表示順を設定していましたが、ClearFlagがSkyboxになった際に題目の問題が発生しました。

該当のソースコード

Spriteのシェーダーは以下です。

HLSL

1Shader "Custom/Character" 2{ 3 Properties{ 4 _Cutoff("Cutoff", Range(0,1)) = 0.5 5 _Color("Color", Color) = (1,1,1,1) 6 _MainTex("Albedo (RGB)", 2D) = "white" {} 7 _Glossiness("Smoothness", Range(0,1)) = 0.5 8 _Metallic("Metallic", Range(0,1)) = 0.0 9 } 10 11 SubShader{ 12 Tags { "Queue" = "AlphaTest" "RenderType" = "TransparentCutout" } 13 LOD 200 14 Cull Off 15 ZWrite Off 16 17 CGPROGRAM 18 #pragma surface surf Standard alphatest:_Cutoff addshadow fullforwardshadows 19 #pragma target 3.0 20 21 sampler2D _MainTex; 22 23 struct Input 24 { 25 float2 uv_MainTex; 26 }; 27 28 half _Glossiness; 29 half _Metallic; 30 fixed4 _Color; 31 32 void surf(Input IN, inout SurfaceOutputStandard o) 33 { 34 fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 35 o.Albedo = c.rgb; 36 o.Metallic = _Metallic; 37 o.Smoothness = _Glossiness; 38 o.Alpha = c.a; 39 } 40 ENDCG 41 } 42 FallBack "Diffuse" 43}

正確には裏面の陰影を表示するため、以下のコードも含まれています。

HLSL

1Cull Front 2 3CGPROGRAM 4 5#pragma surface surf Standard alphatest:_Cutoff fullforwardshadows vertex:vert 6#pragma target 3.0 7 8sampler2D _MainTex; 9 10struct Input 11{ 12 float2 uv_MainTex; 13}; 14 15void vert(inout appdata_full v) 16{ 17 v.normal.xyz = v.normal * -1; 18} 19 20half _Glossiness; 21half _Metallic; 22fixed4 _Color; 23 24void surf(Input IN, inout SurfaceOutputStandard o) 25{ 26 fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; 27 o.Albedo = c.rgb; 28 o.Metallic = _Metallic; 29 o.Smoothness = _Glossiness; 30 o.Alpha = c.a; 31} 32ENDCG

試したこと

ZwriteをOnにすることで回避できますが、表示順が距離依存になってしまうので、この方法だと正確な描写は難しいと判断しました。

SpriteのRender QueueをSkyboxより上げる(2501以上)にすることでも問題を回避できますが、この場合だとSpriteに落ちる影が描写されなくなってしまいます。

Problem with ZWrite and sorting objects - Unity Forum

上記のページも参考にしましたが、シェーダーの知識が足りず、解決には至りませんでした。

補足情報(FW/ツールのバージョンなど)

Unity 2021.2.8f1

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

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

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

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

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

guest

回答1

1

ベストアンサー

おっしゃる通り、ZWrite Onだと同一平面上の部位の重なりが不確定になり...

図1

ZWrite Offだとオーダーに従った重なりになるものの、スカイボックスによる上書きが発生してしまいますね。

図2

一案として、シェーダーはZWrite Offとし、カメラを以前別の方の「Unityのシェーダーで、透明部分が黒く表示されてしまう。」とのご質問に対して申し上げたのと同様の二段構えにしてしまうのはどうでしょうか。

図3

この状態ですと、ちょっと試した限りではスカイボックスによる上書きを防止できているようでした。

図4

投稿2022/03/22 22:03

Bongo

総合スコア10816

bh_evan👍を押しています

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

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

bh_evan

2022/03/22 23:17

解決しました!ありがとうございます! しかし、Standard Assets内のWaterが干渉するという問題が新たに発生しました。 同様の方法で試行錯誤していたところ、「Skybox+Water」「オブジェクト+Water」「その他」の3カメラ構成になりましたが、今のところ正しく描写できています。
bh_evan

2022/03/22 23:28

Waterの干渉はカメラの「Near」が原因だったようです。 「Skybox+Water」「Skybox以外全部」の2カメラで描写できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問