当前位置:   article > 正文

Unity Shader 入门精要——渐变纹理_unity shader graph wen'li渐变

unity shader graph wen'li渐变

效果图:

 代码:

  1. Shader "CustomShader/Texture/RampShader"
  2. {
  3. Properties
  4. {
  5. _RampTex ("Texture", 2D) = "white" {}
  6. _Color ("Color Tint", Color) = (1, 1, 1, 1)
  7. _Specular ("Specular", Color) = (1, 1, 1, 1)
  8. _Gloss ("Gloss", Range(8.0, 256)) = 20
  9. }
  10. SubShader
  11. {
  12. Pass
  13. {
  14. Tags {"LightMode" = "ForwardBase"}
  15. CGPROGRAM
  16. #pragma vertex vert
  17. #pragma fragment frag
  18. #include "Lighting.cginc"
  19. sampler2D _RampTex; //渐变纹理
  20. float4 _RampTex_ST; //纹理属性变量
  21. fixed4 _Color;
  22. fixed4 _Specular;
  23. float _Gloss;
  24. struct appdata
  25. {
  26. float4 vertex : POSITION;
  27. float2 uv : TEXCOORD0;
  28. float3 normal : NORMAL;
  29. };
  30. struct v2f
  31. {
  32. float2 uv : TEXCOORD0;
  33. float4 vertex : SV_POSITION;
  34. float3 worldPos : TEXCOORD1;
  35. float3 worldNormal : TEXCOORD2;
  36. };
  37. v2f vert (appdata v)
  38. {
  39. v2f o;
  40. o.vertex = UnityObjectToClipPos(v.vertex);
  41. //内置宏TRANSFORM_TEX计算经过平铺和偏移后的纹理坐标
  42. o.uv = TRANSFORM_TEX(v.uv, _RampTex);
  43. o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  44. o.worldNormal = UnityObjectToWorldNormal(v.normal);
  45. return o;
  46. }
  47. fixed4 frag (v2f i) : SV_Target
  48. {
  49. fixed3 worldNormal = normalize(i.worldNormal);
  50. fixed3 lightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
  51. fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
  52. fixed halfLambert = dot(worldNormal, lightDir) * 0.5 + 0.5;
  53. fixed3 color = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;
  54. fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
  55. fixed3 diffuse = _LightColor0.rgb * color;
  56. fixed3 halfDir = normalize(viewDir + lightDir);
  57. fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);
  58. return fixed4(ambient + diffuse + specular, 1.0);
  59. }
  60. ENDCG
  61. }
  62. }
  63. FallBack "Specular"
  64. }

在片段着色器中使用半兰伯特光照模型:

  1. fixed halfLambert = dot(worldNormal, lightDir) * 0.5 + 0.5;
  2. fixed3 color = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;

在上面的代码中,通过对法线方向和光照方向的点积做一次0.5倍的缩放以及一个0.5大小的偏移来计算半兰伯特部分halfLambert。这样,我们得到的halfLambert 的范围被映射到了[0,1]之间。之后,我们使用halfLambert 来构建一个纹理坐标,并用这个纹理坐标对渐变纹理_RampTex进行采样。由于_RampTex实际就是一个一维纹理(它在纵轴方向上颜色不变),因此纹理坐标的u和v方向我们都使用了halfLambert。 然后,把从渐变纹理采样得到的颜色和材质颜色Color相乘,得到最终的漫反射颜色。剩下的代码就是计算高光反射和环境光,并把它们的结果进行相加。

fixed2(halfLambert, halfLambert) 这句其实我们只关心其x坐标,y坐标没意义。那么halfLambert为什么可以与纹理坐标联系起来呢,我们从漫反射的公式中看出,法线与光照方向的夹角决定了光照系数,夹角越小,光照系数越大,漫反射越强,反之,系数越小,漫反射越弱,那么我们用渐变纹理的x轴表示其系数变化,x轴也就是系数越小,就采样越黑的颜色,表示漫反射越弱,系数越大也就是x越大,就采样越白的颜色,表示漫反射越强,所以我们的渐变纹理是从左到右从黑到白,就是这个原理。
————————————————
版权声明:本文为CSDN博主「Aimar_Johnny」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lzhq1982/article/details/77659332

需要注意的是,我们需要把渐变纹理的Wrap Mode 设为Clamp模式,以防止对纹理进行采样时由于浮点数精度而造成的问题。

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

闽ICP备14008679号