表面
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 "luoyikun/Clip"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
[Space(10)]_ClipObjPos("遮罩位置", Vector) = (0, 0, 0, 1)
_ClipObjNormal("遮罩法线向量", Vector) = (0, 1, 0, 1)
}
SubShader
{
Tags { "RenderType" = "Opaque" }
//不关闭背面剔除的话看不到物体内侧
Cull off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float3 worldPos:TEXCOORD1;
};
sampler2D _MainTex;
fixed4 _ClipObjPos;
fixed4 _ClipObjNormal;
v2f vert(appdata_base v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.uv = v.texcoord;
return o;
}
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);//两个向量的点乘,<0不同方向
return res;
}
fixed4 frag(v2f i) : SV_Target
{
clip(distanceToPlane(_ClipObjPos.xyz, _ClipObjNormal.xyz, i.worldPos));//<0不显示
float4 color = tex2D(_MainTex, i.uv);
return color;
}
ENDCG
}
}
}
需要裁剪的物体,换上此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
}
}