当前位置:   article > 正文

UnityShader实现较为完整的光照模型(Lambert+Phong+三色环境光+阴影+环境遮蔽(AO))_unity模拟环境光遮罩

unity模拟环境光遮罩

此篇文章为庄懂技术美术课程学习笔记。

首先一个基本光照的组成可以是以下这些

在这里插入图片描述

将这些光分别组合就可以得到一个较好的光照模型

AO(环境遮蔽)是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光、飘和阴影不实等问题,解决或改善场景中缝隙、角线以及细小物体等的表现不清晰问题,综合改善细节尤其是暗部阴影,增强空间的层次感、真实感,同时加强和改善画面明暗对比,增强画面的艺术性。

Lambert+Phong的实现思路在之前的文章中都有过说明,这里就不在重复。

三色环境光实现的核心思路:

法线的G通道是顶光,将其乘上-1就是底光,再用1减去顶光和底光,就是剩余的四周的环境光。

投影调用的方法:

在这里插入图片描述

 连连看部分

先是连连看部分的实现

在这里插入图片描述

代码部分

接着是代码部分的实现

  1. Shader "AP01/L08/OldSchoolPlus" {
  2. Properties {
  3. _BaseCol ("基本色", Color) = (0.5, 0.5, 0.5, 1.0)
  4. _LightCol ("光颜色", Color) = (1.0, 1.0, 1.0, 1.0)
  5. _SpecPow ("高光次幂", Range(1, 90)) = 30
  6. _Occlusion ("AO图", 2D) = "white" {}
  7. _EnvInt ("环境光强度", Range(0, 1)) = 0.2
  8. _EnvUpCol ("环境天顶颜色", Color) = (1.0, 1.0, 1.0, 1.0)
  9. _EnvSideCol ("环境水平颜色", Color) = (0.5, 0.5, 0.5, 1.0)
  10. _EnvDownCol ("环境地表颜色", Color) = (0.0, 0.0, 0.0, 0.0)
  11. }
  12. SubShader {
  13. Tags {
  14. "RenderType"="Opaque"
  15. }
  16. Pass {
  17. Name "FORWARD"
  18. Tags {
  19. "LightMode"="ForwardBase"
  20. }
  21. CGPROGRAM
  22. #pragma vertex vert
  23. #pragma fragment frag
  24. #include "UnityCG.cginc"
  25. // 追加投影相关包含文件
  26. #include "AutoLight.cginc"
  27. #include "Lighting.cginc"
  28. #pragma multi_compile_fwdbase_fullshadows
  29. #pragma target 3.0
  30. // 输入参数
  31. uniform float3 _BaseCol;
  32. uniform float3 _LightCol;
  33. uniform float _SpecPow;
  34. uniform sampler2D _Occlusion;
  35. uniform float _EnvInt;
  36. uniform float3 _EnvUpCol;
  37. uniform float3 _EnvSideCol;
  38. uniform float3 _EnvDownCol;
  39. // 输入结构
  40. struct VertexInput {
  41. float4 vertex : POSITION; // 顶点信息 Get
  42. float4 normal : NORMAL; // 法线信息 Get
  43. float2 uv0 : TEXCOORD0; // UV信息 Get
  44. };
  45. // 输出结构
  46. struct VertexOutput {
  47. float4 pos : SV_POSITION; // 裁剪空间(暂理解为屏幕空间吧)顶点位置
  48. float2 uv0 : TEXCOORD0; // UV0
  49. float4 posWS : TEXCOORD1; // 世界空间顶点位置
  50. float3 nDirWS : TEXCOORD2; // 世界空间法线方向
  51. LIGHTING_COORDS(3,4) // 投影相关
  52. };
  53. // 输入结构>>>顶点Shader>>>输出结构
  54. VertexOutput vert (VertexInput v) {
  55. VertexOutput o = (VertexOutput)0; // 新建输出结构
  56. o.pos = UnityObjectToClipPos( v.vertex ); // 变换顶点位置 OS>CS
  57. o.uv0 = v.uv0; // 传递UV
  58. o.posWS = mul(unity_ObjectToWorld, v.vertex); // 变换顶点位置 OS>WS
  59. o.nDirWS = UnityObjectToWorldNormal(v.normal); // 变换法线方向 OS>WS
  60. TRANSFER_VERTEX_TO_FRAGMENT(o) // 投影相关
  61. return o; // 返回输出结构
  62. }
  63. // 输出结构>>>像素
  64. float4 frag(VertexOutput i) : COLOR {
  65. // 准备向量
  66. float3 nDir = normalize(i.nDirWS);
  67. float3 lDir = _WorldSpaceLightPos0.xyz;
  68. float3 vDir = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);
  69. float3 rDir = reflect(-lDir, nDir);
  70. // 准备点积结果
  71. float ndotl = dot(nDir, lDir);
  72. float vdotr = dot(vDir, rDir);
  73. // 光照模型(直接光照部分)
  74. float shadow = LIGHT_ATTENUATION(i); // 获取投影
  75. float lambert = max(0.0, ndotl);
  76. float phong = pow(max(0.0, vdotr), _SpecPow);
  77. float3 dirLighting = (_BaseCol * lambert + phong) * _LightCol * shadow;
  78. // 光照模型(环境光照部分)
  79. float upMask = max(0.0, nDir.g); // 获取朝上部分遮罩
  80. float downMask = max(0.0, -nDir.g); // 获取朝下部分遮罩
  81. float sideMask = 1.0 - upMask - downMask; // 获取侧面部分遮罩
  82. // 混合环境色
  83. float3 envCol = _EnvUpCol * upMask + _EnvSideCol * sideMask + _EnvDownCol * downMask;
  84. float occlusion = tex2D(_Occlusion, i.uv0); // 采样Occlusion贴图
  85. float3 envLighting = envCol * _EnvInt * occlusion; // 计算环境光照
  86. // 返回结果
  87. float3 finalRGB = dirLighting + envLighting;
  88. return float4(finalRGB, 1.0);
  89. }
  90. ENDCG
  91. }
  92. }
  93. FallBack "Diffuse"
  94. }

这些都是很传统的光照模型的组合,但是运用了现代一些PBR的理念,这些光照模型也可以做不错的美术资源的产出

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

闽ICP备14008679号