接上一篇中說的游戲,我們已經實現了client、host上的一個物體可見不可見的行為。之后我們可以加入類似檢查兩個單位之間的距離、或是兩個單位之間有無阻擋物來進一步實現游戲機制。
在這篇隨筆中我會首先介紹戰爭迷霧的一種繪制方法。下一篇中介紹Line of Sight模型的實時生成。兩者結合后的最終的效果如下:
戰爭迷霧的繪制:
不同的繪制方法有很多,我們這里采取的是把戰爭迷霧的信息保存到貼圖上,然后作為ImageEffect和最終圖像融合。
在想要有迷霧遮罩的地方放上一個模型,然后將其圖層設置為FowMask(僅做例子)。
將主相機中的Culling Mask中的FowMask取消勾選,這樣這個模型不會被渲染到主相機里去。
然后新建一個相機作為渲染貼圖的相機,稱作Fow相機,作為主相機的child Gameobject,並且Culling Mask中只勾選FowMask。並設置Clear Flag和Background Color如下
這樣保證在渲染出的圖像中,除了遮罩模型的地方其他區域alpha都為0。因為我們接下來要用到alpha表示一個區域是否有遮罩。
在Fow相機下添加一個腳本
public class LosMaskSubCamera : MonoBehaviour {
// Use this for initialization
void Start () {
var t = new RenderTexture(Screen.width, Screen.height, 16);
GetComponent<Camera>().targetTexture = t;
Shader.SetGlobalTexture("_LOSMaskTexture", t);
}
}
該腳本新建一張RenderTexture並且讓相機渲染到這張texture中。同時把它作為Shader的輸入。這里的Shader就是附在主相機上的image effect。
在主相機上添加一個腳本代碼如下:
public class LosMask : MonoBehaviour {
public Material LOSMaskMaterial;
private void OnRenderImage(RenderTexture source, RenderTexture destination) {
Graphics.Blit(source, destination, LOSMaskMaterial);
}
}
一個單純的調用一個ImageEffect的代碼。在之后完成Shader、創建Material之后再把Material賦值給它。
現在我們新建一個Shader。代碼跟Image Effect模板相差無幾,如下:
Shader "Custom/LOSMaskShader"
{
Properties
{
_MainTex("MainTex",2D) = "white"{}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _LOSMaskTexture;
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
float4 mask = tex2D(_LOSMaskTexture,i.uv);
float4 main = tex2D(_MainTex,i.uv);
main = main * saturate(mask.a+0.2); //0.2代表不可見區域的可見度。也可以把它暴露成一個變量
return main;
}
ENDCG
}
}
}
代碼非常簡單,最終效果是_LOSMaskTexture中alpha值低的區域變暗。注意到mask里只用到了alpha通道,用剩下的rgb通道還可以做一些有趣的事情。
比如說給在迷霧地區顯示點東西:
模糊是因為整個遮罩都被我模糊過了。
具體實現這里先略過。
之后新建一個Material賦值給主相機下的腳本就可以完成了。
要看到效果,需要新建一個模型,比如一個球體,然后把圖層調整為FowMask。之后運行游戲就可以看到效果了。
如果需要平滑邊緣可以加上高斯模糊。
我這里參考了一位大牛的博客:http://blog.csdn.net/u011047171/article/details/47977441 。直接粘在Fow相機下即可。