Unity3d 实现MeshRender 材质球的遮罩

Shader "Custom/Clip"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}

        _ClipY ("剔除 Y 值", float) = 0

        [Space(10)]_ClipObjPos    ("遮罩位置",    Vector)    = ( 0, 0, 0, 1 )
        _ClipObjNormal    ("遮罩法线向量",    Vector)    = ( 0, 1, 0, 1 )
    }
    SubShader
    {
        Cull Back

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

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float3 worldPos : TEXCOORD1;
            };

            sampler2D _MainTex;
            float _ClipY;
            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;
            }

            v2f vert (appdata v)
            {
                v2f o;

                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                //计算模型的真正世界坐标
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                o.uv = v.uv;
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                clip(distanceToPlane(_ClipObjPos.xyz, _ClipObjNormal.xyz, i.worldPos));
                clip(i.worldPos.y - _ClipY);
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }


            ENDCG
        }
    }
}

使用控制脚本

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

public class SizeClipController : MonoBehaviour
{
    public enum NormalStatus
    {
        none,
        up,
        down,
        left,
        right
    }

    public NormalStatus normalStatus = NormalStatus.none;

    public Transform clipObjTrans;
    public MeshRenderer sizeRenderer;
    public MeshRenderer shortSizeRender_1;
    public MeshRenderer shortSizeRender_2;
    private Material clipMaterial;
    private Material clipMaterial2;
    private Material clipMaterial3;
    public Vector3 clipPos;
    private Vector3 clipNormal;
    [SerializeField]
    bool isCalculate;

    void Start()
    {
        if (sizeRenderer)
        {
            clipMaterial = sizeRenderer.sharedMaterial;
        }
        if (shortSizeRender_1)
        {
            clipMaterial2 = shortSizeRender_1.sharedMaterial;
        }
        if (shortSizeRender_2)
        {
            clipMaterial3=shortSizeRender_2.sharedMaterial;
        }
    }

    void SetMaterialValue(Vector3 pos, Vector3 normal)
    {
       if (clipMaterial)
        {
            clipMaterial.SetVector("_ClipObjPos", pos);
            clipMaterial.SetVector("_ClipObjNormal", normal);
        }

        if (clipMaterial2)
        {
            clipMaterial2.SetVector("_ClipObjPos", pos);
            clipMaterial2.SetVector("_ClipObjNormal", normal);
        }

        if (clipMaterial3)
        {
            clipMaterial3.SetVector("_ClipObjPos", pos);
            clipMaterial3.SetVector("_ClipObjNormal", normal);
        }
    }

    public void SetCalculate(bool value)
    {
        isCalculate = value;
    }


    void Update()
    {
        if (isCalculate)
        {
            clipPos = clipObjTrans.position;

            if (normalStatus == NormalStatus.down)
            {
                //计算XY平面上的法向量,用XY平面作为剔除面
                clipNormal = clipObjTrans.rotation * Vector3.down;
            }
            else if (normalStatus == NormalStatus.up)
            {
                //计算XY平面上的法向量,用XY平面作为剔除面
                clipNormal = clipObjTrans.rotation * Vector3.up;
            }
            else if (normalStatus == NormalStatus.left)
            {
                //计算XY平面上的法向量,用XY平面作为剔除面
                clipNormal = clipObjTrans.rotation * Vector3.left;
            }
            else if (normalStatus == NormalStatus.right)
            {
                //计算XY平面上的法向量,用XY平面作为剔除面
                clipNormal = clipObjTrans.rotation * Vector3.right;
            }

            SetMaterialValue(clipPos, clipNormal);
        }


    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值