Unity_物体轮廓外发光

这篇具有很好参考价值的文章主要介绍了Unity_物体轮廓外发光。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

unity外轮廓发光,Unity,unity,游戏引擎unity外轮廓发光,Unity,unity,游戏引擎

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

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

再创建材质球:Create->Material,将材质球拖入你需要外发光的物体上unity外轮廓发光,Unity,unity,游戏引擎

创建好后单机材质球在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,

unity外轮廓发光,Unity,unity,游戏引擎

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

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;将前面的删除。其他原理与上述差不多文章来源地址https://www.toymoban.com/news/detail-857257.html

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

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

到了这里,关于Unity_物体轮廓外发光的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D】Unity 脚本 ③ ( C# 脚本的执行入口函数 | 获取当前游戏物体及物体名称 | 获取游戏物体的 Transform 组件数据 | UnityEngine 命名空间简介 )

    在 C# 脚本中控制 游戏物体 GameObject 运动 , 要先获取该物体 , 然后 修改其 Transform 组件的属性 ; 在 游戏开始运行后 , 会自动执行 游戏物体 GameObject 上的 C# 组件代码 , 程序入口是 MonoBehaviour#Start() 函数 ; 在 C# 脚本中 , 主要的内容都在 Start() 函数 中实现 ; 在 C# 脚本中 , 游戏物体

    2023年04月12日
    浏览(82)
  • Unity上接入手柄,手柄控制游戏物体移动

    1、unity软件上安装system input 组件。菜单栏【window】-【Packag Manager】打开如下界面,查找Input System,并且安装。 2、安装成功后插入手柄到windows上,打开菜单栏上【window】--【Analysis】--【Input Debuger】 进入Input Debug界面,可以看到手柄设备能被Unity识别。 3、双击【XinputControllerW

    2024年04月15日
    浏览(48)
  • Unity 3D游戏开发+脚本编程完整指南:Unity脚本概览-控制物体的运动

    教程相关资源 Unity 3D游戏开发+脚本编程完整指南(工程文件+PPT).zip Unity 脚本概览 脚本编写并不困难,但是如果直接从细节开始讲起,会让 读者难以看到脚本编程的全貌。因此本章不急于阐述脚本编写 的细节,只介绍简单的修改物体位置、处理用户输入和检测碰 撞的方法

    2024年02月21日
    浏览(71)
  • Unity之获取游戏物体对象或组件的几个方法

    在unity的实际项目开发中,往往都要获取游戏内的各种物体,比如玩家(Player),怪物(Monster),或者其他,那有什么方法可以快速获取呢,下面就来介绍unity获取游戏对象的几个方法 GameObject.Find GameObject.Find 通过游戏物体的名称获取对象 使用方法 缺点: 会遍历当前整个场

    2024年02月01日
    浏览(41)
  • Unity切割图片:把一张图片中的物体裁成多个单独的游戏物体

    首先选中需要切割的图片素材,将Inspector面板中的 Sprite Mode 由默认的 Single改为Multiple ; 然后点击 Sprite Editor ; 第一步之后便会弹出下例面板,然后 点击Slice菜单 ,继续点击,便 会自动被分割好 ,最后 点击右上角的Apply 。 点击Apply后在右下角会弹出一个小的面板,你可以

    2024年02月05日
    浏览(40)
  • 十八、Unity游戏引擎入门

    1、下载     首先需要下载Unity Hub,下载网址:https://unity.com/cn。     然后在其中下载Unity编辑器并安装,可选择最新版本。     接着需要选择适合的开发环境,例如Android Studio或Xcode,以便进行手机游戏开发。在安装完Unity后,需要根据项目需求下载对应的模块和插件,例

    2024年02月16日
    浏览(73)
  • Unity3D:当频繁隐藏和显示游戏物体时,最优的处理方式

    首先说明一下处理的方法一般一共有3种 1.SetActive显示和隐藏物体【不推荐】 优:停止了Update和LateUpdate的性能消耗 劣:每一次显示会调用OnEnable,每一次隐藏会调用OnDisable 2.设置物体的位置,使物体移出摄像机的视野【不推荐】 优:相比较SetActive来说,没什么性能消耗 劣:

    2024年02月12日
    浏览(47)
  • 使用团结引擎开发Unity 3D射击游戏

           本案例是初级案例,意在引导想使用unity的初级开发者能较快的入门,体验unity开发的方便性和简易性能。       本次我们将使用团结引擎进行开发,帮助想体验团结引擎的入门开发者进行较快的环境熟悉。      本游戏是一个俯视角度的射击游戏。主角始终位于屏幕

    2024年01月19日
    浏览(72)
  • 19. Unity - 2D游戏开发小记02 --- 伪透视图、2D物体碰撞、瓦片地图碰撞、素材缩放平铺

    1. 伪视图 在2D游戏开发当中,当角色移动时,会发生物体与物体之间的前后遮挡。2D视图中的前后关系是由 Y 轴决定,y 值越小物体越靠前。unity的渲染应开启根据 y 值的大小进行渲染才能保证正确的遮挡效果,在菜单栏 Editor–project setting -- Graphic 中按照下图方式进行设置:

    2024年02月02日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包