赞
踩
此篇文章为庄懂技术美术课程学习笔记。
首先一个基本光照的组成可以是以下这些
将这些光分别组合就可以得到一个较好的光照模型
AO(环境遮蔽)是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光、飘和阴影不实等问题,解决或改善场景中缝隙、角线以及细小物体等的表现不清晰问题,综合改善细节尤其是暗部阴影,增强空间的层次感、真实感,同时加强和改善画面明暗对比,增强画面的艺术性。
Lambert+Phong的实现思路在之前的文章中都有过说明,这里就不在重复。
三色环境光实现的核心思路:
法线的G通道是顶光,将其乘上-1就是底光,再用1减去顶光和底光,就是剩余的四周的环境光。
投影调用的方法:
先是连连看部分的实现
接着是代码部分的实现
- Shader "AP01/L08/OldSchoolPlus" {
- Properties {
- _BaseCol ("基本色", Color) = (0.5, 0.5, 0.5, 1.0)
- _LightCol ("光颜色", Color) = (1.0, 1.0, 1.0, 1.0)
- _SpecPow ("高光次幂", Range(1, 90)) = 30
- _Occlusion ("AO图", 2D) = "white" {}
- _EnvInt ("环境光强度", Range(0, 1)) = 0.2
- _EnvUpCol ("环境天顶颜色", Color) = (1.0, 1.0, 1.0, 1.0)
- _EnvSideCol ("环境水平颜色", Color) = (0.5, 0.5, 0.5, 1.0)
- _EnvDownCol ("环境地表颜色", Color) = (0.0, 0.0, 0.0, 0.0)
- }
- SubShader {
- Tags {
- "RenderType"="Opaque"
- }
- Pass {
- Name "FORWARD"
- Tags {
- "LightMode"="ForwardBase"
- }
-
-
- CGPROGRAM
- #pragma vertex vert
- #pragma fragment frag
- #include "UnityCG.cginc"
- // 追加投影相关包含文件
- #include "AutoLight.cginc"
- #include "Lighting.cginc"
- #pragma multi_compile_fwdbase_fullshadows
- #pragma target 3.0
- // 输入参数
- uniform float3 _BaseCol;
- uniform float3 _LightCol;
- uniform float _SpecPow;
- uniform sampler2D _Occlusion;
- uniform float _EnvInt;
- uniform float3 _EnvUpCol;
- uniform float3 _EnvSideCol;
- uniform float3 _EnvDownCol;
- // 输入结构
- struct VertexInput {
- float4 vertex : POSITION; // 顶点信息 Get✔
- float4 normal : NORMAL; // 法线信息 Get✔
- float2 uv0 : TEXCOORD0; // UV信息 Get✔
- };
- // 输出结构
- struct VertexOutput {
- float4 pos : SV_POSITION; // 裁剪空间(暂理解为屏幕空间吧)顶点位置
- float2 uv0 : TEXCOORD0; // UV0
- float4 posWS : TEXCOORD1; // 世界空间顶点位置
- float3 nDirWS : TEXCOORD2; // 世界空间法线方向
- LIGHTING_COORDS(3,4) // 投影相关
- };
- // 输入结构>>>顶点Shader>>>输出结构
- VertexOutput vert (VertexInput v) {
- VertexOutput o = (VertexOutput)0; // 新建输出结构
- o.pos = UnityObjectToClipPos( v.vertex ); // 变换顶点位置 OS>CS
- o.uv0 = v.uv0; // 传递UV
- o.posWS = mul(unity_ObjectToWorld, v.vertex); // 变换顶点位置 OS>WS
- o.nDirWS = UnityObjectToWorldNormal(v.normal); // 变换法线方向 OS>WS
- TRANSFER_VERTEX_TO_FRAGMENT(o) // 投影相关
- return o; // 返回输出结构
- }
- // 输出结构>>>像素
- float4 frag(VertexOutput i) : COLOR {
- // 准备向量
- float3 nDir = normalize(i.nDirWS);
- float3 lDir = _WorldSpaceLightPos0.xyz;
- float3 vDir = normalize(_WorldSpaceCameraPos.xyz - i.posWS.xyz);
- float3 rDir = reflect(-lDir, nDir);
-
- // 准备点积结果
- float ndotl = dot(nDir, lDir);
- float vdotr = dot(vDir, rDir);
-
- // 光照模型(直接光照部分)
- float shadow = LIGHT_ATTENUATION(i); // 获取投影
- float lambert = max(0.0, ndotl);
- float phong = pow(max(0.0, vdotr), _SpecPow);
- float3 dirLighting = (_BaseCol * lambert + phong) * _LightCol * shadow;
-
- // 光照模型(环境光照部分)
- float upMask = max(0.0, nDir.g); // 获取朝上部分遮罩
- float downMask = max(0.0, -nDir.g); // 获取朝下部分遮罩
- float sideMask = 1.0 - upMask - downMask; // 获取侧面部分遮罩
- // 混合环境色
- float3 envCol = _EnvUpCol * upMask + _EnvSideCol * sideMask + _EnvDownCol * downMask;
- float occlusion = tex2D(_Occlusion, i.uv0); // 采样Occlusion贴图
- float3 envLighting = envCol * _EnvInt * occlusion; // 计算环境光照
-
- // 返回结果
- float3 finalRGB = dirLighting + envLighting;
- return float4(finalRGB, 1.0);
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- }
这些都是很传统的光照模型的组合,但是运用了现代一些PBR的理念,这些光照模型也可以做不错的美术资源的产出
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。