17229
ゲームでの描画範囲を高さで制限したいです。

例えば、高さ10メートルのオブジェクトが存在し、描画範囲が高さ8メートルならオブジェクトの上2メートル部分は非表示になる。  
尚且つカメラで上から見たときに、そのオブジェクトの断面が見える。というものを作りたいのですが実装方法が分かりません。

よろしくお願いします。

以上
CC BY-SA 3.0
2015-09-30T00:10:54.987
17080
2015-10-03T15:31:05.633
12484
question
c# unity3d
描画範囲を制限したい
シェーダーを使った描画範囲を制限する方法を提示します。  
描画される全てのものを制限するとなると、適応するのは難しいかも知れませんが、方法のひとつとして参考にしてみてください。  
  
ClipHeight.shader

```

    Shader "Test/ClipHeight"
    {
        Properties
        {
            _MainTex("Base (RGB) Trans (A)", 2D)    = "white" {}
            _Height("Clip Height", float)           = 0
        }
    
        SubShader
        {
            Tags
            {
                "RenderType"    = "Opaque"
            }
    
            Cull Off
    
        CGPROGRAM
    
            #pragma surface surf Lambert
    
            struct Input
            {
                float2  uv_MainTex;
                float3  worldPos;
            };
    
            uniform sampler2D   _MainTex;
            uniform float       _Height;
    
            void surf( Input IN, inout SurfaceOutput OUT )
            {
                clip(-IN.worldPos.y + _Height);
                OUT.Albedo  = tex2D( _MainTex, IN.uv_MainTex ).rgb;
            }
    
        ENDCG
    
        }
    }
    
```

ClipHeight.shaderは_Heightに指定した数値未満の部分を描画しないシェーダーです。  
そしてこのClipHeight.shaderを制御するのが以下のClipHeightコンポーネントです。  
  
ClipHeight.cs

```

    public class ClipHeight : MonoBehaviour
    {
        public float Height
        {
            set
            {
                m_material.SetFloat( "_Height", value );
            }
        }
    
        private Material    m_material;
    
        void Awake()
        {
            var render          = GetComponent< Renderer >();
            m_material          = render.material;
    
            // 強制的に、高さでクリップされるシェーダーに切り替える
            m_material.shader   = Shader.Find( "Test/ClipHeight" );        
        }
    }
    
```

  
そして以下のClipHeightManagerコンポーネントがHierarchy上に存在するすべてのRnedererコンポーネントを持つGameObjectにClipHeightコンポーネントを追加するコンポーネントです。  
Heightプロパティが描画を制限する高さです。

```

    public class ClipHeightManager : MonoBehaviour
    {
        [SerializeField]
        private float   m_height;
    
        private List<ClipHeight> m_cliptList = new List<ClipHeight>();
    
        public float Height
        {
            get
            {
                return m_height;
            }
            set
            {
                m_height    = value;
                foreach( var clip in m_cliptList )
                {
                    clip.Height = m_height;
                }
            }
        }
    
        void Awake()
        {
            // 現在Hierarchy上に存在する全てのRendererのマテリアルを専用シェーダに変更。
    
            var renderList  = GameObject.FindObjectsOfType< Renderer >();
            foreach( var render in renderList )
            {
                var clip    = render.gameObject.AddComponent< ClipHeight >();
                m_cliptList.Add( clip );
            }
    
            Height  = m_height;
        }
    }
    
```

  
Heightプロパティを増減することで、以下のように描画範囲を制限できます。  
  
[![画像の説明をここに入力](https://i.stack.imgur.com/yWEbA.gif)](https://i.stack.imgur.com/yWEbA.gif)  
  
ただこの方法では、描画する全てのオブジェクトのマテリアルのシェーダを専用のものにする必要があるため、汎用的に使うのは難しいかもしれません。
CC BY-SA 3.0
2015-10-03T15:31:05.633
17229
2015-10-03T15:31:05.633
12383
17080
answer