当前位置: 首页 > news >正文

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

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

实现原理

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

计算公式

  • 平面上任意向量与该平面法向量点乘为0: (p−TerrainPos)⋅TerrainNormal=0(p−TerrainPos)⋅TerrainNormal=0
  • 平面映射的P点是由光射到顶点延伸得到的: p=d∗L+L0p=d∗L+L0
  • 由上述两个公式联立方程,带入求解d:
  • d=((TerrainPos−L0)⋅TerrainNormal)/(L⋅TerrainNormal)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 OneMinusSrcAlphaZWrite OffPass{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;    // 光源位置L0float3 _LightDir;    // 光源方向L(需归一化)float3 _TerrainPos;  // 平面上任意点float3 _TerrainNormal; // 平面法线(需归一化)Varyings vert(Attributes IN){Varyings OUT;// 计算投影参数dfloat 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开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

http://www.dtcms.com/a/347493.html

相关文章:

  • 如何使用和优化SQL Server存储过程:全面指南
  • 论文阅读:arxiv 2025 Can You Trick the Grader? Adversarial Persuasion of LLM Judges
  • 【数据分享】地级市对外开放程度(2002-2021)-有缺失值
  • SpringBoot自动装配原理深度解析
  • 【LeetCode 热题 100】300. 最长递增子序列——(解法一)记忆化搜索
  • mmap映射物理内存之四内核cache同步
  • 后台管理系统-14-vue3之tag标签页的实现
  • JEI(Journal of Electronic lmaging)SCI四区期刊
  • TypeScript的接口 (Interfaces)讲解
  • Python 版本与 package 版本兼容性检查方法
  • 定时任务——ElasticJob原理
  • ChipCamp探索系列 -- 4. Intel CPU的十八代微架构
  • 【背诵2025】测试
  • 数据结构与算法——树和二叉树
  • 【科研绘图系列】浮游植物的溶解性有机碳与初级生产力的关系
  • 大麦APP抢票
  • 数据结构 之 【AVL树的简介与部分实现】(部分实现只涉及AVL树的插入问题,包括单旋((右单旋、左单旋))、双旋(左右单旋、右左单旋)等操作)
  • 国家自然科学基金(国自然基金)申请技巧详解
  • materials studio中的两种坐标系
  • 基于RISC-V架构的国产MCU在eVTOL领域的应用研究与挑战分析
  • leetcode(同向双指针 滑动窗口)209.长度最小的子数组 713.乘积小于K的子数组 3.无重复字符的最长子串
  • 随机森林1
  • 12 SQL进阶-锁(8.20)
  • 我从零开始学习C语言(14)- 基本类型 PART1
  • FRP 内网穿透全流程部署指南 (Windows/Linux)
  • 不必使用 == 和 ===,更严格的相等性判断 API 来了
  • DFT计算入门(materials studio)---Ni金属表面,几何优化
  • 求职推荐大数据可视化平台招聘系统 Vue+Flask python爬虫 前后端分离
  • 【KO】前端面试四
  • leetcode26:删除有序数组中的重复项Ⅰ(快慢指针解法)