【Unity】視錐台カリングを無効化する

視錐台カリングを(強引に)無効化する方法です。

課題

たとえば下記のようなシェーダで頂点の位置を変えることを考えます。
元の頂点位置に基づいて視錐台カリングが行われた結果、モデルが思わぬところで描画されなくなったりします。

Shader "DisableFrustomCulling"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag
            
           #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
            };
            
            v2f vert (appdata v)
            {
                v2f o;
                // 頂点座標を変える
                v.vertex.y += 100;
                o.vertex = UnityObjectToClipPos(v.vertex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                return half4(1, 0, 0, 1);
            }
            ENDCG
        }
    }
}

こういう時の対処法として、視錐台カリングを無効化してみます。

実装

無効化するといっても、実際に行っているのはバウンディングボックスを大きくしてカリングされないようにしているだけです。

using UnityEngine;

[DisallowMultipleComponent]
public class DisableFrustomCulling : MonoBehaviour
{
    private void Awake()
    {
        GetComponent<MeshFilter>().mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 1000);
    }
}

これを当該GameObjectにアタッチすればカリングされなくなります。

また今回はメッシュを動的に複製していますが、下記のような感じであらかじめバウンディングボックスを大きく設定したメッシュをAsset化しておいても問題ないです。

var mesh = GetComponent<MeshFilter>().mesh;
mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 1000);
UnityEditor.AssetDatabase.CreateAsset(mesh, "Assets/sample_mesh.asset");

そのあたりはケースバイケースで。