带光照模型的的6面切割模型VFshader

      这是用6个面来切割模型shader,当然稍加修改可以支持n(n>=1)个面,在c#代码中分别为pPoint和pNormal参数赋值,pPoint传入平面的世界坐标,pNormal传入该平面的法线。考虑到性能,光照模型加在了顶点程序中。

Shader "Custom/6PlaneClipShader"
{
    Properties{
        _Diffuse("Diffuse", Color) = (1,1,1,1)
        _MainTex("Base 2D", 2D) = "white"{}
    }
    SubShader
    {
    Pass
    {
        Tags{ "RenderType" = "Opaque" }
        CGPROGRAM
        #include "Lighting.cginc"

    fixed4 _Diffuse;
    sampler2D _MainTex;
    float4 _MainTex_ST;
    float4 pPoint[6];
    float4 pNormal[6];

    struct a2v
    {
        float4 vertex : POSITION;
        float3 normal : NORMAL;
        float4 texcoord : TEXCOORD0;
    };
    struct v2f
    {
        float4 pos : SV_POSITION;
        fixed4 color : COLOR;
        float2 uv : TEXCOORD1;
        float4 VertPos:TEXCOORD2;
    };
    bool effectiveRange(float3 pos)
    {
        pos = mul(unity_ObjectToWorld, float4(pos, 1));
        for (int i = 0; i < 6; i++) {
            float3 dir = normalize(pos - pPoint[i].xyz);
            //如果平面内任意点指向该模型顶点的向量与法线夹角为锐角,则保留该点
            if (dot(dir, normalize(pNormal[i].xyz))< 0) {
                return false;
            }
        }
        return true;
    }
    v2f vert(a2v v)
    {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);
        o.VertPos = v.vertex;
        //------------------------
        fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
        float3 worldNormal = mul(unity_WorldToObject,v.normal);
        worldNormal = normalize(worldNormal);
        fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
        fixed3 lambert = 0.5 * dot(worldNormal, worldLightDir)+0.5;
        o.color = fixed4(lambert * _Diffuse.xyz * _LightColor0.xyz + ambient* _Diffuse.xyz, 1.0);
        //---------该部分实现halfLambert光照模型
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        //配置Tilling
        return o;
    }
    fixed4 frag(v2f i) : SV_Target
    {
        fixed4 col = fixed4(0,0,0,0);
        if (effectiveRange(i.VertPos))
        {
            col= i.color * tex2D(_MainTex, i.uv);
        }
        else
        {
            discard;
        }
        return col;
    }

#pragma vertex vert
#pragma fragment frag    
        ENDCG
    }
    }
        FallBack "Diffuse"
}


C#代码部分:

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

public class SetAllPlane : MonoBehaviour {
    public Transform[] plane;
    void Start () {
        Vector4[] point = new Vector4[6];
        Vector4[] normal = new Vector4[6];
        for (int i=0;i<plane.Length;i++)
        {
            point[i] = plane[i].position;
            normal[i] = plane[i].forward;
        }
        GetComponent<MeshRenderer>().material.SetVectorArray("pPoint", point);
        GetComponent<MeshRenderer>().material.SetVectorArray("pNormal", normal);
    }    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值