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

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

新規登録して質問してみよう
ただいま回答率
85.51%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

Q&A

解決済

1回答

6118閲覧

Unityで影だけを表示させたい

hirokun9465

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

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

0グッド

0クリップ

投稿2018/03/08 09:10

Unityでゲームオブジェクトを、ライトで真上から照らした光沢にしつつ、それに付く影はライトを上斜めから当てた感じで表示させたいと考えています。
Dlirectional lightを2種類用意して一つは真上から照らし、もう一つは影だけのために斜め上から照らす方法を考え、影用のライトはオブジェクトの光沢に影響を与えないようにcolorを黒に設定したのですが、そうすると影も消えてしまい、上手く行きません。
このようにDlirectional lightを2種類用意して出来るものでしょうか。もしくは他に方法がありますでしょうか?
宜しくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

光源は1種類だけとし、斜め上から照らすことで影は通常通りに生じさせ、表面の光沢を決定する際に光源の向きを真上に書き換えて、このニセの光源方向をもとに描画させるというのはどうでしょう。

「Assets」→「Create」→「Shader」→「Standard Surface Shader」で新規サーフェスシェーダーを作り、コードを下記のように変更してみました。

HLSL

1Shader "Custom/CustomLit" 2{ 3 Properties 4 { 5 _Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0) 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 { 13 Tags { "RenderType"="Opaque" } 14 LOD 200 15 16 CGPROGRAM 17 // Physically based Standard lighting model, and enable shadows on all light types 18 #pragma surface surf CustomLit fullforwardshadows // StandardをCustomLitに差し替え 19 20 // Use shader model 3.0 target, to get nicer looking lighting 21 #pragma target 3.0 22 23 #include "UnityPBSLighting.cginc" // SurfaceOutputStandard、LightingStandard、LightingStandard_Deferred、LightingStandard_GIを使用できるようにする 24 25 sampler2D _MainTex; 26 27 struct Input 28 { 29 float2 uv_MainTex; 30 }; 31 32 // CustomLit用SurfaceOutput...構成はSurfaceOutputStandardと同じ 33 struct SurfaceOutputCustomLit 34 { 35 fixed3 Albedo; // base (diffuse or specular) color 36 fixed3 Normal; // tangent space normal, if written 37 half3 Emission; 38 half Metallic; // 0=non-metal, 1=metal 39 half Smoothness; // 0=rough, 1=smooth 40 half Occlusion; // occlusion (default 1) 41 fixed Alpha; // alpha for transparencies 42 }; 43 44 half _Glossiness; 45 half _Metallic; 46 fixed4 _Color; 47 48 // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. 49 // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. 50 // #pragma instancing_options assumeuniformscaling 51 UNITY_INSTANCING_BUFFER_START(Props) 52 // put more per-instance properties here 53 UNITY_INSTANCING_BUFFER_END(Props) 54 55 void surf(Input IN, inout SurfaceOutputCustomLit o) // SurfaceOutputStandardをSurfaceOutputCustomLitに変更、処理内容自体はデフォルトのコードのまま 56 { 57 // Albedo comes from a texture tinted by color 58 fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; 59 o.Albedo = c.rgb; 60 // Metallic and smoothness come from slider variables 61 o.Metallic = _Metallic; 62 o.Smoothness = _Glossiness; 63 o.Alpha = c.a; 64 } 65 66 // フォワードレンダリング用 67 inline half4 LightingCustomLit(SurfaceOutputCustomLit s, half3 viewDir, UnityGI gi) 68 { 69 return LightingStandard((SurfaceOutputStandard)s, viewDir, gi); // 引数をLightingStandardにそのまま渡し、結果を返す 70 } 71 72 // デファードレンダリング用 73 inline half4 LightingCustomLit_Deferred(SurfaceOutputCustomLit s, half3 viewDir, UnityGI gi, out half4 outGBuffer0, out half4 outGBuffer1, out half4 outGBuffer2) 74 { 75 return LightingStandard_Deferred((SurfaceOutputStandard)s, viewDir, gi, outGBuffer0, outGBuffer1, outGBuffer2); // 引数をLightingStandard_Deferredにそのまま渡し、結果を返す 76 } 77 78 // GI情報のデコード 79 inline void LightingCustomLit_GI(SurfaceOutputCustomLit s, UnityGIInput data, inout UnityGI gi) 80 { 81 data.light.dir = half3(0.0, 1.0, 0.0); // 光源の向きを(0, 1, 0)に書き換える 82 83 LightingStandard_GI((SurfaceOutputStandard)s, data, gi); // 引数をLightingStandard_GIに渡す 84 } 85 86 ENDCG 87 } 88 89 FallBack "Diffuse" 90}

これを使ったマテリアルをオブジェクトに適用したところ、下図のようになりました。

プレビュー

奥4つはデフォルトのサーフェスシェーダーをそのまま用いた場合、中4つは上記CustomLitを使った場合です。
CustomLitを使った場合、オブジェクトが落とす影は光源の向きに合わせて変化しますが、光沢は真上から照らしたような陰影付けのまま変化しません。
さらに、手前4つはCustomLitを使った上でインスペクタの「Mesh Renderer」の「Receive Shadows」をオフにしたものです。そのオブジェクト自身や他のオブジェクトが落とした影がオブジェクト自身の上にかからなくなるので、このような設定にした場合は影の中でも真上から照らされたように描画されることになります。

インスペクタ

このニセ光源方向効果をデファードレンダリングモードでも行うには、デファードレンダリング用シェーダーも改造する必要があるでしょう。
「Resources」フォルダ内に例えば下記のようなファイルを置いて、

HLSL

1Shader "Hidden/Internal-DeferredShadingCustomLit" { 2Properties { 3 _LightTexture0 ("", any) = "" {} 4 _LightTextureB0 ("", 2D) = "" {} 5 _ShadowMapTexture ("", any) = "" {} 6 _SrcBlend ("", Float) = 1 7 _DstBlend ("", Float) = 1 8} 9SubShader { 10 11// Pass 1: Lighting pass 12// LDR case - Lighting encoded into a subtractive ARGB8 buffer 13// HDR case - Lighting additively blended into floating point buffer 14Pass { 15 ZWrite Off 16 Blend [_SrcBlend] [_DstBlend] 17 18CGPROGRAM 19#pragma target 3.0 20#pragma vertex vert_deferred 21#pragma fragment frag 22#pragma multi_compile_lightpass 23#pragma multi_compile ___ UNITY_HDR_ON 24 25#pragma exclude_renderers nomrt 26 27#include "UnityCG.cginc" 28#include "UnityDeferredLibrary.cginc" 29#include "UnityPBSLighting.cginc" 30#include "UnityStandardUtils.cginc" 31#include "UnityGBuffer.cginc" 32#include "UnityStandardBRDF.cginc" 33 34sampler2D _CameraGBufferTexture0; 35sampler2D _CameraGBufferTexture1; 36sampler2D _CameraGBufferTexture2; 37 38half4 CalculateLight (unity_v2f_deferred i) 39{ 40 float3 wpos; 41 float2 uv; 42 float atten, fadeDist; 43 UnityLight light; 44 UNITY_INITIALIZE_OUTPUT(UnityLight, light); 45 UnityDeferredCalculateLightParams (i, wpos, uv, light.dir, atten, fadeDist); 46 47 light.color = _LightColor.rgb * atten; 48 49 // unpack Gbuffer 50 half4 gbuffer0 = tex2D (_CameraGBufferTexture0, uv); 51 half4 gbuffer1 = tex2D (_CameraGBufferTexture1, uv); 52 half4 gbuffer2 = tex2D (_CameraGBufferTexture2, uv); 53 UnityStandardData data = UnityStandardDataFromGbuffer(gbuffer0, gbuffer1, gbuffer2); 54 55 float3 eyeVec = normalize(wpos-_WorldSpaceCameraPos); 56 half oneMinusReflectivity = 1 - SpecularStrength(data.specularColor.rgb); 57 58 UnityIndirect ind; 59 UNITY_INITIALIZE_OUTPUT(UnityIndirect, ind); 60 ind.diffuse = 0; 61 ind.specular = 0; 62 63 light.dir = half3(0.0, 1.0, 0.0); // 光源の向きを(0, 1, 0)に書き換える 64 65 half4 res = UNITY_BRDF_PBS (data.diffuseColor, data.specularColor, oneMinusReflectivity, data.smoothness, data.normalWorld, -eyeVec, light, ind); 66 67 return res; 68} 69 70#ifdef UNITY_HDR_ON 71half4 72#else 73fixed4 74#endif 75frag (unity_v2f_deferred i) : SV_Target 76{ 77 half4 c = CalculateLight(i); 78 #ifdef UNITY_HDR_ON 79 return c; 80 #else 81 return exp2(-c); 82 #endif 83} 84 85ENDCG 86} 87 88 89// Pass 2: Final decode pass. 90// Used only with HDR off, to decode the logarithmic buffer into the main RT 91Pass { 92 ZTest Always Cull Off ZWrite Off 93 Stencil { 94 ref [_StencilNonBackground] 95 readmask [_StencilNonBackground] 96 // Normally just comp would be sufficient, but there's a bug and only front face stencil state is set (case 583207) 97 compback equal 98 compfront equal 99 } 100 101CGPROGRAM 102#pragma target 3.0 103#pragma vertex vert 104#pragma fragment frag 105#pragma exclude_renderers nomrt 106 107#include "UnityCG.cginc" 108 109sampler2D _LightBuffer; 110struct v2f { 111 float4 vertex : SV_POSITION; 112 float2 texcoord : TEXCOORD0; 113}; 114 115v2f vert (float4 vertex : POSITION, float2 texcoord : TEXCOORD0) 116{ 117 v2f o; 118 o.vertex = UnityObjectToClipPos(vertex); 119 o.texcoord = texcoord.xy; 120#ifdef UNITY_SINGLE_PASS_STEREO 121 o.texcoord = TransformStereoScreenSpaceTex(o.texcoord, 1.0f); 122#endif 123 return o; 124} 125 126fixed4 frag (v2f i) : SV_Target 127{ 128 return -log2(tex2D(_LightBuffer, i.texcoord)); 129} 130ENDCG 131} 132 133} 134Fallback Off 135}

Unity - Manual: Deferred shading rendering pathの一番下にある手順に従って、そのカスタムデファードレンダリング用シェーダーを使うようグラフィックス設定を変更する必要があるかと思います。

The only lighting model available is Standard. If a different model is wanted you can modify the lighting pass shader, by placing the modified version of the Internal-DeferredShading.shader file from the Built-in shaders into a folder named “Resources” in your “Assets” folder. Then go to the Edit->Project Settings->Graphics window. Changed the “Deferred” dropdown to “Custom Shader”. Then change the Shader option which appears to the shader you are using.

使用可能なライティングモデルはStandardのみです。もし別のライティングモデルが必要なら、ビルトインシェーダーのInternal-DeferredShading.shaderの改変版を「Assets」フォルダ内の「Resources」という名前のフォルダ内に置くことでライティングパスシェーダーを変更できます。そして、「Edit」→「Project Settings」→「Graphics」を開き、「Deferred」ドロップダウンを「Custom Shader」に変更してください。すると「Shader」オプションが現れるので、それを使用するシェーダーに変更します。

投稿2018/03/10 01:46

Bongo

総合スコア10807

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

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

hirokun9465

2018/03/11 02:20

ありがとうございます。 シェーダーを使うしかないということは調べていくうちに何となく分かっていたのですが、自力で解決出来ず時間が過ぎていき、もう諦めようと思っていたところで素晴らしい回答を頂き、やりたい事を実現することができました。 この度は分かりやすい説明と長いプログラムを提供して頂きまして、誠にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問