Unity中如何根据物体与地面距离动态提升阴影强度?
解决方案:基于物体高度动态调整阴影强度
核心问题分析
直接调整平行光的全局阴影参数无法满足需求——平行光的阴影设置是全局生效的,无法针对不同高度的物体单独控制强度。必须通过每个物体独立计算阴影权重的方式实现目标效果。
方法一:自定义Shader实现(通用方案,支持所有渲染管线)
通过在物体的Shader中嵌入高度判断逻辑,动态调整阴影的混合强度,是最可靠的解决方案。
Shader核心代码片段
在片段着色器中添加高度计算与阴影强度控制:// 暴露可调整参数 float _GroundY; // 地面的Y坐标 float _MaxHeight; // 阴影开始增强的临界高度 float _MinHeight; // 地面高度(通常等于_GroundY) fixed4 frag(v2f i) : SV_Target { // 获取物体世界空间位置 float3 worldPos = mul(unity_ObjectToWorld, i.vertex).xyz; // 计算当前高度与地面的差值 float heightDiff = worldPos.y - _GroundY; // 平滑计算阴影强度系数:越靠近地面,系数越接近1 float shadowIntensity = smoothstep(_MaxHeight, _MinHeight, heightDiff); // 采样漫反射颜色与阴影 fixed3 diffuseColor = tex2D(_MainTex, i.uv).rgb * _Color; float shadow = SHADOW_ATTENUATION(i); // 混合颜色与阴影:阴影强度随高度动态变化 fixed4 finalColor = fixed4(diffuseColor * (1 - shadowIntensity) + diffuseColor * shadow * shadowIntensity, 1.0); return finalColor; }使用步骤
- 将上述逻辑整合到你的物体Shader中(替换原有片段着色器的颜色混合部分)
- 在材质面板中设置
_GroundY(地面Y值)、_MaxHeight(比如设为2,即物体低于2单位时开始增强阴影) - 给所有下落立方体使用该材质,即可实现每个物体根据自身高度独立调整阴影强度
方法二:URP/HDRP专属:脚本+材质参数联动
如果使用URP或HDRP,可以通过脚本实时更新物体材质的阴影强度参数,简化Shader修改:
C#脚本代码
using UnityEngine; public class ShadowIntensityByHeight : MonoBehaviour { public float groundY = 0f; public float maxHeight = 2f; private Renderer _renderer; private Material _material; void Start() { _renderer = GetComponent<Renderer>(); _material = _renderer.material; } void Update() { // 计算当前物体高度与临界高度的比例 float intensityRatio = Mathf.InverseLerp(maxHeight, groundY, transform.position.y); // 将比例传递给材质的自定义参数(需在Shader中提前定义_ShadowIntensity) _material.SetFloat("_ShadowIntensity", intensityRatio); } }Shader适配
在URP/HDRP的Shader中,将阴影采样结果乘以_ShadowIntensity参数即可,例如:float _ShadowIntensity; // ... float shadow = SHADOW_ATTENUATION(i) * _ShadowIntensity;
注意事项
- 若地面不是平面,可通过射线检测获取物体下方的地面高度,替代固定的
groundY值 - 使用
smoothstep或InverseLerp可让阴影强度的过渡更自然,避免出现生硬的突变 - 确保所有下落物体的Shader/材质都配置了对应的参数,避免遗漏
内容的提问来源于stack exchange,提问作者DaSoliman
相关产品推荐
相关产品推荐

