终于有空看点新东西,这一篇在《游戏编程精粹1》的5.3节中,主要讲经过烘焙先后左右4个方向光照并插值,来代替顶点光照的作法git
看了下原文例程的代码,彷佛是放在cpu部分处理的顶点色,或可能只是参考用的脚本编程
这种烘焙4个方向的作法或许优于顶点光照,但缺点是光线角度较为固定,原文描述早期的足球游戏有使用到app
或许改为贴图的话能够烘焙进一些法线效果,或是作成粒子光照。。测试
首先写一个简单的兰伯特光照,烘焙四个方向:优化
这4个方向的灯光信息会被烘焙到uv2,uv3中,运行后cpu计算当前角度的权重,到shader里进行混合。spa
插值的计算用了比较偷懒的作法,原文是转角度进行处理,因为y方向固定,这里直接用Vector2点乘。3d
public class LightingRuntime : MonoBehaviour { public Transform virtualLight; public Color virtualLightCol; public SkinnedMeshRenderer testRenderer; void Update() { var lightDir = (virtualLight.position - transform.position).normalized; lightDir = Vector3.ProjectOnPlane(lightDir, Vector3.up); var lightDir_vec2 = new Vector2(lightDir.x, lightDir.z); var blend1 = Mathf.Clamp01(Vector2.Dot(lightDir_vec2, Vector2.up)); var blend2 = Mathf.Clamp01(Vector2.Dot(lightDir_vec2, Vector2.down)); var blend3 = Mathf.Clamp01(Vector2.Dot(lightDir_vec2, Vector2.left)); var blend4 = Mathf.Clamp01(Vector2.Dot(lightDir_vec2, Vector2.right)); var vec4 = new Vector4(blend1, blend2, blend3, blend4); testRenderer.material.SetVector("_TestLight", vec4); testRenderer.material.SetVector("_TestLightCol", virtualLightCol); } }
传入4个权重表明4个方向,而后shader部分根据4个方向的权重乘起来便可。code
能够用uv2,uv3来储存4个方向的光照信息。orm
v2f vert (appdata v) { v2f o = (v2f)0; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.uv2 = v.uv2; o.uv3 = v.uv3; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 lightVolume = i.uv2.x * _TestLight.x + i.uv2.y * _TestLight.y + i.uv3.x * _TestLight.z + i.uv3.y * _TestLight.w; return lightVolume * _TestLightCol; }
可是占用uv2,uv3有点占用带宽,因而想了一个办法,左右和先后的方向能够各用一个镜像:blog
left = 1 - right;
用镜像以前须要记录4个方向,如今只需记录2个。可是要考虑一些长期阴影的区域,因此还需加些参数调节去缓解。
优化了一下,将uv2做为光照信息,并镜像了烘焙到顶点上的光照(输出的uv2是float4),以及微调参数:
v2f vert (appdata v) { v2f o = (v2f)0; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.uv2.xz = v.uv2.xy; o.uv2.y = (1 - v.uv2.x) - 0.8; o.uv2.w = (1 - v.uv2.y) - 1; return o; } fixed4 frag (v2f i) : SV_Target { fixed lightVolume = dot(i.uv2, _TestLight); return lightVolume * _TestLightCol; }
最终效果:
2019/06/2补充,增长一组面片的使用状况:
测试工程地址: