You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将顶点着色器的曲面修改传递给Unity表面着色器

实现Subway Surfer风格的曲面效果(结合Unity Standard表面着色器)

嘿,你已经找对路子了!用表面着色器的vertex:vert指令自定义顶点变换,同时保留Standard光照管线的效果,这个思路完全正确。你的测试代码里给X轴加偏移的逻辑没问题,只需要把原来的曲面计算逻辑正确迁移到顶点函数里,再注意几个关键细节就能搞定。

修正后的完整Shader代码

Shader "Custom/CurvedSurface" {
    Properties{
        _Color("Color", Color) = (1,1,1,1)
        _MainTex("Albedo (RGB)", 2D) = "white" {}
        _Glossiness("Smoothness", Range(0,1)) = 0.5
        _Metallic("Metallic", Range(0,1)) = 0.0
        _QOffset("Curve Offset (X,Y,Z)", Vector) = (0,1,0,0) // 默认Y轴偏移,匹配Subway Surfer地面向上弯曲的效果
        _Dist("Curve Distance Factor", Float) = 100.0
    }
    SubShader{
        Tags{ "RenderType" = "Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows vertex:vert addshadow
        #pragma target 3.0

        sampler2D _MainTex;
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float4 _QOffset;
        float _Dist;

        struct Input {
            float2 uv_MainTex;
        };

        void vert(inout appdata_full v) {
            // 1. 把模型空间顶点转换到视图空间(和你找到的原始Shader逻辑对齐)
            float4 worldPos = mul(unity_ObjectToWorld, v.vertex);
            float4 viewPos = mul(UNITY_MATRIX_V, worldPos);
            
            // 2. 计算基于深度的二次偏移因子——距离相机越远,弯曲程度越大
            float zOff = viewPos.z / _Dist;
            viewPos += _QOffset * zOff * zOff;
            
            // 3. 把修改后的视图空间位置转换回模型空间,赋值给顶点
            v.vertex = mul(unity_WorldToObject, mul(UNITY_MATRIX_V_INV, viewPos));
        }

        void surf(Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

核心细节解释

  • 空间转换的重要性:原始Shader是在视图空间计算弯曲的,这样效果会跟随相机视角(地面越远越向上弯),完美匹配Subway Surfer的视觉体验。如果直接修改模型空间的顶点,弯曲效果会和模型绑定,而不是相机视角,这就不符合需求了。
  • 阴影正确显示:一定要加上addshadow指令!它会让Unity自动生成适配弯曲顶点的阴影投射器,不然阴影会还是原来的平面形状,穿帮感拉满。
  • 参数调整技巧:
    • _QOffset的Y值设为正数时,地面向上弯;调X值可以左右弯,按需调整。
    • _Dist越小,弯曲效果越强烈,你可以根据场景的大小慢慢试出合适的值。

踩坑提醒

  • 必须用透视相机!正交相机下视图空间的Z值变化逻辑不一样,弯曲效果会完全不对。
  • 这个Shader只给场景静态物体(地面、轨道)用就行,别给玩家角色、道具用,不然它们也会跟着弯曲,显得很奇怪。
  • 如果你的场景里有动态阴影(比如实时光影),fullforwardshadows指令已经帮你处理了大部分情况,不用额外写阴影代码。

内容的提问来源于stack exchange,提问作者Carlos Hdez Barbera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:16:02