Unity_物体轮廓外发光
创始人
2024-11-15 18:36:29
0

Shader实现Unity中物体轮廓外发光效果,效果如图

上述效果分两个pass实现,就是每一个pass会绘制一次,至于为什么更改Shader以及相关GPU绘制物体基本流程可以自行搜索,这里只做代码实现以及实现原理,这里更改顶点Shader以及片元着色Shader,这也是我们自己可以代码干预的。

在Assets目录下创建Shader:Create->Shader->Unlit Shader

再创建材质球:Create->Material,将材质球拖入你需要外发光的物体上

创建好后单机材质球在Inspector中找到Shader,更换为Shader->Unlit->你创建好的Shader然后双击打开shader

一、物体边缘黑色光

 Pass  {       cull front      CGPROGRAM       #pragma vertex vert      #pragma fragment frag      #pragma multi_compile_fog      #include "UnityCG.cginc"      struct appdata      {          float4 vertex : POSITION;          float2 uv : TEXCOORD0;          float3 normal:NORMAL;      };      struct v2f      {          float2 uv : TEXCOORD0;          UNITY_FOG_COORDS(1)          float4 vertex : SV_POSITION;           float4 w_vertex:TEXTURE2;          float3 w_normal:TEXTURE1;      };      sampler2D _MainTex;      float4 _MainTex_ST;      v2f vert (appdata v)      {          v2f o;          float4 new_vert=v.vertex+float4(v.normal,1)*float4(0.1,0.1,0.1,1);          o.vertex = UnityObjectToClipPos(new_vert);          o.uv = TRANSFORM_TEX(v.uv, _MainTex);          o.w_normal=UnityObjectToWorldNormal(v.normal);          o.w_vertex=mul(unity_ObjectToWorld,v.vertex);          UNITY_TRANSFER_FOG(o,o.vertex);          return o;      }      fixed4 frag (v2f i) : SV_Target      {          fixed4 col =  fixed4(0,0,0,1);           UNITY_APPLY_FOG(i.fogCoord, col);          return col;      }      ENDCG  }

在第一个pass后直接添加第二个pass,下面讲解上述代码原理:

1.原理

网格包含有顶点坐标,发现,纹理坐标等信息,我们利用法线扩大物体顶点后计算相机与物体顶点法线的之间,法线与相机的角度cos,作为每个顶点都不同的值,并将他作为混合模式的值进行光照计算

2.实现

2.1CGPROGRAM

CGPROGRAM表示Cg program,cg代码开始,最后会有ENDCG表示cg结束

2.2顶点、片元着色器
 #pragma vertex vert  #pragma fragment frag

顶点着色器函数名为vert  
片元着色器函数名为frag  

 #include "UnityCG.cginc"

shader的库函数

v2f vert (appdata v)

 这里开始顶点绘制,在上面struct v2f中拿到需要的参数

 v2f vert (appdata v)  {      v2f o;      float4 new_vert=v.vertex+float4(v.normal,1)*float4(0.1,0.1,0.1,1);      o.vertex = UnityObjectToClipPos(new_vert);      o.uv = TRANSFORM_TEX(v.uv, _MainTex);      o.w_normal=UnityObjectToWorldNormal(v.normal);      o.w_vertex=mul(unity_ObjectToWorld,v.vertex);      UNITY_TRANSFER_FOG(o,o.vertex);      return o;  }

将顶点沿着法线方向放大0.1,

并将新顶点模型坐标转为世界坐标再转为相对相机为原点的坐标。法线向量从对象空间转换到世界空间,返回数据给渲染管道。

fixed4 frag (v2f i) : SV_Target {     fixed4 col =  fixed4(0,0,0,1);      UNITY_APPLY_FOG(i.fogCoord, col);     return col; }

这里我只需要黑色外轮廓所以直接返回黑色

注意cull front剔除前面

上面把效果图中黑色外轮廓实现,注意unity写shader并没有提示,小心错误

二、物体边缘轮廓发亮

 Pass  {      cull front      blend SrcAlpha One      CGPROGRAM       #pragma vertex vert      #pragma fragment frag      #include "UnityCG.cginc"      struct appdata      {          float4 vertex : POSITION;          float2 uv : TEXCOORD0;          float3 normal:NORMAL;      };      struct v2f      {          float2 uv : TEXCOORD0;          UNITY_FOG_COORDS(1)          float4 vertex : SV_POSITION;          float4 w_vertex:TEXTURE2;          float3 w_normal:TEXTURE1;      };      sampler2D _MainTex;      float4 _MainTex_ST;      v2f vert (appdata v)      {          v2f o;          float4 new_vert=v.vertex+float4(v.normal,1)*float4(0.5,0.5,0.5,1);          o.vertex = UnityObjectToClipPos(new_vert);          o.w_normal=UnityObjectToWorldNormal(v.normal);          o.w_vertex=mul(unity_ObjectToWorld,v.vertex);          UNITY_TRANSFER_FOG(o,o.vertex);          return o;      }      fixed4 frag (v2f i) : SV_Target      {         float3 view_dir=i.w_vertex-_WorldSpaceCameraPos;         float3 w_normal=i.w_normal;         view_dir=normalize(view_dir);         w_normal=normalize(w_normal);         float value=dot(view_dir,w_normal);         value=(value<0)?0:value;         value=pow(value,2);          fixed4 col =fixed4(0,1,0,value);          UNITY_APPLY_FOG(i.fogCoord, col);          return col;      }      ENDCG  }

blend SrcAlpha One 这种混合模式通常用于实现一些半透明的效果,其他混合模式可以去unity官方手册查看,下面提供跳转链接

Unity 用户手册 2020.3 (LTS) - Unity 手册

frag中的参数用于计算value值

这样写完之后会导致边缘可能发黑,因为剔除前面但可能网格包含前面,

所以value=(value<0)?0:value;将前面的删除。其他原理与上述差不多

注意:
本篇参考博易创为老师的内容,可以去搜索看看。
只想实现的可以直接复制上述两个pass的代码。

结尾:实现的方式有好多种,我的只是参考。如果frag中点乘不懂的话可以联系我。有任何错误请指出,补充请评论,看到会第一时间回复,谢谢。

相关内容

热门资讯

四分钟了解!方片十三张脚本(辅... 四分钟了解!方片十三张脚本(辅助挂)详细透视开挂辅助必赢方法(其实真的有挂)-哔哩哔哩是一款可以让一...
关于"德扑之星有规律... 关于"德扑之星有规律"详细外挂透明挂辅助挂-原生是有挂(哔哩哔哩)相信很多朋友都在电脑上玩过德扑之星...
第八分钟了解(扑克世界app)... 第八分钟了解(扑克世界app)外挂辅助插件安装下载(透视)插件教程(2026已更新)(哔哩哔哩);1...
wepoke黑科技ai!wpk... wepoke黑科技ai!wpk模拟器是什(透视)德州论坛(有挂总结)-哔哩哔哩;1、点击下载安装,w...
五分钟了解!陕麻圈辅助开挂软件... 五分钟了解!陕麻圈辅助开挂软件(辅助挂)详细透视开挂辅助透明挂教程(本来真的有挂)-哔哩哔哩是一款可...
玩家必看科普!"德扑... 您好:德扑ai软件靠谱这款游戏可以开挂的,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌...
一分钟了解(微扑克开发)外挂辅... 一分钟了解(微扑克开发)外挂辅助插件安装黑科技(透视)教你教程(2026已更新)(哔哩哔哩);一分钟...
wepoker有外挂!wejo... wepoker有外挂!wejoker辅助机器人(透视)AA德州教程(有挂教学)-哔哩哔哩;wejok...
第五分钟了解!哈局八张有透视挂... 第五分钟了解!哈局八张有透视挂(辅助挂)详细透视开挂辅助透明挂教程(总是是有挂)-哔哩哔哩;1、完成...
第二分钟了解(微扑克内置)外挂... 第二分钟了解(微扑克内置)外挂辅助插件安装科技(透视)教你教程(2025已更新)(哔哩哔哩);微扑克...