Clip one cube with two plane arrays and keep positive sides?

I’m looking for a way to clip with plane arrays for my project.

The test code works, but not in my project.

The effect I am going for is each array of planes has it’s own object to clip.

How do I clip one cube with two plane arrays and keep the positive sides?

My test code.

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class clipcube : MonoBehaviour
{
    public GameObject Cube;

    public Vector4[] PlanePos;

    public MaterialPropertyBlock BlockOne;

    public List<Plane> planes = new List<Plane>();

    // Start is called before the first frame update
    void Start()
    {
        PlanePos = new Vector4[10];

        BlockOne = new MaterialPropertyBlock();

        planes.Add(new Plane(new Vector3(5,0,0), new Vector3(5,0, -1), new Vector3(5, 1, -1)));

        planes.Add(new Plane(new Vector3(-5, 1, -1), new Vector3(-5, 0, -1), new Vector3(-5, 0, 0)));
    }
       

    // Update is called once per frame
    void Update()
    {
        for (int i = 0; i < planes.Count; i++)
        {
            BlockOne.SetInt("_Int", planes.Count);

            Array.Clear(PlanePos, 0, PlanePos.Length);

            PlanePos[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, planes[i].distance);

            Matrix4x4 matrix = Matrix4x4.TRS(Cube.transform.position, Cube.transform.rotation, Cube.transform.lossyScale);

            Graphics.DrawMesh(Cube.GetComponent<MeshFilter>().mesh, matrix, Cube.GetComponent<Renderer>().sharedMaterial, 0, Camera.main, 0, BlockOne, false, false);

            BlockOne.SetVectorArray("_Plane", PlanePos);
        }
    }
}

My shader

Shader "Custom/Clipping"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        [HDR]_Emission ("Emission", color) = (0,0,0)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
            float3 worldPos;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        int _Int = 0;
        float4 _Plane[50];
        half3 _Emission;

        // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
        // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
        // #pragma instancing_options assumeuniformscaling
        UNITY_INSTANCING_BUFFER_START(Props)
            // put more per-instance properties here
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            for (int i = 0; i < _Int; i++)
            {
                float distance = dot(IN.worldPos, _Plane[i].xyz);
                distance = distance + _Plane[i].w;
                clip(distance);
            }
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
            o.Emission = _Emission * tex2D(_MainTex, IN.uv_MainTex);
}
        ENDCG
    }
    FallBack "Diffuse"
}

The update loop doesn’t make any sense to me. You’re rendering one cube multiple times, once for each plane in the array, only assigning one plane in each loop, but also setting the material to iterate over the array as if all of the planes are there. You’re also not setting the plane array in the property block until after adding the DrawMesh command, meaning the first draw won’t have any plane data! The property block is copied when you call DrawMesh, so any modifications you make after calling DrawMesh are ignored by the call.

If the code was modified to properly draw the cube once for each plane, the result would be you’d still just see a solid cube except where the planes intersect, as the rest of the cube is still being rendered each time.

To me it seems like you want to do this:

void Update()
{
  BlockOne.SetInt("_Int", planes.Count);
  Array.Clear(planePos, 0, planes.Count);
  for (int i=0; i<planes.Count; i++)
    planePos[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, planes[i].distance);
  BlockOne.SetVectorArray("_Plane", planePos);
  Matrix4x4 matrix = Matrix4x4.TRS(Cube.transform.position, Cube.transform.rotation, Cube.transform.lossyScale);
  Graphics.DrawMesh(Cube.GetComponent<MeshFilter>().mesh, matrix, Cube.GetComponent<Renderer>().sharedMaterial, 0, Camera.main, 0, BlockOne, false, false);
}

Thank you, I set the vector array and now the project works.