当前位置:   article > 正文

【Unity Shader】纹理实践4.0:简单尝试渐变纹理和遮罩纹理_unity 遮罩变化特效

unity 遮罩变化特效

写在前面

由于我还是处于刚刚入门(其实还是小菜鸡...)的阶段,关于渐变纹理目前主要是学习一下如何通过渐变纹理控制漫反射光照。

这种用渐变纹理控制颜色效果的想法,是Valve公司(提出半兰伯特光照技术的公司)他们提出来的,主要想要用来渲染游戏中具有卡通、插画风格的效果。

原理部分真得不想说太多了,其实本来想借着ramp纹理的功夫深扒一扒从Team Fortress 2开始到现在的应用过程,顺藤摸瓜偶遇了Toon Shader,突然醒悟——Ramp纹理原来只是卡通渲染这块大蛋糕上的小小一隅,立刻放弃要深究的念头,打算打牢基础再说!

关于遮罩纹理:遮罩纹理(mask texture)能做的事情有很多,这次仅作纯粹的记录用它来控制高光的使用效果。

存一些发现的比较有意思的帖子,后续再回来看:

Blender Toon Shader教程跟做(通用Shader) - 知乎 (zhihu.com)

Unity Toon Shader 卡通着色器(一):卡通着色_Sorumi的博客-CSDN博客

[译] 实现Unity 后处理特效 (3) _渐变 Ramp - 知乎 (zhihu.com)  


1 渐变纹理

1.1 Shader代码展示

  1. Shader "Unity Shaders Book/Chapter 7/Ramp Texture"
  2. {
  3. Properties
  4. {
  5. _Color ("Color", Color) = (1, 1, 1, 1)
  6. _Specular ("Specular", Color) = (1, 1, 1, 1)
  7. _Gloss ("Gloss", Range(8.0, 256)) = 20
  8. _RampTex ("RampTex", 2D) = "white" {}
  9. }
  10. SubShader
  11. {
  12. Tags { "LightMode" = "ForwardBase" }
  13. Pass
  14. {
  15. CGPROGRAM
  16. #pragma vertex vert
  17. #pragma fragment frag
  18. #include "Lighting.cginc"
  19. sampler2D _RampTex;
  20. float4 _RampTex_ST;
  21. fixed3 _Color;
  22. fixed3 _Specular;
  23. float _Gloss;
  24. struct a2v
  25. {
  26. float4 vertex : POSITION;
  27. float3 normal : NORMAL;
  28. float2 texcoord : TEXCOORD0;
  29. };
  30. struct v2f
  31. {
  32. float2 uv : TEXCOORD0;
  33. float4 pos : SV_POSITION;
  34. float3 worldNormal : TEXCOORD1;
  35. float3 worldPos : TEXCOORD2;
  36. };
  37. v2f vert (a2v v)
  38. {
  39. v2f o;
  40. o.pos = UnityObjectToClipPos(v.vertex);
  41. o.uv = TRANSFORM_TEX(v.texcoord, _RampTex); //重点1
  42. o.worldNormal = UnityObjectToWorldNormal(v.normal);
  43. o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  44. return o;
  45. }
  46. fixed4 frag (v2f i) : SV_Target
  47. {
  48. fixed3 worldNormal = normalize(i.worldNormal);
  49. fixed3 worldlightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
  50. fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
  51. fixed3 halfDir = normalize(worldlightDir + viewDir);
  52. fixed3 specular = _LightColor0.rgb * _Specular * pow(saturate(dot(halfDir, worldNormal)), _Gloss);
  53. fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
  54. //计算半兰伯特的值
  55. fixed halfLambert = dot(worldNormal, worldlightDir) * 0.5 + 0.5;
  56. //用半兰伯特去采样这个一级纹理,y方向上不会改变
  57. fixed3 diffuseColor = tex2D(_RampTex, float2(halfLambert, halfLambert)).rgb * _Color;
  58. fixed3 diffuse = _LightColor0.rgb * diffuseColor * diffuseColor;
  59. return fixed4(diffuse + specular + ambient, 1.0);
  60. }
  61. ENDCG
  62. }
  63. }
  64. FallBack "Specular"
  65. }

1.2 效果展示

渐变纹理分别为:

Game视图中的渲染效果:

2 遮罩纹理

2.1 Shader代码展示

  1. Shader "Unity Shaders Book/Chapter 7/Mask Texture2"
  2. {
  3. Properties
  4. {
  5. _Color ("Color", Color) = (1, 1, 1, 1)
  6. _Specular ("Specular", Color) = (1, 1, 1, 1)
  7. _Gloss ("Gloss", Range(8.0, 256)) = 20
  8. _MainTex ("MainTex", 2D) = "white" {}
  9. _SpecularMask ("SpecularMask", 2D) = "white" {}
  10. _SpecularScale ("SpecualrScale", float) = 1
  11. _NormalTex ("NormalTex", 2D) = "bump" {}
  12. _NormalScale ("NormalScale", Range(-1.0, 1.0)) = 1
  13. }
  14. SubShader
  15. {
  16. Tags { "LightMode" = "ForwardBase" }
  17. Pass
  18. {
  19. CGPROGRAM
  20. #pragma vertex vert
  21. #pragma fragment frag
  22. #include "Lighting.cginc"
  23. fixed4 _Color;
  24. fixed4 _Specular;
  25. float _Gloss;
  26. sampler2D _MainTex;
  27. sampler2D _SpecularMask;
  28. float _SpecularScale;
  29. sampler2D _NormalTex;
  30. float _NormalScale;
  31. float4 _MainTex_ST;
  32. struct a2v
  33. {
  34. float4 vertex : POSITION;
  35. float3 normal : NORMAL;
  36. float2 texcoord : TEXCOORD0;
  37. float4 tangent : TANGENT;
  38. };
  39. struct v2f
  40. {
  41. float2 uv : TEXCOORD0;
  42. float4 pos : SV_POSITION;
  43. float3 lightDir : TEXCOORD1;
  44. float3 viewDir : TEXCOORD2;
  45. };
  46. v2f vert (a2v v)
  47. {
  48. v2f o;
  49. o.pos = UnityObjectToClipPos(v.vertex);
  50. o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  51. TANGENT_SPACE_ROTATION; //获得rotation
  52. o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex)).xyz;
  53. o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex)).xyz;
  54. return o;
  55. }
  56. fixed4 frag (v2f i) : SV_Target
  57. {
  58. fixed3 lightDir = normalize(i.lightDir);
  59. fixed3 viewDir = normalize(i.viewDir);
  60. fixed3 halfDir = normalize(lightDir + viewDir);
  61. fixed3 tangentNormal = UnpackNormal(tex2D(_NormalTex, i.uv));
  62. tangentNormal.xy *= _NormalScale;
  63. tangentNormal.z = sqrt(1 - saturate(dot(tangentNormal.xy, tangentNormal.xy)));
  64. fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
  65. fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo;
  66. fixed halfLambert = dot(tangentNormal, lightDir) * 0.5 + 0.5;
  67. fixed3 diffuse = _LightColor0.rgb * albedo * halfLambert;
  68. fixed specularMask = tex2D(_SpecularMask, i.uv).r * _SpecularScale;
  69. fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(halfDir, tangentNormal)), _Gloss) * specularMask * albedo;
  70. fixed3 specular2 = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(halfDir, tangentNormal)), _Gloss);
  71. return fixed4(diffuse + specular + ambient, 1.0);
  72. }
  73. ENDCG
  74. }
  75. }
  76. FallBack "Specular"
  77. }

2.2 材质面板

需要加入漫反射纹理、法线纹理以及用到的高光遮罩纹理。

2.3 效果展示

(仅用了半兰伯特)中间(漫反射+高光无遮罩)右边(漫反射+高光有遮罩)

从效果看明显右边更接近实际~中间的高光太水亮、太假,左边直接无高光好像少了点什么。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/107250
推荐阅读
相关标签
  

闽ICP备14008679号