【URP】[平面阴影]原理与实现
【从UnityURP开始探索游戏渲染】专栏-直达
实现原理
光源点L0,光源方向L,光源距离要投影的的平面距离d;要投影的平面的向上法线向量TerrainNormal,平面上的任意点TerrainPos;现在要计算出光源投向空间中模型上的点在平面上的平面投影点坐标P。
- 示意图:
![]()
计算公式
- 平面上任意向量与该平面法向量点乘为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开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,)
【URP】[平面阴影]原理与实现的更多相关文章
- DEM山体阴影原理以及算法具体解释
山体阴影原理以及算法具体解释 山体阴影基本原理: 山体阴影是假想一个光源在某个方向和某个太阳高度的模拟下.用过临近像元的计算来生成一副0-255的灰度图. 一.山体阴影的主要參数: 1. 太阳光线的 ...
- 3D模板阴影原理
3D模板阴影原理 1:先从3dsMax中导出一个简单的场景,一个园环,球,平面. 2:园环直接面向光源,园环对球体来说是一个光线的阻挡物,园环在它上面形成阴影,同时,园环和球体对平面来说是光线的阻挡物 ...
- OpenGL平面阴影
几种绘制阴影的方法 在OpenGL中,比较常见的绘制阴影的方法有:shadow mapping,shadow volumes以及一种在红宝书上提及的适合在确定平面上绘制阴影的方法. 平面阴影 在确定的 ...
- 由浅入深学习PBR的原理和实现
目录 一. 前言 1.1 本文动机 1.2 PBR知识体系 1.3 本文内容及特点 二. 初阶:PBR基本认知和应用 2.1 PBR的基本介绍 2.1.1 PBR概念 2.1.2 与物理渲染的差别 2 ...
- CSS3实现图形曲线阴形和翘边阴影
首先,来看看完成之后的效果图: 实现原理 ①曲线阴影实现: 多个阴影重叠,就是正常阴影+曲线阴影 正常情况下,有个矩形有正常的阴影,作为主投影,这时候再定义一个有一定弧度圆角的圆角矩形,然后放在正常矩 ...
- 聊聊 Material Design 里,阴影的那些事儿!
当你的设计师要求你在某个 View 上增加阴影效果,那你只需要认真阅读本文,阴影的问题就不再是问题. 一.前言 设计师的世界,与常人不同,有时候想要扁平化的风格,有时候又想要拟物化的风格.而在 Mat ...
- [UWP]使用GetAlphaMask和ContainerVisual制作长阴影(Long Shadow)
1. 什么是长阴影 前几年扁平化设计(Flat Design)十分流行,后来在扁平化的基础上又流行起了长阴影(Long Shadow).长阴影其实就是扩展了对象的投影,感觉是一种光线照射下的影子,通常 ...
- [UnityShader]unity中2D Sprite显示阴影和接受阴影
首先是效果 要让2D显示阴影,首先假设知道Unity阴影来源(shader中的ShadowCaster) 最简单的方法是,首先从官网下载Sprite-Default.Shader,查看源码 然后复制粘 ...
- MATLAB绘图与图形处理
参考:http://www.cnblogs.com/djcsch2001/tag/MATLAB/ matlab部分写的不错! 7.2 三维图形 7.2.1 三维曲线.面填色命令 命令1 com ...
- LearnOpenGL.PBR.理论
判断一种PBR光照模型是否是基于物理的,必须满足以下三个条件: ()基于微平面(Microfacet)的表面模型.Be based on the microfacet surface model. ( ...
随机推荐
- 8月18日直播预告 | Flink SQL转换Operator流程及源码解析
8月18日晚19点,袋鼠云数栈技术研发团队开发工程师--修竹,将会为大家直播分享<Flink SQL转换Operator流程及源码解析>. 课程内容主要包括以下两点: 1. Flink ...
- update 批量修改sql 记录
update_table 是要修改的表 join_table 是关联另一张表来修改update_table表的字段 update update_table set id= tmp.id from jo ...
- Spring Boot 集成 tess4j 实现图片识别文本
前言 tesseract是一个开源的光学字符识别(OCR)引擎,它可以将图像中的文字转换为计算机可读的文本.支持多种语言和书面语言,并且可以在命令行中执行.它是一个流行的开源OCR工具,可以在许多不同 ...
- AI应用实战课学习总结(7)聚类算法分析实战
大家好,我是Edison. 最近入坑黄佳老师的<AI应用实战课>,记录下我的学习之旅,也算是总结回顾. 今天是我们的第7站,一起了解下聚类算法基本概念 以及 通过聚类算法辅助用户画像的案例 ...
- MCPmarket.cn最全最好用的中文MCP平台:推出全新MCP教程《MCP从0到1》第1课:MCP关键概念与术语详解
MCPmarket.cn 正式推出全新教程<MCP 从 0 到 1>,面向AI爱好者和开发者朋友,零基础友好,帮你系统掌握 MCP(Model Context Protocol,模型上下文 ...
- net core api 跨域 Cors 找不到 “Access-Control-Allow-Origin”
public static void AddCorsSetup(this IServiceCollection services) { services.AddCors(c => { //允许任 ...
- windows11安装linux
安装教程 https://blog.csdn.net/Daisy74RJ/article/details/125483629 可能遇到的问题 如果报错 则参考 WslRegisterDistribut ...
- HDU7458 旅行 题解
前言 感觉是非常优秀的题目,写一篇题解记录一下. HDU-7458 旅行(on Vjudge) 题面 题目描述 有一棵 \(n\) 个结点的无根树,每个结点都有对应的类型 \(c_i\) 和权重 \( ...
- Codeforces Round #705 (Div. 2) AB题解
A. Anti-knapsack 思路:首先比k大的都可以加进来.其次对于小于k的,检验当前集合里面有没有和他相加等于k的,没有的话就可以加进集合.这一步可以覆盖多个数相加的情况. view code ...
- java 中的访问限制
简介 1)仅对本类可见--private 2) 对所有类可见--public 3) 对本包和所有子类可见--protected 4) 对本包可见--默认,不需要修饰符
