終於有空看點新東西,這一篇在《遊戲編程精粹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補充,增長一組面片的使用狀況:
測試工程地址: