浅谈Unity之模型裁剪shader

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,5000CU*H 3个月
模型训练 PAI-DLC,5000CU*H 3个月
简介: Unity之模型裁剪shader

前言:每日记录自己学习unity的心得和体会,小弟才疏学浅,如有错误的地方,欢迎大佬们指正,感谢~

使用的核心方法是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

图片.png

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

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"

}


相关文章
|
2天前
|
图形学
【实现100个unity特效】shader实现3D物品闪光和描边效果
【实现100个unity特效】shader实现3D物品闪光和描边效果
7 0
|
3天前
|
存储 图形学
【unity小技巧】unity中导入下载的3D模型及albedo/baseColor、normal 、AO/Occlus、metallic、roughness贴图纹理设置
【unity小技巧】unity中导入下载的3D模型及albedo/baseColor、normal 、AO/Occlus、metallic、roughness贴图纹理设置
5 0
|
24天前
|
图形学
初识Unity——基本模型、场景操作、世界坐标系和局部坐标系
初识Unity——基本模型、场景操作、世界坐标系和局部坐标系
16 1
|
3天前
|
开发工具 图形学
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
【推荐100个unity插件之11】Shader实现UGUI的特效——UIEffect为 Unity UI 提供视觉效果组件
5 0
|
3天前
|
图形学
【实现100个unity特效之2】使用shader和shader Graph实现2d图片描边效果(附源码)
【实现100个unity特效之2】使用shader和shader Graph实现2d图片描边效果(附源码)
4 0
|
3天前
|
图形学 开发者
【实现100个unity特效之1】使用Shader Graph实现动物森友会的世界弯曲效果(带源码)
【实现100个unity特效之1】使用Shader Graph实现动物森友会的世界弯曲效果(带源码)
6 0
|
2月前
|
图形学 异构计算
【Unity Shader 中Pass相关介绍_第四篇】
【Unity Shader 中Pass相关介绍_第四篇】
|
2月前
|
缓存 图形学 异构计算
【#Unity Shader#Amplify Shader Editor(ASE)_第二篇】
【#Unity Shader#Amplify Shader Editor(ASE)_第二篇】
|
2月前
|
图形学
【Unity Shader 中Pass相关介绍_第三篇】
【Unity Shader 中Pass相关介绍_第三篇】
|
2月前
|
图形学 异构计算
【Unity Shader 中Pass相关介绍_第二篇】
【Unity Shader 中Pass相关介绍_第二篇】