您当前的位置: 首页 >  unity

Jave.Lin

暂无认证

  • 8浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Unity Shader - URP - 抄作业 - Deep Crack - 裂痕深坑 - SRP Batch优化

Jave.Lin 发布时间:2022-04-28 18:14:43 ,浏览量:8

文章目录
  • 环境
  • 思路
  • 建模
    • Houdini
      • 设置好
      • Geometry + Curve + Extrude
    • 3ds max
      • 设置好参考背景图
      • 使用:创建/图形/线,来勾勒刨面
      • 封口刨面
      • 转为可编辑多边形
      • 导出用于仅仅写入深度的面片
      • 挤出裂痕深度
      • 导出带挤出裂痕模型
  • 最终效果
  • 优化
    • 再次优化
  • 优缺点
  • 其他的裂痕方案
  • 完整的 Shader
    • 深坑部分
    • 裂痕表面部分
  • Project
  • References

环境

Unity : 2020.3.18f1 Pipeline : URP

之前看了一下公司里有位同学买了 taecg 老师的课程 里面有讲到 裂痕深坑 的制作方式(做法有多种,这课程中只是其中一种) 那么下面我将一些后续的优化讲一下(不使用双 pass,直接使用多网格,区别材质,调整 RenderQueue)

思路
  • 将深坑部分的网格绘绘制出来(会增加 overrdraw)
  • 再将裂痕表面部分写入深度(可以使用 Offset 调整一下深度)
  • 再正常绘制其他不透明对象即可
建模 Houdini

课程里面 使用的是 Houdini 的 Geometry + Curve + Extrude 来建模的

我也使用 Houdini 按这种方式实现了,但是挤出的底部面片有面的点顺序错乱问题,我那位同事使用 Houdini 18 版来建模,没有问题,我使用的是 Houdini 19 就问题(反正我不熟悉 Houdini,第一次用,希望后续有机会用此神器来程序化建模)

设置好

Top View 参考图片 在这里插入图片描述

Geometry + Curve + Extrude
  • Geometry 节点下添加 Curve
  • Curve 勾勒除刨面剪影
  • Extrude 挤出剪影深度 在这里插入图片描述

最后导出到 unity Assets 下 在这里插入图片描述

导出之后,使用 ms 的 3d view 查看到底部有问题(目测点序错乱) 请添加图片描述

3ds max

因为 Houdini 导出后的 FBX 的底部面片顶点错乱

所以后续我使用了 3ds max 2020 来建模(虽然我也不熟悉,但是起码一些基础的操作也是会一丢丢的)

  • 设置好 系统单位、显示单位:米
  • 设置好仅旋转轴 X 90

在顶视图下设计

设置好参考背景图

在这里插入图片描述

在这里插入图片描述 下面是设置好的效果 在这里插入图片描述

使用:创建/图形/线,来勾勒刨面

在这里插入图片描述

封口刨面

在这里插入图片描述

这样大致的刨面剪影就 OK了 在这里插入图片描述

转为可编辑多边形

在这里插入图片描述

导出用于仅仅写入深度的面片

上面的网格,我们在导出前,要记得 塌陷 一下,目的是:将所有的修改器都应用到网格本身,并删除所有修改器 在这里插入图片描述

挤出裂痕深度

我们将上面的仅仅用于写入深度的面片复制一份 在这里插入图片描述

挤出一下,用来绘制裂痕深坑部分 在这里插入图片描述

导出带挤出裂痕模型

OK,看着没有 Houdini 中点序错乱的问题 请添加图片描述

最终效果

在这里插入图片描述 请添加图片描述

发布 Google Pixel 6 Pro 上的效果: 在这里插入图片描述

优化

我们上面的方式是:不使用 URP 中的双 pass 因为会打断合批

我先使用 SRP Batcher 合批绘制第一批深坑部分

我之前也概要描述了一下 SRP Batch 和其他 Batch 的区别:Unity - DrawCall, Batch, SetPassCall区别 在这里插入图片描述

再绘制裂痕表面部分,用于写入深度 再图像上是看不到内容的,因为我们设置了 ColorMask 0 所以我们先屏蔽 ColorMask 0 并输出一下白色,便于查看 在这里插入图片描述

下面白色部分是裂痕表面仅仅写入深度的像素部分 在这里插入图片描述

最后绘制场景其他不透明部分 + Bloom 后效 在这里插入图片描述

最终我们这么多的 裂痕深坑,只要两个 SRP Batch 就可以完事: 在这里插入图片描述

在这里插入图片描述

之前说过,这种方式是不用双pass 的方式,这样尽可能让 SRP Batcher 生效

但是这种方式只能使用:Prefab 裹起来 在这里插入图片描述

而且会对出一个 GameObject 对象,会占用额外的 GameObject 的一些消耗(生命周期、内存、等,虽然可以使用 DOTS+ESC 来优化)

除了这种方式外,还可以使用另一种方式: 使用 URP Render Feature 给 DeepCrack 独立的两个 Feature 来绘制即可,这样也是可以让 SRP Batcher 尽可能生效,但就是需要增加 Render Feature ,有丢丢麻烦,Render Feature 的一些基础使用可以参考我之前写得:Unity - URP RenderFeature - 实现类似多 Pass 的 XRay: Rim、Pattern

所有实现方式都是根据项目情况来选择

再次优化

其实还可以再次优化:使用 Instancing 方式 因为我们的 Mesh、Material 都是相同的 这是用 Instancing 再适合不过 这部分我就不写了

优缺点

没有完美的方案,只有最适合的方案

优点:可以比较好的把控裂痕边缘的清晰度,和坑内内容 缺点:只能适用于特定的表面形状来实现,比如:上面只适合 平地 上的深坑,一旦有不平整的都不会有效果,如:上面的球体、立方体底部,可以看到

其他的裂痕方案

以前看到过使用 SSD (Space Space Decal) 来实现 还将过有些是再配合上 视差来制作位深度来实现

总之每一种方案都有优缺点,没有完美的方案,根据实际项目来选择对应的实现方案才是最适合的

可以参考我之后另一篇:DCC - Photoshop - Nvidia NormalMapFilter - 法线生成工具 - 顺便测试 Unity URP 12.1 中的 Decal System

理论上还有一些方案使用的是:Parallex Map 配合 Decal 来做裂痕效果也是可以的(还没试过)

完整的 Shader 深坑部分
// jave.lin 2022/04/27
// 裂痕深坑的深坑部分

Shader "Test/DeepCrack_URP_USING_DEPTH"
{
    Properties
    {
        _Color0 ("Color0", Color) = (1, 1, 1, 1)
        [HDR] _Color1 ("Color1", Color) = (0, 0, 0, 0)

        _Height0 ("Height0", Range(-10, 10)) = 0
        _Height1 ("Height1", Range(-10, 10)) = -1
        _HeightScale ("HeightScale", Range(0.001, 1)) = 1
        _HeightPower ("Height Power", Range(0.01, 10)) = 1

        [Toggle] _TWINKLE ("Twinkle On", Int) = 1
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Geometry-2" }
        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma shader_feature _ _TWINKLE_ON
            #pragma multi_compile_fog
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            struct Attributes
            {
                float4 positionOS : POSITION;
            };

            struct Varings
            {
                float4 positionCS : SV_POSITION;
                half3 color : COLOR;
                half fogFactor : TEXCOORD1;
            };

            CBUFFER_START(UnityPerMaterial)
                half4 _Color0;
                half4 _Color1;
                float _Height0;
                float _Height1;
                float _HeightScale;
                float _HeightPower;
            CBUFFER_END

            Varings vert (Attributes i)
            {
                Varings o = (Varings)0;
                o.positionCS = TransformObjectToHClip(i.positionOS.xyz);
                o.fogFactor = ComputeFogFactor(o.positionCS.z);
                half height_col_lerp_t = smoothstep(_Height0, _Height1, i.positionOS.y * _HeightScale);
                height_col_lerp_t = pow(height_col_lerp_t, _HeightPower);
                o.color = lerp(_Color0.rgb, _Color1.rgb, height_col_lerp_t);
                #ifdef _TWINKLE_ON
                    o.color *= sin(_Time.z) * 0.3 + 0.7;
                #endif
                return o;
            }

            half4 frag (Varings i) : SV_Target
            {
                i.color = MixFog(i.color, i.fogFactor);
                return half4(i.color, 1);
            }
            ENDHLSL
        }
    }
}
裂痕表面部分
// jave.lin 2022/04/27
// 裂痕深坑的表面部分:仅仅写入顶层深度

Shader "Test/DeepCrack_URP_USING_WRITE_TOP_DEPTH"
{
    Properties
    {
        _DepthOffset1 ("DepthOffset1", Float) = 0
        _DepthOffset2 ("DepthOffset2", Float) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Geometry-1" }
        Pass
        {
            Offset [_DepthOffset1], [_DepthOffset2]
            ZTest Always
            ColorMask 0
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            float4 vert (float4 positionOS : POSITION) : SV_POSITION
            {
                positionOS.y = 0;
                return TransformObjectToHClip(positionOS.xyz);
            }
            half4 frag (float4 positionCS : SV_POSITION) : SV_Target
            {
                return 0;
            }
            ENDHLSL
        }
    }
}
Project

学习、备忘用,不公开,上面公开的内容已经够多了,而且都是参考 taecg 老师的一些课程

TestDeepCrackEffect_2020_3_18f1.rar

References
  • Unity VFX - Ground Cracks | Fissure | Hole Effect Tutorial - youtube 1年前的表面裂痕效果,但是 VFX 制作的,估计原来的这个效果,多少有一些抄袭成分
关注
打赏
1664331872
查看更多评论
立即登录/注册

微信扫码登录

0.1058s