NewUnlitShader.shader 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
  2. // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
  3. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  4. //边缘发光Shader
  5. //by:puppet_master
  6. //2016.12.11
  7. Shader "ApcShader/RimLight"
  8. {
  9. //属性
  10. Properties{
  11. _Diffuse("Diffuse", Color) = (1,1,1,1)
  12. _RimColor("RimColor", Color) = (1,1,1,1)
  13. _RimPower("RimPower", Range(0.0001, 3.0)) = 0.1
  14. _MainTex("Base 2D", 2D) = "white"{}
  15. }
  16. //子着色器
  17. SubShader
  18. {
  19. Pass
  20. {
  21. //定义Tags
  22. Tags{ "RenderType" = "Opaque" }
  23. CGPROGRAM
  24. //引入头文件
  25. #include "Lighting.cginc"
  26. //定义Properties中的变量
  27. fixed4 _Diffuse;
  28. sampler2D _MainTex;
  29. //使用了TRANSFROM_TEX宏就需要定义XXX_ST
  30. float4 _MainTex_ST;
  31. fixed4 _RimColor;
  32. float _RimPower;
  33. //定义结构体:vertex shader阶段输出的内容
  34. struct v2f
  35. {
  36. float4 pos : SV_POSITION;
  37. float3 worldNormal : TEXCOORD0;
  38. float2 uv : TEXCOORD1;
  39. //在vertex shader中计算观察方向传递给fragment shader
  40. float3 worldViewDir : TEXCOORD2;
  41. };
  42. //定义顶点shader,参数直接使用appdata_base(包含position, noramal, texcoord)
  43. v2f vert(appdata_base v)
  44. {
  45. v2f o;
  46. o.pos = UnityObjectToClipPos(v.vertex);
  47. //通过TRANSFORM_TEX宏转化纹理坐标,主要处理了Offset和Tiling的改变,默认时等同于o.uv = v.texcoord.xy;
  48. o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  49. o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
  50. //顶点转化到世界空间
  51. float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  52. //可以把计算计算ViewDir的操作放在vertex shader阶段,毕竟逐顶点计算比较省
  53. o.worldViewDir = _WorldSpaceCameraPos.xyz - worldPos;
  54. return o;
  55. }
  56. //定义片元shader
  57. fixed4 frag(v2f i) : SV_Target
  58. {
  59. //unity自身的diffuse也是带了环境光,这里我们也增加一下环境光
  60. fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _Diffuse.xyz;
  61. //归一化法线,即使在vert归一化也不行,从vert到frag阶段有差值处理,传入的法线方向并不是vertex shader直接传出的
  62. fixed3 worldNormal = normalize(i.worldNormal);
  63. //把光照方向归一化
  64. fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
  65. //根据半兰伯特模型计算像素的光照信息
  66. fixed3 lambert = 0.5 * dot(worldNormal, worldLightDir) + 0.5;
  67. //最终输出颜色为lambert光强*材质diffuse颜色*光颜色
  68. fixed3 diffuse = lambert * _Diffuse.xyz * _LightColor0.xyz + ambient;
  69. //进行纹理采样
  70. fixed4 color = tex2D(_MainTex, i.uv);
  71. //以下为本篇主题:计算RimLight
  72. //把视线方向归一化
  73. float3 worldViewDir = normalize(i.worldViewDir);
  74. //计算视线方向与法线方向的夹角,夹角越大,dot值越接近0,说明视线方向越偏离该点,也就是平视,该点越接近边缘
  75. float rim = 1 - max(0, dot(worldViewDir, worldNormal));
  76. //计算rimLight
  77. fixed3 rimColor = _RimColor * pow(rim, 1 / _RimPower);
  78. //输出颜色+边缘光颜色
  79. color.rgb = color.rgb * diffuse + rimColor;
  80. return fixed4(color);
  81. }
  82. //使用vert函数和frag函数
  83. #pragma vertex vert
  84. #pragma fragment frag
  85. ENDCG
  86. }
  87. }
  88. //前面的Shader失效的话,使用默认的Diffuse
  89. FallBack "Diffuse"
  90. }