球の中にシーンの景色を入れる
目次 [TOC]
はじめに
こういうのです.
見かけたことはあるけど作ったことはなかったので試してみました.
環境
Unity 2019.3.0f6
やってみる
球を見るシーンを用意
まずはSphereを置いておきます.
次に, シェーダーを作成します. Create>Shader>Unlit Shader
で作成されたファイルを開き, 元々書いてあったコードをすべて下のコードに置き換えて下さい. これはビルトインシェーダーのskybox/cubemap
を一部変更したものです.(https://unity3d.com/jp/get-unity/download/archive)
Shader "Custom/Cubemap" { Properties { _Tint ("Tint Color", Color) = (.5, .5, .5, 1.) [Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0 _Rotation ("Rotation", Range(0, 360)) = 0 [NoScaleOffset] _Tex ("Cubemap (HDR)", Cube) = "grey" {} } SubShader { Tags { "Queue"="Transparent" "RenderType"="Transparent"} Cull Front ZWrite Off Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 2.0 #include "UnityCG.cginc" samplerCUBE _Tex; half4 _Tex_HDR; half4 _Tint; half _Exposure; float _Rotation; float3 RotateAroundYInDegrees (float3 vertex, float degrees) { float alpha = degrees * UNITY_PI / 180.0; float sina, cosa; sincos(alpha, sina, cosa); float2x2 m = float2x2(cosa, -sina, sina, cosa); return float3(mul(m, vertex.xz), vertex.y).xzy; } struct appdata_t { float4 vertex : POSITION; UNITY_VERTEX_INPUT_INSTANCE_ID }; struct v2f { float4 vertex : SV_POSITION; float3 texcoord : TEXCOORD0; UNITY_VERTEX_OUTPUT_STEREO }; v2f vert (appdata_t v) { v2f o; UNITY_SETUP_INSTANCE_ID(v); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation); o.vertex = UnityObjectToClipPos(rotated); o.texcoord = v.vertex.xyz; return o; } fixed4 frag (v2f i) : SV_Target { half4 tex = texCUBE (_Tex, i.texcoord); half3 c = DecodeHDR (tex, _Tex_HDR); c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb; c *= _Exposure; return half4(c, _Tint.a); } ENDCG } } Fallback Off }
このシェーダーファイルを右クリックしてCreate>Material
で作成されたマテリアルをさっきのSphereにつけます.
このマテリアルのインスペクターにあるCubemapに置きたい景色のCubemap用のテクスチャを貼れば完了です.
Cubemap用のテクスチャを用意
球に入れる適当なシーンを用意します. 今回はOculus Integrationのサンプルシーンを使いました.
次に, HierarchyでCreate>Light>Reflection Probe
でReflection Probeを作成し, シーンの中央らへんに配置します.
配置ができたら, Refelction ProbeのインスペクターでCubemapに映したいオブジェクトに応じてTypeを選択します.
- Baked プローブは、エディターでのベイキングによって生成される静的リフレクションキューブマップを保存します。
- Custom プローブは、ベイクによって、または、ユーザーによる手動の設定によって、生成された静的キューブマップを保存します。
- Realtime プローブはキューブマップをランタイムで更新するので、シーン内で動的オブジェクトに反応することができます。
staticなオブジェクトのみ対象とするか, 動的なオブジェクトも対象にするか, ランタイムに生成するかで選択するとよさそうです.
今回のシーンでは動くブロックなども含めたかったのでCustomでDynamic Objectsにチェックをいれて使いました.
次はReflection Probeの範囲の調整です.
Refelction Probeのインスペクターの一番上にあるEdit Bounding Volume
のアイコンをクリックするとこのような直方体が表示されます.
これがReflection Probeの範囲なので, Box Size
やBox Offset
をいじって適切なサイズに調整します.
最終的にこんな感じにしました.
Cubemap capture settingsのResolutionなども好きなように設定して下さい.
諸々の設定が完了したらReflection Probeのインスペクターの一番下にあるBakeを実行すればCubemapのテクスチャが生成されます.
テクスチャの生成が完了したらRefelction Probeは消してもOKです(そのまま使いたい場合はもちろん残してもらっても大丈夫です.)
完成
最初に作ったシーンへ戻ります.
用意してあるマテリアルに生成したテクスチャを貼ります.
なんかぼやけてますね...
生成したテクスチャのインスペクターを見てみて下さい.
このようにMappingのConvolution TypeがSpecularだとぼやけるようなので, Noneに変更してApplyしてみて下さい.
すると, このようにきれいになりました!
参考
https://docs.unity3d.com/ja/2019.3/Manual/class-Cubemap.html https://docs.unity3d.com/ja/2018.4/Manual/class-ReflectionProbe.html https://light11.hatenadiary.com/entry/2018/07/10/231546