unity-urp:视野雾

问题背景

恐怖游戏在黑夜或者某些场景下,需要用雾或者黑暗遮盖视野,搭建游戏氛围

效果

场景中,雾会遮挡场景和怪物,但是在玩家视野内雾会消散,距离玩家越近雾越薄。

当前是第三人称视角,但是可以轻松的把这个效果转换为第一人称视角。

原理

正如屏幕空间的高度雾,这里做一个屏幕空间的视野雾。

采用特殊的材质在相机前方绘制一个能遮盖相机的矩形。如果矩形覆盖的像素点在视野内,就降低雾效果,否则绘制雾效果。

实现

urp下使用RenderFeature + 自定义shader实现

简略步骤

在相机节点下放置一个Plane,隐藏它

编写shader并创建材质

像素着色器代码如下,原理为采样深度,根据深度计算出当前像素的世界坐标,根据坐标和玩家位置的关系确定雾效果

            float4 frag(Varyings input) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
                //计算屏幕uv
                float2 screenUV = GetNormalizedScreenSpaceUV(input.positionCS);
                //采样深度
                #if UNITY_REVERSED_Z
                    float depth = SampleSceneDepth(screenUV);
                #else
                    // Adjust Z to match NDC for OpenGL ([-1, 1])
                    float depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(screenUV));
                #endif
                //根据深度计算当前像素所代表的世界空间坐标
                float3 worldPos = ComputeWorldSpacePosition(screenUV, depth, UNITY_MATRIX_I_VP);
                //计算角色位置和当前渲染的像素所代表的世界坐标的距离
                float distanceVal = distance(worldPos, _PosWS);
                //做过渡
                float t = (max(distanceVal - (_Range * 0.8), 0)) / (_Range * 1.2);
                //计算透明度,透明度越低雾越薄
                float alpha = lerp(0, 1, saturate(t * t));
                //返回像素颜色
                return float4(_Color.rgb, alpha * _Color.a);
            }
创建并且配置RenderFeature到URP管线的自定义Renderer

自定义Pass中的核心代码,使用指定的材质绘制隐藏的Plane

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        if(null == Renderer)
        {
            if(null != SceneFogController.Instance)
            {
                Renderer = SceneFogController.Instance.Renderer;
            }
        }
        if (null == FogMat || null == Renderer)
        {
            return;
        }
        var cmd = CommandBufferPool.Get("FogPass");
        cmd.DrawRenderer(Renderer, FogMat, 0, 0);
        //Matrix4x4 material = new Matrix4x4();
        //material.SetTRS(_renderer.transform.position, _renderer.transform.rotation, Vector3.one);
        //cmd.DrawMesh(_renderer.gameObject.GetComponent<MeshFilter>().sharedMesh, material, FogMat);
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值