Unity Shader unity文档学习笔记(十一):战争迷雾核心算法

核心算法 非常简单 主要就是把一个点的世界坐标转换到贴图的UV坐标
给整个场景一个大的plane 加上写的shader
摄像机位置调成plane的正上方

Shader "Unlit/FogRender"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags{ "Queue" = "Transparent+151" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
		Blend SrcAlpha OneMinusSrcAlpha
		ZWrite Off
		ZTest Off
		Cull Back

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma fragmentoption ARB_precision_hint_fastest 
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				// sample the texture
				half4 col = tex2D(_MainTex, i.uv);
				return col;
			}
			ENDCG
		}
	}
}

给plane加上渲染的脚本 随便写的 0.0

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FogSystem : MonoBehaviour {
    public Material material;
    private Texture2D mTexture;
    private float worldToTex;
    private int textureSize = 50;
    private int inputSize = 2;
    private float transScale;
    private Vector2Int worldPos = new Vector2Int(0,0);
    // Use this for initialization
    void Start () {
        transScale = transform.localScale.x * 10;
        worldToTex = textureSize/transScale;
        UpdateTexture();
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                // or hit.collider.transform;
                Vector2 v2 = new Vector2(hit.point.x + transScale / 2, hit.point.z + transScale / 2) * worldToTex;
                worldPos = new Vector2Int((int)v2.x,(int)v2.y); 
                UpdateTexture();
            }
        }
	}
    void UpdateTexture()
    {
        if (mTexture == null)
        {
            // Native ARGB format is the fastest as it involves no data conversion
            mTexture = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false);
 
            mTexture.wrapMode = TextureWrapMode.Clamp;
            Color32[] defaultColor = new Color32[textureSize * textureSize];
            for (int i = 0; i < defaultColor.Length; i++)
            {
                defaultColor[i] = Color.black;
            }
            mTexture.SetPixels32(defaultColor);
            mTexture.Apply();
        }
        else
        { 
            Color32[] colors = new Color32[inputSize * inputSize];
            for (int i = 0; i < colors.Length; i++)
            {
                colors[i] = Color.white;
                colors[i].a = 0;
            }
            mTexture.SetPixels32(worldPos.x, worldPos.y, inputSize, inputSize, colors);
            mTexture.Apply();
        }
    }
    private void OnWillRenderObject()
    {
        material.SetTexture("_MainTex", mTexture);
    }
}

有一篇写的比较好的博客
优化了算法 加入了多线程

Unity3D游戏高性能战争迷雾系统实现
mBuffer1 用来计算 是否可见
mBuffer2 用来计算 模糊
最终使用的是mBuffer0 多线程 就是要麻烦一点
边缘模糊使用的是均值模糊均值模糊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值