Shader "Custom/Clip" {
Properties{
_MainTex("Texture", 2D) = "white" {}
_BumpMap("Bumpmap", 2D) = "bump" {}
[Space(10)]_ClipObjPos("遮罩位置", Vector) = (0, 0, 0, 1)
_ClipObjNormal("遮罩法線向量", Vector) = (0, 1, 0, 1)
}
SubShader{
Tags{ "RenderType" = "Opaque" } Cull Off
CGPROGRAM
#pragma surface surf Lambert
struct Input {
float2 uv_MainTex;
float2 uv_BumpMap; float3 worldPos;
};
sampler2D _MainTex;
sampler2D _BumpMap;
fixed4 _ClipObjPos;
fixed4 _ClipObjNormal;
float distanceToPlane(float3 pos, float3 objNormal, float3 pointInWorld)
{
float3 w = -(pos - pointInWorld);
//根據數學公式,用平面的法向量計算距離
float res = (objNormal.x * w.x + objNormal.y * w.y + objNormal.z * w.z)
/ sqrt(objNormal.x * objNormal.x + objNormal.y * objNormal.y + objNormal.z * objNormal.z);
return res;
}
void surf(Input IN, inout SurfaceOutput o) {
clip(distanceToPlane(_ClipObjPos.xyz, _ClipObjNormal.xyz, IN.worldPos));
o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb;
o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap));
}
ENDCG
}
Fallback "Diffuse"
}
需要裁剪的物體,換上此shader,可增加實時判斷需要裁剪的位置
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ClipTest : MonoBehaviour {
Material m_mat;
public GameObject m_clipPlane;
// Use this for initialization
void Start () {
m_mat = GetMat(gameObject.GetComponent<Renderer>());
SetMaterialValue(m_clipPlane.transform.position, m_clipPlane.transform.rotation * -Vector3.up);
}
// Update is called once per frame
void Update () {
SetMaterialValue(m_clipPlane.transform.position, m_clipPlane.transform.rotation * -Vector3.up);
}
void SetMaterialValue(Vector3 pos, Vector3 normal)
{
m_mat.SetVector("_ClipObjPos", pos);
m_mat.SetVector("_ClipObjNormal", normal);
}
public static Material GetMat(Renderer render)
{
#if UNITY_EDITOR
return render.material;
#else
return render.sharedMaterial;
#endif
}
}