网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 其他技术区 > 游戏开发 >

【URP】[平面阴影]原理与实现

时间:2025-09-02 08:58

人气:

作者:admin

标签:

导读:本文介绍了在Unity URP中实现平面投影阴影的Shader实现方法。通过解析光源位置、方向与平面法线的关系,推导出投影点计算公式,并给出了完整的Shader代码实现。文章详细说明了计算过...

【从UnityURP开始探索游戏渲染】专栏-直达

光源点L0,光源方向L,光源距离要投影的的平面距离d;要投影的平面的向上法线向量TerrainNormal,平面上的任意点TerrainPos;现在要计算出光源投向空间中模型上的点在平面上的平面投影点坐标P。

  • 示意图:
    image.png

计算公式

  • 平面上任意向量与该平面法向量点乘为0: $(p-TerrainPos)·TerrainNormal=0$
  • 平面映射的P点是由光射到顶点延伸得到的: $p=d*L+L0$
  • 由上述两个公式联立方程,带入求解d:
  • $d=((TerrainPos-L0)·TerrainNormal)/(L·TerrainNormal)$

实现要点说明:

  • 使用URP核心库(ShaderLibrary/Core.hlsl)确保兼容性
  • 通过_CBUFFER_START声明材质属性
  • 顶点着色器中实现完整投影公式计算
  • 添加透明度衰减效果增强真实感
  • 使用Transparent渲染队列和混合模式
  • 禁用ZWrite避免深度冲突

使用方式:

  • 创建材质并指定该Shader

  • 通过C#脚本设置_LightPos等参数

  • 将材质应用到需要投射阴影的物体上

  • 确保接收阴影的平面有适当渲染材质

  • PlaneShadow.shader

    Shader "Custom/PlaneShadow"
    {
        Properties
        {
            _ShadowColor("Shadow Color", Color) = (0,0,0,0.5)
        }
    
        SubShader
        {
            Tags { "RenderType"="Transparent" "Queue"="Transparent" }
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
    
            Pass
            {
                HLSLPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    
                struct Attributes
                {
                    float4 positionOS : POSITION;
                };
    
                struct Varyings
                {
                    float4 positionCS : SV_POSITION;
                    float alpha : TEXCOORD0;
                };
    
                CBUFFER_START(UnityPerMaterial)
                float4 _ShadowColor;
                CBUFFER_END
    
                // 外部传入参数
                float3 _LightPos;    // 光源位置L0
                float3 _LightDir;    // 光源方向L(需归一化)
                float3 _TerrainPos;  // 平面上任意点
                float3 _TerrainNormal; // 平面法线(需归一化)
    
                Varyings vert(Attributes IN)
                {
                    Varyings OUT;
    
                    // 计算投影参数d
                    float d = dot((_TerrainPos - _LightPos), _TerrainNormal) / 
                              dot(_LightDir, _TerrainNormal);
    
                    // 计算模型顶点到光源的向量
                    float3 lightToVertex = IN.positionOS.xyz - _LightPos;
    
                    // 计算投影点P = L0 + (d / (L·(V-L0))) * (V-L0)
                    float t = d / dot(_LightDir, lightToVertex);
                    float3 shadowPos = _LightPos + t * lightToVertex;
    
                    // 转换到裁剪空间
                    OUT.positionCS = TransformWorldToHClip(shadowPos);
                    
                    // 根据距离计算透明度衰减
                    OUT.alpha = saturate(1.0 - length(shadowPos - IN.positionOS.xyz) * 0.1);
                    return OUT;
                }
    
                half4 frag(Varyings IN) : SV_Target
                {
                    half4 col = _ShadowColor;
                    col.a *= IN.alpha;
                    return col;
                }
                ENDHLSL
            }
        }
    }
    

【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,????)

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
  • 便捷打包Instant Asset脚本

    便捷打包Instant Asset脚本

    使用说明 将脚本放在Assets/Editor目录下 在需要打包同一个table的资源要放在同一...
  • Tuanjie InstantAsset

    Tuanjie InstantAsset

    InstantAsset InstantAsset 是一套全新的资产解决方案,旨在提升开发者的开发和运行...
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信