zoukankan      html  css  js  c++  java
  • 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相机下即可。

  • 相关阅读:
    Lucene.Net 2.3.1开发介绍 —— 二、分词(一)
    控制‘控制台应用程序’的关闭操作
    详解for循环(各种用法)
    敏捷软件开发
    Sql Server的一些知识点
    在SharePoint 2010 中配置Remote Blob Storage FILESTREAM Provider
    使用LotusScript操作Lotus Notes RTF域
    JOpt Simple 4.5 发布,命令行解析器
    John the Ripper 1.8.0 发布,密码破解工具
    PacketFence ZEN 4.0.1 发布,网络接入控制
  • 原文地址:https://www.cnblogs.com/yangrouchuan/p/6366608.html
Copyright © 2011-2022 走看看