unity3d:shader: Clip裁剪显示

表面

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
    }

}

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四夕立羽

你的鼓励将是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值