unity 代码边缘发光_Shader案例之内发光和边缘泛光效果
![](/assets/blank.gif)
在很多游戏都可以看到这种效果,具体怎么去实现呢,其实超级简单。首先呢,我们先去把内发光的效果给做出了,然后再去实现外发光的效果。
1,我们最开始先实现一个显示再屏幕上的颜色:
pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"struct a2v{float4 vertex:POSITION;};struct v2f{float4 pos:SV_POSITION;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);return o;}fixed4 frag(v2f f):SV_TARGET{return fixed4(1,1,1,1);}
![](/assets/blank.gif)
2,我们可以使用视角方向和模型法线方向点积来分配颜色值,在这个球的最边缘的法线刚好和视角方向垂直,根据点积的几何意义我们可以知道,如果两个向量的角度等于90度,那么它的点积结果就为0,反之,角度等于0的点积结果为1,这样我们就可以得到一个以下的效果:
![](/assets/blank.gif)
pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;return o;}fixed4 frag(v2f f):SV_TARGET{//我们在世界空间下来计算向量fixed3 WorldNormal=normalize(f.Wnormal);//得到模型指向摄像机的方向fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);//我们用法线方向和视角方向的点乘来取到它们的点积值,//我们知道最边缘的法线和视角方向刚好垂直,两个垂直的向量的点积结果为0,//面对我们的法线和视角刚好重合在一起,方向也是一样的,那么结果为1,fixed bright=max(0,dot(WorldNormal,ViewDir));return fixed4(1,1,1,1)*bright;}ENDCG}
因为我们需要的是边缘发光,希望是中间是没有颜色的,颜色在旁边,所以我们可以把点积的结果进行1减操作,从而取反:
float bright=1.0-saturate(dot(WorldNormal,ViewDir));
![](/assets/blank.gif)
我们发现这并不是我们想要的效果,范围太大了,什么??范围太大了,第一个想到的肯定是我们可以利用平方去控制它的范围,好的,下面我们就去实现它:
Properties{_Scale("内发光范围控制",Range(1,8))=1}
//这个属性用来控制开方的次数float _Scale;
//我们在CGPROGRAM-ENDCG之间声明了它bright=pow(bright,_Scale);
//使用它
![](/assets/blank.gif)
3,我希望这个效果是中间透明的,边缘才有颜色:
//在Subshader里设置一下透明混合所需的标签
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType "="Transparent"}
//Pass中设置混合因子
Blend SrcAlpha OneMinusSrcAlpha
![](/assets/blank.gif)
不过混合纹理我们不需要开启透明,这个透明我们可以用外发光的上,让它看着有一种透明而且渐变的效果,所以我们只相加它的颜色,a通道还是用纹理的,现在得到了一个看起来不错的效果,我们需要把它和纹理叠加在一起:
Shader "01/1"{Properties{_Scale("内发光范围控制",Range(1,8))=1_MainTex("贴图1",2D)="white"{}}SubShader{Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType "="Transparent"}pass{Blend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"sampler2D _MainTex;float4 _MainTex_ST;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;float4 texcoord:TEXCOORD0;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;float2 uv:TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;return o;}float _Scale;fixed4 frag(v2f f):SV_TARGET{fixed4 texcolor=tex2D(_MainTex,f.uv);fixed3 WorldNormal=normalize(f.Wnormal);fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);fixed bright=1.0-max(0,dot(WorldNormal,ViewDir));bright=pow(bright,_Scale);fixed4 edge=fixed4(1,1,1,1)*bright;fixed3 AddColor=edge.rgb+texcolor.rgb;return fixed4(AddColor,texcolor.a);}ENDCG}}
}
![](/assets/blank.gif)
Properties{_Scale("内发光范围控制",Range(1,8))=1_MainTex("贴图1",2D)="white"{}_ScaleColor("内发光颜色",Color)=(1,1,1,1)}
//偷偷加上控制内发光颜色的属性
fixed4 edge=_ScaleColor*bright;
![](/assets/blank.gif)
4,接下来就该轮到我们的外发光效果了,实现方法也非常简单,利用另一个pass来渲染,我们可以复制第一个pass进行修改,我们先渲染内发光再渲染外扩,反过来也是一样的,不过第一种会比较节省性能,可以通过深度检测过滤掉很多描边绘制的像素,效率会更好。:
这是是这个shader的源代码,希望能够帮助到大家
Shader "01/1"{Properties{_Scale("内发光颜色范围控制",Range(1,8))=1_Scale2("外轮廓颜色范围控制",Range(1,8))=1_MainTex("贴图1",2D)="white"{}_ScaleColor("内发光颜色",Color)=(1,1,1,1)_ScaleColor2("外轮廓颜色",Color)=(1,1,1,1)_outline("轮廓范围",Range(0,1))=0.1}SubShader{Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType "="Transparent"}//外扩散发光pass{Blend SrcAlpha OneMinusSrcAlphaZWrite OffCGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"sampler2D _MainTex;fixed4 _ScaleColor;fixed4 _ScaleColor2;fixed _outline;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;};v2f vert(a2v v){v.vertex.xyz+=v.normal*_outline;v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;return o;}float _Scale;float _Scale2;fixed4 frag(v2f f):SV_TARGET{fixed3 WorldNormal=normalize(f.Wnormal);fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);fixed bright=max(0,dot(WorldNormal,ViewDir));bright=pow(bright,_Scale2);_ScaleColor2.a=_ScaleColor2.a*bright;return fixed4(_ScaleColor2);}ENDCG}//===============================================================================
//第2个pass,内发光pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "Unitycg.cginc"sampler2D _MainTex;float4 _MainTex_ST;fixed4 _ScaleColor;struct a2v{float4 vertex:POSITION;float3 normal:NORMAL;float4 texcoord:TEXCOORD0;};struct v2f{float4 pos:SV_POSITION;float3 Wnormal:TEXCOORD0;float3 Wvertex:TEXCOORD1;float2 uv:TEXCOORD2;};v2f vert(a2v v){v2f o;o.pos=UnityObjectToClipPos(v.vertex);o.Wnormal=UnityObjectToWorldNormal(v.normal);o.Wvertex=mul(unity_ObjectToWorld, v.vertex).xyz;o.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;return o;}float _Scale;fixed4 frag(v2f f):SV_TARGET{fixed4 texcolor=tex2D(_MainTex,f.uv);fixed3 WorldNormal=normalize(f.Wnormal);fixed3 ViewDir=normalize(_WorldSpaceCameraPos.xyz-f.Wvertex.xyz);fixed bright=1.0-max(0,dot(WorldNormal,ViewDir));bright=pow(bright,_Scale);fixed4 edge=_ScaleColor*bright;fixed3 AddColor=edge.rgb+texcolor.rgb;return fixed4(AddColor,texcolor.a);}ENDCG}}
}
最终效果:
![](/assets/blank.gif)
不嫌弃的话可以来群里一起交流学习,干货满满哟
![](/assets/blank.gif)
unity 代码边缘发光_Shader案例之内发光和边缘泛光效果相关推荐
- unity3d 不规则外发光描边_Shader案例之内发光和边缘泛光效果
在很多游戏都可以看到这种效果,具体怎么去实现呢,其实超级简单.首先呢,我们先去把内发光的效果给做出了,然后再去实现外发光的效果. 1,我们最开始先实现一个显示再屏幕上的颜色: pass{CGPROGR ...
- Unity UGUI开发设计及案例讲解
Unity--UGUI开发设计及案例讲解 1. Unity4.6跟以前的版本的最大区别首先在于在层级视图中点鼠标右键时出现的弹出菜单上,它把以前许多的菜单项进行了归类,比如cube sphere ca ...
- Shader Forge 入门学习(二) 实现发光、火焰燃烧、溶解、扭曲效果
引言:本篇博客主要记录ShaderForge的常用案例,包括外发光.火焰燃烧.溶解.扭曲等效果.由于内容较多会分成几篇博客记录.如果您对Shader Forge的常用操作还不熟悉,请先看 Unity3 ...
- 工业边缘计算技术实用案例分享
前言 当前,工厂自动化和过程自动化类型的工厂均使用边缘计算来捕获车间数据和处理任务的其他数据.工业边缘计算的应用也加速了Industrie 4.0业务模型的集成,带来了机器优化和生产率提高等好处. 本 ...
- dll放在unity哪个文件夹下_程序丨如何将你的Unity代码整理到一个DLL中?
原标题:程序丨如何将你的Unity代码整理到一个DLL中? 翻译:林政(玄猫大人) 审校:沈晓霖 代码复用的重要性 这里有一则故事也是你听过类似的: 你下载好Unity,看完Youtube上的一些教程 ...
- 帧差法matlab代码_【游戏流体力学基础及Unity代码(一)】热传导方程
在游戏中模拟流体并不是什么新鲜事,但是我几乎就没看到什么好的入门文章.有些文章用尖峰波或者FFT模拟,但那毕竟是统计学方法,和流体力学还是不搭边.其余的文章倒是用了纳韦斯托克方程,但那也仅仅是把纳韦斯 ...
- qt 模拟鼠标滑轮_【游戏流体力学基础及Unity代码(四)】用欧拉方程模拟无粘性染料之公式推导...
先放一张动态图吊一下胃口~下面就是最终的效果 不可压缩的欧拉方程只比NS方程少一个粘性项.所以下面的内容是完全适合NS方程的.各位请准备好! 散度定理 模拟流体的时候会遇到许多数学公式.为了深刻理解这 ...
- Unity 代码修改宏名并一键打包
Unity 代码修改宏名并一键打包 Unity3d 项目开发切换平台与发布版本时,不同的平台,不同的版本,可能会有不同的实现方式,这样就需要宏去控制调用,执行需要在该平台的逻辑操作.其中Unity内部 ...
- Unity代码调用网络摄像头WebCamTexture
Unity代码调用网络摄像头WebCamTexture 初始代码 后续功能&代码更新 注意事项 初始代码 编辑器模式或Android环境和实机测试都没有问题. using System.Col ...
最新文章
- 服务器何时取得客户端信息,HttpRequest获得服务端和客户端的详细信息
- 2017.4.2号总结
- 特质波动率python
- win10 应用程序 快捷启动
- python2好还是python3好-总结对比Python2和Python3之间的区别
- 燕京理工学院java期末_英华学堂燕京理工学院的答案
- C++三大继承与多级派生
- python 目录 文件名_python目录与文件名操作
- 浅谈android中的自定义封装易用的Dialog
- python 读取excel失败 可以转换成csv文件
- linux离线安装docx包
- NVIDIA Nsight Compute,Nsight Systems, Nsight Graphics,Nsight Deep Learning Designer简介-草稿
- kuangbin字典树
- 猫途鹰联手携程集团打造面向中国出境旅行者的顶级旅行平台
- 老路《用得上的商学课》学习开篇(自序)
- JavaScript中的数组方法总结+详解
- 如何提高Python编程能力?
- 微信公众号页面开发记录
- L2-3 清点代码库【STL】
- linux三剑客-sed命令的学习笔记