• unity中绘制战争迷雾


    接上一篇中说的游戏,我们已经实现了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相机下即可。

  • 相关阅读:
    改变原数组的filter
    fireEvent2
    Ajaxを勉強しよ
    javascript 地图
    fillZero函数
    window.onerror
    とある要素以下にある textNode で一致する textNode を XPath で高速に取り出す
    判定是否为表单元素
    Django中判断用户是否登陆
    【 如果你和我一样在一栋33层大厦的27层工作,在这栋大厦里发生了火灾,那么你该怎么办? 看看也许会保住你的性命!!!】
  • 原文地址:https://www.cnblogs.com/yangrouchuan/p/6366608.html
Copyright © 2020-2023  润新知