【unity】模型裁剪shader(建筑生长动画)

【unity】模型裁剪shader(建筑生长动画)

思路

使用的核心方法是clip,当传入正值时渲染,传入负值时不渲染。定义一个裁剪向量,使用裁剪向量和模型点点乘,如果模型点和裁剪向量是同一个方向,点乘为正,相反为负。

shader源码

Shader "SongShaderDemo/CutOffWorld"
{
    Properties
    {
       _MainTex("Texture", 2D) = "white" {}
       _CutValue("切割范围:",Float) = 0
      _CutDirection("切割方向",Vector) = (0, 1, 0, 0)
      _CutDistance("切割距离",Float) = 1000
       _LightIntensity("灯光强度",Float) = 1
    }
    SubShader
    {
       Tags { "RenderType" = "Opaque" "LigthMode" = "ForwarBase"}
        LOD 100

        Pass
        {
            Cull Off
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #include "Lighting.cginc "
            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal: NORMAL;//存储法线的盒子
            };

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

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _CutValue;
            float _CutDistance;
            float4 _CutDirection;
            float _LightIntensity;
            v2f vert (appdata v)
            {
                v2f o;
                o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
    
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.wNormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                //_WorldSpaceLightPos0 unity提供的灯光向量
                float3 L = normalize(_WorldSpaceLightPos0);
                float3 N = normalize(i.wNormal);
                float halfLam = dot(L, N) * 0.5 + 0.75;
                //_LightColor0.rgb unity提供的灯光强度
                float3 diffLight = halfLam * _LightColor0.rgb*_LightIntensity;
                fixed4 diffColor = fixed4(diffLight.rgb, 1);
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                float3 cutDirection = normalize(_CutDirection.xyz);//切割向量
                float3 curCenter = (cutDirection * (_CutValue - 0.5) * _CutDistance);//切割的原点,在切割的向量上移动
                float3 targetVer = i.worldPos - curCenter;//切割原点到模型点上的向量
                float angel =- dot(cutDirection,normalize(targetVer));//切割向量和targetVer点乘,正则同方向,父则反方向
                clip(angel);//反方向剔除
                return col* diffColor;
            }
            ENDCG
        }
    }
}

使用Shader Graphs

在这里插入图片描述

shaderGraphs设置

在Gragh Inspector里勾选Alpha Cilpping

在Fragment里Alpha Clip Threshold设置为0(Alpha>=Alpha Clip Threshold阈值,那么显示图像,如果小于,则裁剪掉小于的部分

demo

using System;
using System.Collections;
using UnityEngine;

public class MatManager : MonoBehaviour
{
    public float High;//裁剪距离
    public Material CutMaterial;//裁剪材质
    void Start()
    {
        DoTime(4, SetCutHigh);
    }
    void  SetCutHigh(float Time)
    {
        CutMaterial.SetFloat("_CutValue", High* Time);
    }
    /// <summary>
    /// 时间插值
    /// </summary>
    /// <param name="time">插值时间</param>
    /// <param name="id">ID</param>
    /// <param name="action">返回方法</param>
    public void DoTime(float time, Action<float> action, string id = null)
    {

        IEnumerator coroutine;
        coroutine = DoTimeIE(time, action);
        StartCoroutine(coroutine);
    }
    IEnumerator DoTimeIE(float time, Action<float> action = null)
    {
        float t = 0;
        while (t < 1)
        {
            t += Time.deltaTime / time;
            if (action != null)
            {
                action(t);
            }
            t = t > 1 ? 1 : t;
            yield return null;
        }
        action(1);
    }
}

补充(自身模型空间的裁剪)

Shader "SongShaderDemo/CutOffObject"
{
	Properties
	{
	   _MainTex("Texture", 2D) = "white" {}
	   _CutValue("切割范围:",Float) = 0
	  _CutDirection("切割方向",Vector) = (0, 0, 0, 0)
	  _CutDistance("切割距离",Float) = 1
      _LightIntensity("灯光强度",Float) = 1
	}
		SubShader
	   {
		   Tags { "RenderType" = "Opaque" "LigthMode" = "ForwarBase"}
		   LOD 100
		  // Blend SrcAlpha OneMinusSrcAlpha

		ZWrite On
		Pass
		{
		Cull Off
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "Lighting.cginc "

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
				float3 normal: NORMAL;//存储法线的盒子
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
				float3  worldPos  : TEXCOORD1;
				float3 center:TEXCOORD2;
				float3 wNormal:TEXCOORD6;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			float _CutValue;
			float _CutDistance;
			float _LightIntensity;
			float4 _CutDirection;
			v2f vert(appdata v)
			{
				v2f o;
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				//得到中心点
				o.center = float3(unity_ObjectToWorld[0].w, unity_ObjectToWorld[1].w, unity_ObjectToWorld[2].w);
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				o.wNormal = UnityObjectToWorldNormal(v.normal);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				//_WorldSpaceLightPos0 unity提供的灯光向量
				float3 L = normalize(_WorldSpaceLightPos0);
				float3 N = normalize(i.wNormal);
				float halfLam = dot(L, N)*0.5 + 0.75;
				//_LightColor0.rgb unity提供的灯光强度
				float3 diffLight = halfLam * _LightColor0.rgb*_LightIntensity;
				fixed4 diffColor = fixed4(diffLight.rgb, 1);
				// sample the texture
				fixed4 col = tex2D(_MainTex, i.uv);

			float3 cutDirection = normalize(_CutDirection.xyz);//切割向量
			float3 curCenter = i.center + (cutDirection*(_CutValue - 0.5)*_CutDistance);//切割的原点,在切割的向量上移动
			float3 targetVer = i.worldPos - curCenter;//切割原点到模型点上的向量
			float angel = dot(normalize(targetVer), cutDirection);//切割向量和targetVer点乘,正则同方向,父则反方向
			clip(angel);//反方向剔除
	
			return col * diffColor;
			}
			ENDCG
		}
		

	   }
		  Fallback "Transparent/VertexLit"
}

### 如何在银河麒麟 V10 SP1 系统中安装或使用微信 #### 方法一:通过添加软件源并安装 PC 版微信 如果希望在银河麒麟 V10 SP1 上安装 PC 版微信,可以尝试以下操作。首先需要确保系统的软件源已经配置完成,并能够访问外部网络资源。 ```bash sudo apt update && sudo apt upgrade -y ``` 接着可以通过 `apt` 命令来查找和安装微信的相关依赖以及应用本身: ```bash sudo apt install weixin ``` 此方法适用于系统源中已包含微信的情况[^1]。如果没有找到对应的包,则可能需要手动下载 `.deb` 文件并通过 `dpkg` 安装。 --- #### 方法二:利用网页版微信作为替代方案 对于某些情况下无法直接安装 PC 版微信的情形,可以选择使用网页版微信。然而,在银河麒麟 V10 中可能会遇到网页版微信登录失败的问题。此时可通过清理浏览器缓存或者更换支持的浏览器实现正常功能。 针对银河麒麟自带的浏览器或其他兼容 Chromium 的浏览器,可执行以下命令清空缓存数据: ```bash rm -rf ~/.cache/chromium/ ``` 上述命令会删除用户的 Chromium 浏览器缓存目录,从而帮助解决因缓存导致的页面加载异常问题[^2]。 另外一种方式是借助第三方工具扩展 Chrome 或者基于其开发的其他浏览器的能力以适配更广泛的网站服务需求。例如提到的一个 GitHub 开发项目提供了专门用于增强 Linux 下 Web 微信体验的支持插件[^4]。 --- #### 方法三:检查系统激活状态影响的应用权限 值得注意的是,部分应用程序的行为受限于操作系统本身的授权情况。假如当前使用的银河麒麟实例尚未经过正式注册或许可验证流程,则有可能面临诸如即时通讯类程序连接不上服务器等问题。 对此建议先检验本机环境是否处于有效期内被官方认可的状态下运作;如果不是则按照指引完成必要的设置步骤后再试一次启动目标社交平台客户端进程: ```bash sudo apt-get install kylin-activation libkylin-activation ``` 以上脚本片段旨在引导用户正确处理涉及版权保护机制下的软硬件交互逻辑关系。 --- #### 方法四:考虑特定架构优化后的 Qt 库版本因素 最后还有一点需要注意的就是关于图形界面渲染引擎选型方面的影响。由于不同 CPU 平台之间存在差异化的编译参数设定标准,所以在选用适合龙芯系列处理器特性的组件集合时也要格外小心谨慎对待每一个细节环节。 比如这里提到了一个具体例子就是有关 qt5-default 软件包及其附属模块组合在一起共同构成了完整的 GUI 层面支撑框架结构体系[^3] 。因此当发现原有默认选项不能满足实际业务场景要求时候不妨试着切换成定制化程度更高的备选方案试试看效果如何? --- ### 总结 综上所述,要在银河麒麟 V10 SP1 系统成功部署运行微信主要有四种途径可供选择分别是直接从仓库获取预构建好的二进制文件形式分发包、采用轻量级在线聊天室入口链接跳转至对应位置继续后续动作、排查是否存在未解锁隐藏特性开关按钮阻止正常使用情形发生以及调整底层技术支持栈构成要素使之更加贴合本地实际情况达到最佳性能表现水平为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小生云木

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

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

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

打赏作者

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

抵扣说明:

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

余额充值