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

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

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

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

Unity

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

HLSL

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

Q&A

解決済

1回答

3657閲覧

Unity ライトを使用しないで、奥に行くほど暗くなるシェーダ

yaman

総合スコア7

Unity3D

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

Unity

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

HLSL

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

0グッド

0クリップ

投稿2019/02/26 14:58

編集2019/02/26 15:17

前提・実現したいこと

unityシェーダーで「ライトを使用しないで奥に行くほど暗くなるシェーダ」を作成しています。
現状、Unlitで「Texture」は出来たのですが、Unlitで「Cutout」と「Transparent」の対応がしたいのですが
出来ておりません。
(シェーダー初心者なので、お力をお借りしたく)

Unlitで「Texture」の自作シェーダー → (自分では出来ていると思っている…)

Shader "Custom/UnlitDepthShadow_Normal" { Properties { _MainTex ("Main Texture", 2D) = "white" {} _StartDepth ("カメラからの開始深度(小数)", Float) = 50. _EndDepth ("カメラからの終了深度(小数)", Float) = 100. _DepthColor ("深度カラー", Color) = (1,1,1,1) } SubShader { Pass { Tags { "RenderType"="Opaque" "Queue"="Geometry"} Lighting Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float4 projPos : TEXCOORD3; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; // World position float3 _worldPos = mul(unity_ObjectToWorld, v.vertex); // Clip position float4 _pos = mul(UNITY_MATRIX_VP, float4(_worldPos, 1.)); // Screen position o.projPos = ComputeScreenPos(_pos); return o; } sampler2D _MainTex; float _StartDepth; float _EndDepth; fixed4 _DepthColor; sampler2D _CameraDepthTexture; // Depth texture fixed4 frag(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv); // カメラからの距離 float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); if( _StartDepth <= sceneZ ) { fixed4 c2 = tex2D(_MainTex, i.uv) * _DepthColor; ////float _z = clamp(sceneZ,_StartDepth,_EndDepth ); float _per = (sceneZ - _StartDepth) / (_EndDepth - _StartDepth); // 奥に行くほど1.0になる c.rgb = lerp(c.rgb, c2.rgb, _per); } return c; } ENDCG } } FallBack "Diffuse" }

> 結果(成功)

イメージ説明

↓↓↓↓↓ 以下失敗の様子 ↓↓↓↓↓

Unlitで「Transparent」の自作シェーダー

上手くDepth値が取得出来ていないのか、または、その他設定が悪いのか、見当がつかない状態です。
自分なりに調べてコード書いてみたのですがうまく行かず。

Shader "Custom/UnlitDepthShadow_Transparent" { Properties { _MainTex ("Main Texture", 2D) = "white" {} _StartDepth ("カメラからの開始深度(小数)", Float) = 50. _EndDepth ("カメラからの終了深度(小数)", Float) = 100. _DepthColor ("深度カラー", Color) = (1,1,1,1) } SubShader { Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} Pass { Lighting Off ZWrite Off ZTest LEqual Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float4 projPos : TEXCOORD3; }; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; // World position float3 _worldPos = mul(unity_ObjectToWorld, v.vertex); // Clip position float4 _pos = mul(UNITY_MATRIX_VP, float4(_worldPos, 1.)); // Screen position o.projPos = ComputeScreenPos(_pos); return o; } sampler2D _MainTex; float _StartDepth; float _EndDepth; fixed4 _DepthColor; sampler2D _CameraDepthTexture; // Depth texture fixed4 frag(v2f i) : SV_Target { fixed4 c = tex2D(_MainTex, i.uv); // カメラからの距離 float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); ////float partZ = i.projPos.z; if( _StartDepth <= sceneZ ) { fixed4 c2 = tex2D(_MainTex, i.uv) * _DepthColor; float _per = (sceneZ - _StartDepth) / (_EndDepth - _StartDepth); // 奥に行くほど1.0になる c.rgb = lerp(c.rgb, c2.rgb, _per); } return c; } ENDCG } } FallBack "Diffuse" }

> 結果

イメージ説明

実現したい事

以下写真右の様に、「Transparent」または「Cutout」でも、奥に行くほど色(影)を付けたいのです。
ご教授お願い致します。

イメージ説明

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

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

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

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

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

guest

回答1

0

ベストアンサー

Transparentなマテリアルは通常はデプスバッファへの書き込みを行わないので、デプステクスチャからsceneZを求めようとしてもうまくいかなかったのではないかと思います。今回のような場合では、デプステクスチャを使わずとも座標をビュー座標系に変換してやるだけでいいのではないでしょうか?

ShaderLab

1Shader "Custom/UnlitDepthShadow_Transparent" 2{ 3 Properties 4 { 5 _MainTex ("Main Texture", 2D) = "white" {} 6 _StartDepth ("カメラからの開始深度(小数)", Float) = 50. 7 _EndDepth ("カメラからの終了深度(小数)", Float) = 100. 8 _DepthColor ("深度カラー", Color) = (1,1,1,1) 9 } 10 11 SubShader 12 { 13 Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} 14 15 Pass 16 { 17 18 Lighting Off 19 ZWrite Off 20 ZTest LEqual 21 Blend SrcAlpha OneMinusSrcAlpha 22 23 CGPROGRAM 24 #pragma vertex vert 25 #pragma fragment frag 26 27 #include "UnityCG.cginc" 28 29 struct appdata 30 { 31 float4 vertex : POSITION; 32 float2 uv : TEXCOORD0; 33 }; 34 35 struct v2f 36 { 37 float4 vertex : SV_POSITION; 38 float2 uv : TEXCOORD0; 39 40 // projPosはやめて、カメラから見た座標を使うことにする 41 float sceneZ : TEXCOORD3; 42 // float4 projPos : TEXCOORD3; 43 }; 44 45 v2f vert(appdata v) 46 { 47 v2f o; 48 o.vertex = UnityObjectToClipPos(v.vertex); 49 o.uv = v.uv; 50 51 // ビュー座標系はZが反転しているそうなので、正負反転して奥ほど大きな値になるようにする 52 o.sceneZ = -UnityObjectToViewPos(v.vertex).z; 53 54 /* 55 // World position 56 float3 _worldPos = mul(unity_ObjectToWorld, v.vertex); 57 // Clip position 58 float4 _pos = mul(UNITY_MATRIX_VP, float4(_worldPos, 1.)); 59 // Screen position 60 o.projPos = ComputeScreenPos(_pos); 61 */ 62 63 return o; 64 } 65 66 sampler2D _MainTex; 67 float _StartDepth; 68 float _EndDepth; 69 fixed4 _DepthColor; 70 71 // デプステクスチャも使わない 72 // sampler2D _CameraDepthTexture; // Depth texture 73 74 fixed4 frag(v2f i) : SV_Target 75 { 76 fixed4 c = tex2D(_MainTex, i.uv); 77 78 // カメラからの距離 79 // sceneZはやめて、以下ではsceneZに代わってi.sceneZを使う 80 // float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); 81 ////float partZ = i.projPos.z; 82 83 if( _StartDepth <= i.sceneZ ) 84 { 85 // tex2D(_MainTex, i.uv)で得られる色は上で取得したcと同じはずなので、再度サンプリングする必要はないのではないでしょうか? 86 // fixed4 c2 = tex2D(_MainTex, i.uv) * _DepthColor; 87 fixed4 c2 = c * _DepthColor; 88 float _per = (i.sceneZ - _StartDepth) / (_EndDepth - _StartDepth); // 奥に行くほど1.0になる 89 c.rgb = lerp(c.rgb, c2.rgb, _per); 90 } 91 92 return c; 93 } 94 95 ENDCG 96 } 97 } 98 99 FallBack "Diffuse" 100}

投稿2019/02/26 18:53

Bongo

総合スコア10807

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

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

yaman

2019/02/26 19:16

お返事ありがとうございます。 早速、入れ込んでみましたが、期待通りの表示になりました。 ホントに有難う御座いました! // tex2D(_MainTex, i.uv)で得られる色は上で取得したcと同じはずなので、再度サンプリングする必要はないのではないでしょうか? 「Transparent」も含め、上記も修正させて頂きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問