Shader实例(流光实现)

流光效果

首先来看一下流光效果。流光效果是一个非常常见的效果,不仅仅是游戏,一些广告之类的也都会有这种效果。流光的原理还是比较简单的:首先就是需要一张流光图,这张流光图的大部分都是黑色,然后有一条亮线,然后我们在采样的时候,最终输出叠加上这张图的采样值,并根据时间调整采样的UV就可以有流光的效果啦。下面是一个比较简单的流光效果实现:

下面看属性参数:
接下来是SubShader中的一些参数定义
顶点函数处理
光照处理
以上是对于2D图像常用的流光实现方式,如果是3D物体用这种方式的话,可能会出现问题,所以对于3D物体,采用按照物体的世界坐标按时间偏移查询纹理贴图就行了
具体参数按需求改下就好了

按照方向消失或重现效果

我们再来看一个用模型空间坐标作为采样的uv的栗子,也是一种比较好玩的效果。比如我们需要一个模型身体按照一定的方向逐渐消失,直至全部消失掉的一个效果。下面说一下思路,与世界空间采样的流光效果一样,我们在vertex阶段记录一下vertex坐标,传递给fragment阶段,在fragment阶段用这个值和一个设定好的阈值进行比较,不满足条件的像素点直接discard,逐渐调整阈值,就可以得到让模型按照某个方向消失的效果了。代码如下:
[csharp] view plain copy
  1. //按照方向消失的效果
  2. //by:CJB_King
  3. //2017.12.23
  4. Shader "SelfShader/DissolveEffectX"
  5. {
  6. Properties
  7. {
  8. _MainTex("MainTex(RGB)", 2D) = "white" {}
  9. _DissolveVector("DissolveVector", Vector) = (0,0,0,0)
  10. }
  11. CGINCLUDE
  12. #include "Lighting.cginc"
  13. uniform sampler2D _MainTex;
  14. uniform float4 _MainTex_ST;
  15. uniform float4 _DissolveVector;
  16. struct v2f
  17. {
  18. float4 pos : SV_POSITION;
  19. float3 worldNormal : NORMAL;
  20. float2 uv : TEXCOORD0;
  21. float3 worldLight : TEXCOORD1;
  22. float4 objPos : TEXCOORD2;
  23. };
  24. v2f vert(appdata_base v)
  25. {
  26. v2f o;
  27. o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
  28. o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  29. //顶点转化到世界空间
  30. o.objPos = v.vertex;
  31. o.worldNormal = UnityObjectToWorldNormal(v.normal);
  32. o.worldLight = UnityObjectToWorldDir(_WorldSpaceLightPos0.xyz);
  33. return o;
  34. }
  35. fixed4 frag(v2f i) : SV_Target
  36. {
  37. half3 normal = normalize(i.worldNormal);
  38. half3 light = normalize(i.worldLight);
  39. fixed diff = max(0, dot(normal, light));
  40. fixed4 albedo = tex2D(_MainTex, i.uv);
  41. //不满足条件的discard
  42. clip(i.objPos.xyz - _DissolveVector.xyz);
  43. fixed4 c;
  44. c.rgb = diff * albedo;
  45. c.a = 1;
  46. return c;
  47. }
  48. ENDCG
  49. SubShader
  50. {
  51. Pass
  52. {
  53. Tags{ "RenderType" = "Opaque" }
  54. CGPROGRAM
  55. #pragma vertex vert
  56. #pragma fragment frag
  57. ENDCG
  58. }
  59. }
  60. FallBack "Diffuse"
  61. }
还有一个小问题,其实上图中的例子里面,模型从上到下,理想情况应该是调整Y轴,不过例子里面调整的确实X轴,原因应该与Unity导入之后会绕着X轴旋转90度有关,也就是原本在max里面的Y轴变成Unity里面的X轴。
下面,我们再看一下增加了边缘高亮的消失效果,为了让模消失的型边缘高亮,我们通过将用于clip的factor值与另一个高亮阈值值进行比较,如果factor小于高亮阈值,则返回一个高亮的颜色值,否则正常渲染。这样模型就总共有三种显示状态:clip状态,高亮状态,正常状态。代码如下:
[csharp] view plain copy
  1. //消失效果
  2. //by:CJB_King
  3. //2017.12.23
  4. Shader "SelfShader/DissolveEffectX"
  5. {
  6. Properties{
  7. _Diffuse("Diffuse", Color) = (1,1,1,1)
  8. _DissolveColor("Dissolve Color", Color) = (0,0,0,0)
  9. _MainTex("Base 2D", 2D) = "white"{}
  10. _ColorFactor("ColorFactor", Range(0,1)) = 0.7
  11. _DissolveThreshold("DissolveThreshold", Float) = 0
  12. }
  13. CGINCLUDE
  14. #include "Lighting.cginc"
  15. uniform fixed4 _Diffuse;
  16. uniform fixed4 _DissolveColor;
  17. uniform sampler2D _MainTex;
  18. uniform float4 _MainTex_ST;
  19. uniform float _ColorFactor;
  20. uniform float _DissolveThreshold;
  21. struct v2f
  22. {
  23. float4 pos : SV_POSITION;
  24. float3 worldNormal : TEXCOORD0;
  25. float2 uv : TEXCOORD1;
  26. float4 objPos : TEXCOORD2;
  27. };
  28. v2f vert(appdata_base v)
  29. {
  30. v2f o;
  31. o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
  32. o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  33. o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
  34. o.objPos = v.vertex;
  35. return o;
  36. }
  37. fixed4 frag(v2f i) : SV_Target
  38. {
  39. float factor = i.objPos.x - _DissolveThreshold;
  40. clip(factor);
  41. //Diffuse + Ambient光照计算
  42. fixed3 worldNormal = normalize(i.worldNormal);
  43. fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
  44. fixed3 lambert = saturate(dot(worldNormal, worldLightDir));
  45. fixed3 albedo = lambert * _Diffuse.xyz * _LightColor0.xyz + UNITY_LIGHTMODEL_AMBIENT.xyz;
  46. fixed3 color = tex2D(_MainTex, i.uv).rgb * albedo;
  47. //等价于下面注释代码的操作
  48. fixed lerpFactor = saturate(sign(_ColorFactor - factor));
  49. return lerpFactor * _DissolveColor + (1 - lerpFactor) * fixed4(color, 1);
  50. /*
  51. if (factor < _ColorFactor)
  52. {
  53. return _DissolveColor;
  54. }
  55. return fixed4(color, 1);*/
  56. }
  57. ENDCG
  58. SubShader
  59. {
  60. Tags{ "RenderType" = "Opaque" }
  61. Pass
  62. {
  63. //不让模型穿帮,关掉了背面裁剪
  64. Cull Off
  65. CGPROGRAM
  66. #pragma vertex vert
  67. #pragma fragment frag
  68. ENDCG
  69. }
  70. }
  71. FallBack "Diffuse"
  72. }

溶解效果进阶版

之前的文章里,我们研究过溶解效果,不过这个效果是基于全身的,我们来尝试一下,把上面按照方向消失的效果与溶解效果结合起来,做成一个按照某个方向逐渐溶解的效果。要得到随机的溶解效果,我们需要采样一张噪声图,然后在原本会直接clip掉的部分根据采样的噪声图进行clip,就能得到按照方向的溶解效果啦。
[csharp] view plain copy
  1. //溶解效果
  2. //by:CJB_King
  3. //2017.12.23
  4. Shader "SelfShader/DissolveEffectX"
  5. {
  6. Properties{
  7. _Diffuse("Diffuse", Color) = (1,1,1,1)
  8. _DissolveColor("Dissolve Color", Color) = (1,1,1,1)
  9. _MainTex("Base 2D", 2D) = "white"{}
  10. _DissolveMap("DissolveMap", 2D) = "white"{}
  11. _DissolveThreshold("DissolveThreshold", Range(0,1)) = 0
  12. _DissolveSpeedFactor("DissolveSpeed", Range(0,5)) = 2
  13. _DissolveControl("ColorFactorB", Float) = 0
  14. }
  15. CGINCLUDE
  16. #include "Lighting.cginc"
  17. uniform fixed4 _Diffuse;
  18. uniform fixed4 _DissolveColor;
  19. uniform sampler2D _MainTex;
  20. uniform float4 _MainTex_ST;
  21. uniform sampler2D _DissolveMap;
  22. uniform float _DissolveThreshold;
  23. uniform float _DissolveSpeedFactor;
  24. uniform float _DissolveControl;
  25. struct v2f
  26. {
  27. float4 pos : SV_POSITION;
  28. float3 worldNormal : TEXCOORD0;
  29. float2 uv : TEXCOORD1;
  30. float4 objPos : TEXCOORD2;
  31. };
  32. v2f vert(appdata_base v)
  33. {
  34. v2f o;
  35. o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
  36. o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  37. o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
  38. o.objPos = v.vertex;
  39. return o;
  40. }
  41. fixed4 frag(v2f i) : SV_Target
  42. {
  43. fixed4 dissolve = tex2D(_DissolveMap, i.uv);
  44. //Diffuse + Ambient光照计算
  45. fixed3 worldNormal = normalize(i.worldNormal);
  46. fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
  47. fixed3 lambert = saturate(dot(worldNormal, worldLightDir));
  48. fixed3 albedo = lambert * _Diffuse.xyz * _LightColor0.xyz + UNITY_LIGHTMODEL_AMBIENT.xyz;
  49. fixed3 color = tex2D(_MainTex, i.uv).rgb * albedo;
  50. float factor = i.objPos.x - _DissolveControl;
  51. if(factor < 0)
  52. {
  53. clip(_DissolveThreshold - dissolve.r * abs(factor) * _DissolveSpeedFactor);
  54. }
  55. return fixed4(color, 1);
  56. }
  57. ENDCG
  58. SubShader
  59. {
  60. Tags{ "RenderType" = "Opaque" }
  61. Pass
  62. {
  63. Cull Off
  64. CGPROGRAM
  65. #pragma vertex vert
  66. #pragma fragment frag
  67. ENDCG
  68. }
  69. }
  70. FallBack "Diffuse"
  71. }

Shader "SelfShader/Dissolve"
{Properties{_MainColor("MainColor",COLOR)=(1,1,1,1)_MainTex ("Texture", 2D) = "white" {}_Noise("Noise",2D)="white"{}_Dissolve("Dissolve",Vector)=(0.2,0.5,0.8)_DissolveThread("DissolveThread",float)=0.2_DissolveColor("DissolveColor",COLOR)=(1,1,1,1)_DissolveColFactor("_DissolveColFactor",float)=2_FlyFactor("FlyFactor",float)=3}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"#include "Lighting.cginc"struct a2v{float4 vertex : POSITION;float2 uv : TEXCOORD0;fixed3 normal:NORMAL;};struct v2f{float2 uv : TEXCOORD0;float4 pos : SV_POSITION;fixed3 worldNormal:TEXCOORD1;fixed3 worldPos:TEXCOORD2;fixed3 objPos:TEXCOORD3;};sampler2D _Noise;sampler2D _MainTex;float4 _MainTex_ST;fixed4 _MainColor;fixed4 _Dissolve;float _DissolveThread;fixed4 _DissolveColor;float _DissolveColFactor;float _FlyFactor;v2f vert (a2v v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldPos=mul((float3x3)unity_ObjectToWorld,v.vertex);o.worldNormal=UnityObjectToWorldNormal(v.normal);o.objPos=v.vertex;o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.pos.xyz+=v.normal*saturate(_DissolveThread-_FlyFactor)*_FlyFactor;return o;}fixed4 frag (v2f i) : SV_Target{fixed3 worldNor=normalize(i.worldNormal);fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz);fixed4 albedo = tex2D(_MainTex, i.uv)*_MainColor;fixed4 noiseColor=tex2D(_Noise,i.uv);float factor=noiseColor.r-_DissolveThread;clip(factor);fixed3 ambient=UNITY_LIGHTMODEL_AMBIENT.xyz*albedo.rgb;fixed3 diffuse=_LightColor0.rgb*albedo.rgb*(0.5*dot(lightDir,worldNor)+0.5);float lerpFactor=saturate(sign(_DissolveColFactor-factor));return lerp(fixed4(ambient+diffuse,1),_DissolveColor,lerpFactor);}ENDCG}}
}

Shader实例(流光实现)相关推荐

  1. android 4实例分析,OpenGL Shader实例分析(4)闪光效果

    本文实例为大家分享了opengl shader实例闪光效果的具体代码,供大家参考,具体内容如下 在游戏中,当战斗结束后,对一些获取的宝贝需要进行闪光处理.这篇文章介绍一个进行闪光处理的shader,运 ...

  2. shader实例:实现类似宝可梦 Pokemon 的战斗转场

    宝可梦游戏在进入战斗前会有类似这样转场动画. 例子中使用的纹理质量较差,边缘比较模糊,和shader无关. 这个UI是盖在所有UI最前面的.可以使用shader来完成这个工作,而不是复杂的动画. 使用 ...

  3. android雪花飘落效果,【OpenGL】Shader实例分析(七)- 雪花飘落效果

    研究了一个雪花飘落效果.感觉挺不错的.分享给大家,效果例如以下: 代码例如以下: Shader "shadertoy/Flakes" { // https://www.shader ...

  4. Shader实例:Planar Reflection 平面反射

    目前采用比较多的反射,最终效果示例: 代码已经中文注解,有2部分需扩展:反射矩阵.歪截头体矩阵.注解中有来源链接可以去理解推导过程. 可用于镜面和水面. 咱还是直接看注解过的代码 MirrorRefl ...

  5. android+动态光圈效果,OpenGL Shader实例分析(8)彩色光圈效果

    本文实例为大家分享了opengl实现彩色光圈效果的具体代码,供大家参考,具体内容如下 研究了一个彩色光圈效果,感觉挺不错的,分享给大家,效果如下: 代码如下: shader "shadert ...

  6. D3D9 Shader实例教程

    啥是Shader? Shader是一段运行在GPU上的小程序,是运行在GPU上的Pipeline上的特定的可编程单元的小程序. 从D3D9 API层面学习Shader编程 随着Unity3D的流行,很 ...

  7. Three 自定义着色器Shader实例

    基础环境搭建: camera = new THREE.OrthographicCamera(-10, 10, 10, -10, 0, 100)camera.position.set(0, 0, 10) ...

  8. OpenGL Blinn-Phong Shader实例

    OpenGL blinnphong 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <vmath.h> #include <sh ...

  9. unity描边发光shader_unity shader实例#1 轮廓渲染-描边

    本文主要来讲几种描边的实现方法 1.法线外扩 一般期望的描边效果,就是在模型外面有一圈选边,因此我们可以把模型扩大一点点,利用这个扩大的边缘来实现描边效果.可以看出,扩大的方向其实就是法线的方向,边缘 ...

最新文章

  1. 怎么把一个控件放到tab页面上去?_移动端页面内容切换
  2. C#将图片白色背景设置为透明
  3. Git 分支管理 Feature分支 强行删除分支
  4. linux php imagick 扩展安装,linux下为php5.3安装Imagick扩展
  5. jQuery操作示例
  6. SimpleDateFormat 线程不安全及解决方案
  7. python基础(1)——简介与安装
  8. Select2使用经验及多Jquery版本处理
  9. Mugeda(木疙瘩)H5案例课—教你做魔性H5弹幕-岑远科-专题视频课程
  10. android cursor循环,Android:Cursor.getColumnIndex()在行循环中是不变的吗?
  11. day13_spring环境配置及bean使用
  12. 和平精英服务器响应超时什么意思,和平精英服务器无响应,和平精英服务器超时...
  13. Maven学习——maven基础
  14. 关于CSDN博客域名
  15. Linux获取最后一个参数(参数统计)
  16. 最新源码交易网系统HTML源码(可商用)
  17. Python进阶(三十三)Python获取并输出当前日期时间
  18. VST3主机开发(二)——插件调用
  19. C语言 用空格作判断,C语言菜鸟基础教程之判断
  20. Ubuntu16.04网络配置

热门文章

  1. Git使用方法(将本地文件上传到github远程仓库)
  2. supesite 模板标签详解!
  3. golang大厂面试2
  4. 假装Python高手,把类这样改,真刺激!
  5. windows脚本记录端口访问日志
  6. JSON增删改查学习笔记
  7. 科研双十一,带你系统学习药物设计,快来看吧
  8. np.linspace() 函数用法
  9. BOS初级开发培训认证
  10. 苹果原壁纸高清_119期 | 欧美经典电影拼接壁纸