MCS Male Liteのキャラクターを、全天球画像(360度パノラマ画像)を貼り付けた球体のなかで歩かせてみた。
まず、下記のサイトで公開されているSphere100.fbxをダウンロードし、UnityプロジェクトのAssetsフォルダに置く。https://dl.dropboxusercontent.com/u/5911974/Sphere100.fbx
次に、Unityの画面で、Project->Assetsに、Sphere100.fbxが現れるので、それをSceneにドラッグアンドドロップする。
次に、Sphere100のpositionを(0,0,0)に、Scaleを(100,100,100)に変更する。
次に、全天球画像をダウンロードする。適当にGoogleで「360 panorama image」などのキーワードで検索するといっぱいでてくる。
例えば、
http://www.hdrlabs.com/sibl/archive.html
http://rocket9.net/Japan_Trip_Panorama.htm
http://www.freegreatpicture.com/seamless-360-degree-panorama/degree-seamless-panoramic-13972
などから画像をダウンロードして、Assetsフォルダに置く。
今回は、下記のサイトのチャイニーズシアターの写真(Mans_Outside_8k_TMap.jpg)を用いてみた。
http://www.hdrlabs.com/sibl/archive.html
画像を、下図のようにSphere100のMesh Rendererのあたりにドラッグアンドドロップする。
そして、光源の位置を、画像の太陽の位置に合わせて調整する。再生すると以下のような感じに、キャラクターがチャイニーズシアターの前をうろうろと歩かせることができた。ただし、キャラクターの影が球の下側に投影されて不自然な状態になっている。
下記のサイトに従って、透明だけど影を表示するShaderの床(plane)を追加してみた。
http://tsubakit1.hateblo.jp/entry/2015/10/03/001105
http://forum.unity3d.com/threads/transparent-shader-receive-shadows.325877/
手順は以下の通りである。
1)HierarchyにScaleが(2,2,2)のPlateを追加する
2)TransparentShadowCollector.shaderを追加
https://gist.github.com/tsubaki/055575f78334ed727350のshaderそのままでは床が透明にならなかったので、下記のように少し修正を加えたShaderを作る。
Shader "Custom/TransparentShadowCollector" { Properties { _Color("Main Color", Color) = (1,1,1,0.5) // 影の色 _ShadowIntensity("Shadow Intensity", Range(0, 1)) = 0.6 // 影の強さ } SubShader { // Tags{ "Queue" = "Geometry-1" } // QueueをGeometry-1に設定すると球体より前にレンダリングしてしまうので、透明にならない? Pass { Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" "LightMode" = "ForwardBase" } Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include "UnityCG.cginc" #include "AutoLight.cginc" uniform fixed4 _Color; uniform float _ShadowIntensity; struct v2f { float4 pos : SV_POSITION; LIGHTING_COORDS(0,1) }; //vertex shader v2f vert(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); // 頂点の位置を取得 TRANSFER_VERTEX_TO_FRAGMENT(o); // 照明の情報をflagment shaderに渡す return o; } //flagment shader fixed4 frag(v2f i) : COLOR { float attenuation = LIGHT_ATTENUATION(i); // 照明の減衰率を計算 return fixed4(0,0,0,(1 - attenuation)*_ShadowIntensity) * _Color; // 影のレンダリング } ENDCG } } Fallback "VertexLit" }
オリジナルのものとの差分は、「Tags{ "Queue" = "Geometry-1" }」をコメントアウトしたところだけである。
Queueは、シェーダーが設定されているオブジェクトのレンダリングする順番を決めるものであり、下記のようにGeometryはBackgroundの次に大きな値をとるため、Backgroundの次にレンダリングされる。※Queueの値の小さいものからレンダリングされる。
Background 1000 Geometry 2000 AlphaTest 2450 Transparent 3000 Overlay 4000
通常の床の場合、それ以外のオブジェクトより先にレンダリングするので、「Geometry-1」に設定しBackgroundの次にレンダリングするので問題はない。ただし、今回の場合、全天球画像を貼り付けてある球体が床の外側にあり、その球体より先に床をレンダリングしてしまうというのはおかしなことになる。。。そのため、今回はコメントアウトした。
3)Materialを追加
Project->Assetsにて右クリックして、Create->Materialを選択する。Materialの名前を、transparent_shadow(任意)にする。
4)Materialのshaderを設定
3)で作ったMaterialのShaderをCustomize->TransparentShadowCollector.shaderに設定する。
5)PlaneのMaterialを設定
1)で作ったPlaneのMesh Renderer->Materials->Element 0に、3)のMaterialをドラッグアンドドロップして、Materialを設定する。そうすると下図のように透過しつつ影が投影されるようになる。