Unity顶点位移Shader无效:平面始终平坦问题求助
Unity顶点位移Shader无效果,平面始终平坦的问题修复
问题描述
尝试实现海洋顶点位移Shader,但平面始终保持平坦,Shader无任何位移效果。已排查材质与平面的关联、GPU实例化开关,均无改善。
原Shader代码
Shader "Custom/Waves" { 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 _NormalMap ("Normal Map", 2D) = "bump" {} //Wave Properties _Direction("Direction", Vector) = (1.0, 0.0, 0.0, 1.0) _Steepness("Steepness", Range(0.1,1.0)) = 0.5 _Freq("Frequency", Range(1.0,10.0)) = 1.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard fullforwardshadows // Use shader model 3.0 target, to get nicer looking lighting #pragma target 3.0 sampler2D _MainTex; float _Steepness, _Freq; float4 _Direction; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader. // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing. // #pragma instancing_options assumeuniformscaling UNITY_INSTANCING_BUFFER_START(Props) // put more per-instance properties here UNITY_INSTANCING_BUFFER_END(Props) void vert(inout appdata_full v){ float3 pos = v.vertex.xyz; float4 dir = normalize(_Direction); float defaultWavelength = 2 * UNITY_PI; float wL = defaultWavelength / _Freq; float phase = sqrt(9.8/wL); float disp = wL * (dot(dir, pos) - (phase * _Time.y)); float peak = _Steepness/wL; pos.x += dir.x * (peak * cos(disp)); pos.y = peak * sin(disp); pos.z += dir.y * (peak * cos(disp)); v.vertex.xyz = pos; } void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; // Metallic and smoothness come from slider variables o.Metallic = _Metallic; o.Smoothness = _Glossiness; o.Alpha = c.a; } ENDCG } FallBack "Diffuse" }
Unity场景截图

问题根源与修复方案
核心问题:顶点函数未绑定到Surface Shader
原Shader中,#pragma surface指令没有指定自定义顶点函数,导致vert方法完全不会被执行。需要修改为:#pragma surface surf Standard fullforwardshadows vertex:vert方向向量错误修正
_Direction是三维方向,使用float3类型更合理,避免w分量干扰- 原代码中
pos.z += dir.y是错误的,应该使用dir.z来控制z轴方向的位移
其他细节优化
- 明确重力加速度的含义,添加注释
- 确保顶点位移的计算逻辑符合波浪公式
修正后的完整Shader代码
Shader "Custom/Waves" { 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 _NormalMap ("Normal Map", 2D) = "bump" {} //Wave Properties _Direction("Direction", Vector) = (1.0, 0.0, 1.0, 0.0) _Steepness("Steepness", Range(0.1,1.0)) = 0.5 _Freq("Frequency", Range(1.0,10.0)) = 2.0 } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM // 绑定自定义顶点函数vert #pragma surface surf Standard fullforwardshadows vertex:vert #pragma target 3.0 sampler2D _MainTex; float _Steepness, _Freq; float3 _Direction; struct Input { float2 uv_MainTex; }; half _Glossiness; half _Metallic; fixed4 _Color; UNITY_INSTANCING_BUFFER_START(Props) UNITY_INSTANCING_BUFFER_END(Props) void vert(inout appdata_full v){ float3 pos = v.vertex.xyz; // 归一化三维方向向量 float3 dir = normalize(_Direction); // 基础波长为2π,根据频率计算实际波长 float wL = 2 * UNITY_PI / _Freq; // 波浪传播速度(基于重力加速度9.8m/s²) float phaseSpeed = sqrt(9.8 / wL); // 位移计算因子 float dispFactor = dot(dir, pos) - phaseSpeed * _Time.y; float disp = wL * dispFactor; // 波浪振幅 float amplitude = _Steepness / wL; // 计算顶点位移 pos.x += dir.x * amplitude * cos(disp); pos.y = amplitude * sin(disp); pos.z += dir.z * amplitude * cos(disp); v.vertex.xyz = pos; } 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" }
额外验证步骤
- 增加平面细分:平面默认分段数太少,顶点不足会导致波浪效果不明显。创建平面时提高Width Segments和Height Segments,或给平面添加
Subdivision Surface组件增加细分等级。 - 调整参数:建议将
_Freq设为2-5,_Steepness设为0.5-0.8,_Direction设为(1,0,1)可以看到斜向波浪。
内容的提问来源于stack exchange,提问作者BaguetteDeP1
相关产品推荐
相关产品推荐

