Unity - URP RenderFeature - 实现类似多 Pass 的 XRay: Rim、Pattern

本文详细介绍了在Unity 2019.4.30f1的URP中,如何在Built-in RP与RendererFeatures中使用多Pass技术来实现XRay效果,包括Pattern、Rim的运用,以及URP相对于Built-in RP在多Pass上的优势,如减少SetGPUData次数。还提供了脚本示例和关键配置步骤。

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发


环境

先声明使用的环境信息:
Unity : 2019.4.30f1
URP : 7.7.1

为何要声明环境信息?

因为我自己下了好多个 Unity 版本,发现 URP 都几乎发生了变化,这不得不说:很折腾使用 URP 的开发人员

我已经下载了 5 个 Unity 版本了,-_-!
在这里插入图片描述

其中我也发现了: URP学习之七–RenderFeature 他使用的 URP 版本和我的也是不一样的

如下图,是 RendererFeatures Inspector 界面区别
在这里插入图片描述

下面我是使用了 高版本的 Unity 2021.1.21f1 ,还好发现和我现在的 RenderFeatures 的功能差不多
在这里插入图片描述


XRay : Rim, Pattern, Pattern+Rim


在 Built-RP 中

如果在 Built-in RP 中,我们可能需要这么写 Shader

// jave.lin 2021/10/19 这是伪代码
Shader "YourShaderName" {
   
   
	Properties {
   
   }
	SubShader {
   
   
		Pass {
   
   
			Name "DrawBody"
		}
		Pass {
   
   
			Name "DrawXRayPattern+Rim"
		}
	}
	Fallback "xxx"
}

然后你打开 Unity 的 Window/Analysic/Frame Debugger…,你会发现材质直接 YourShaderName Shader 的都不能合批,合批原因就是因为使用了多 Pass

为何多 Pass 不能合批?因为每个 Pass 的 GPU Data 可能都不一样,GPU Data 可能包含:ZTest, ZWrite, Blend, Fog, ColorMask, LightMode,还有各种 uniform 可能都不一样,所以合不了 DC


在 URP 中


Shader

先给原始的绘制对象写好 shader

// jave.lin 2021/10/19
// 测试 PP RenderObj 的 原始绘制 Shader

Shader "Test/RF_DrawCharacter"
{
   
   
    Properties
    {
   
   
        _Color("Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
   
   
        Tags
        {
   
   
            "RenderType" = "Opaque"
        }
        LOD 100
        Pass
        {
   
   
            // 标记上 Stencil,给 XRay 效果时防止重复绘制
            Stencil
            {
   
   
                Ref 1
                Comp Always
                Pass Replace
            }
            HLSLPROGRAM
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #pragma vertex vert
            #pragma fragment frag
            struct appdata
            {
   
   
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            struct v2f
            {
   
   
                float4 vertex : SV_POSITION;
                float3 normal : NORMAL;
            };
            CBUFFER_START(UnityPerMaterial)
                float4 _Color;
            CBUFFER_END
            float3 _LightDirection;
            v2f vert (appdata v)
            {
   
   
                v2f o;
                o.vertex = TransformObjectToHClip(v.vertex.xyz);
                o.normal = TransformObjectToWorldNormal(v.normal);
                return o;
            }
            half4 frag(v2f i) : SV_Target
            {
   
   
                //half3 L = _LightDirection;
                //return half4(L, 1); // 有时候 _LightDirection 没有数据,xyzw == 0
                // 
                // 建议使用下面的 GetMainLight() 的方式来获取灯光相关信息
                // struct Light 需要 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
                Light light = GetMainLight();
                half3 L = light.direction;
                //return half4(L, 1); // 这里输出颜色可以看到是有效的
                half diffuse = dot(L, normalize(i.normal)) * 0.5 + 0.5;
                return _Color * diffuse;
            }
            ENDHLSL
        }
    }
}

注意,我们用了 Stencil,目的:标记上 Stencil,给 XRay 效果时防止重复绘制

给遮挡的 墙体 对象的 Shader 也写上:(普通的 half lambert 着色即可)

// jave.lin 2021/10/19
// 测试 PP RenderObj 的 原始用于遮挡 Character 的 Shader

Shader "Test/RF_DrawWall"
{
   
   
    Properties
    {
   
   
        _Color ("Color", Color) = (1, 1, 1, 1)
    }
    SubShader
    {
   
   
        Tags
        {
   
   
            "RenderType" = "Opaque"
        }
        LOD 100
        Pass
        {
   
   
            HLSLPROGRAM
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #pragma vertex vert
            #pragma fragment frag
            struct appdata
            {
   
   
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            struct v2f
            {
   
   
                float4 vertex : SV_POSITION;
                float3 normal : NORMAL;
            };
            CBUFFER_START(UnityPerMaterial)
                float4 _Color;
            CBUFFER_END
            float3 _LightDirection;
            v2f vert (appdata v)
 

低功耗蓝牙项目,需要一块懂省电的板

思澈 SF32LB52 芯片,BLE 协议栈深度优化,上手即开发

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值