【Unity】Planar Shadows平面阴影的实现
Plannar Shadows,即平面阴影,是一个适用于平坦地形的假阴影技术。要求阴影的Receiver为平面,Occluder不与其他物体穿插。
实现效果
1.定向光源Planar Shadows
2.点光源Planar Shadows
实现步骤
实现Planar Shadows,这里主要考虑两种光源,定向光和点光源两种十分常用的光源类型。实现Planar Shadows的核心就是推导两种光源的投影矩阵,为了简化矩阵,将xz平面(y=0)作为Receiver平面。
顶点着色器核心代码如下:
1 v2f vert(a2v v) 2 { 3 v2f o; 4 o.uv = v.uv; 5 half3 wordPos=mul(unity_ObjectToWorld,v.vertex).xyz; 6 //投影:中心投影(透视投影,点光源),平行投影 7 //平行投影:斜投影(定向光),正投影 8 9 half3 l=_WorldSpaceLightPos0.xyz; 10 //透视投影矩阵:将点光源投影到xz平面 11 half4x4 Projection=half4x4( 12 l.y,-l.x,0,0, 13 0,0,0,0, 14 0,-l.z,l.y,0, 15 0,-1,0,l.y 16 ); 17 //斜投影矩阵 18 // half4x4 Projection=half4x4( 19 // l.y,-l.x,0,0, 20 // 0,0,0,0, 21 // 0,-l.z,l.y,0, 22 // 0,0,0,l.y 23 // ); 24 half4 shadowPos=mul(Projection,half4(wordPos,1)); 25 shadowPos.x/=shadowPos.w; 26 shadowPos.z/=shadowPos.w; 27 shadowPos.y=_HeightBias; 28 o.pos=UnityWorldToClipPos(shadowPos); 29 return o; 30 }
1.额外的阴影Pass
需要在Shader中,常规渲染Pass外增加新的用于Planar Shadows的额外的渲染Pass。
2.推导定向光和点光源的投影矩阵
定向光的投影类型为斜投影,点光源的投影类型为中心投影,需要提前推导出投影矩阵。为了条理清晰,在顶点着色器中进行了矩阵的计算。实际上,可以预计算矩阵然后脚本传递给Shader。
3.矩阵变换
首先将顶点变换到世界空间,然后进行投影变换。由于使用齐次坐标系,需要除w分量来得到正确的结果。
_WorldSpaceLightPos0——是Unity内置着色器变量,在光源为定向光的情况下,xyz分量表示方向,w分量为0,在光源为点光源的情况下,xyz分量表示位置,w分量为1。
_HeightBias——用来解决深度冲突造成的显示错误。
效果优化
以上的步骤虽然完成了阴影的形式上的正确,但仍然有优化的空间。接下来介绍使用模板缓冲,实现更优的效果。
优化效果如下:
上图实现了阴影边缘裁剪和半透明的效果。
1.边缘裁剪
为了实现边缘裁剪的效果,这里用到了模板缓冲,用于Mask掉超出Receiver边缘的阴影像素。
首先,在Receiver的Shader中,添加模板缓冲的代码:
1 Stencil { 2 Ref 1 3 Comp always 4 Pass replace 5 }
这段代码的用处是,将模板值1写入到模板缓冲中,即Receiver覆盖像素位置的对应模板缓冲区的模板值均为1。
然后在我们Occluder的Shader中,将Queue值调整为Receiver的Queue+1,同时添加一下的代码:
1 Stencil { 2 Ref 1 3 Comp equal 4 Pass keep 5 }
这段代码的用处是,绘制阴影像素的模板值为1,与深度缓存中已有的模板值比较,如果相同的话,那就保持缓冲区值不变,模板测试通过,像素将被绘制。关闭深度缓冲写入的意义是使得渲染按照先渲染Receiver然后Occluder的顺序,让Receiver的模板值先写入模板缓冲中。
2.半透明
如果我们直接对阴影进行半透明着色,会发现在简单物体上效果还可以。但是在复杂的模型上,有很大的问题,如下图所示:
因此,我们为了解决这个问题,需要用模板缓冲,来保证每个像素被绘制一次。
做法很简单,除了对一些透明的相关设置外,需要对Occluder的模板缓冲代码进行修改。
1 Stencil { 2 Ref 1 3 Comp equal 4 Pass incrWrap 5 Fail keep 6 }
这段代码的和上面的不同是,如果模板测试通过,将模板缓冲中的模板值+1,像素被绘制。这样的话,如果一个重叠像素要被绘制,因为模板值+1=2,不通过模版测试(条件为Equal),并不会被绘制。
小结
虽然实现了阴影的正确投射,以及边缘裁剪和半透明问题,现在的效果于Unity中Hard Shadow的效果已经十分接近。对于对于如何实现软阴影(本影+半影),希望有较好的解决方案。
转载于:https://www.cnblogs.com/jaffhan/p/7645475.html
【Unity】Planar Shadows平面阴影的实现相关推荐
- Real-Time Rendering——7.1 Planar Shadows平面阴影7.1.1 Projection Shadows投影阴影
7.1 Planar Shadows平面阴影 A simple case of shadowing occurs when objects cast shadows onto a planar sur ...
- 2d shader unity 阴影_【Unity Shader】平面阴影(Planar Shadow)
来介绍一种适用于移动平台的高性能实时阴影解决方案--平面阴影(Planar Shadow). 由于Unity内置的实时阴影实现方式是屏幕空间阴影贴图(Screen Space Shadow Map)非 ...
- Unity Shader - Planar Shadow - 平面阴影
文章目录 整体运行效果 思路 Shader 问题 Z-Fighting,解决:按法线方向偏移一丢丢 绘制 Alpha 混合重叠,解决:使用 stencil buffer 来规避 为何出现这个问题 解决 ...
- Unity Shader 麻将平面阴影高光
做了一个麻将高光和阴影的材质,第一个shader,纪念一下~直接贴代码 // 高光在第一个pass,阴影在第二个pass // Upgrade NOTE: replaced '_Object2Worl ...
- 8.3实例程序:平面阴影
在场景中被灯光照射的地方会产生阴影,这将使场景变的更真实.在这一部分我们将演示怎样实现平面阴影,即在平面上的阴影(如图8.5). 使用这种阴影只是一种权宜之计,虽然它增强了场景的真实效果,但是这并不是 ...
- Unity SOFT SHADOWS WITH PCSS
这里是引用 https://blog.csdn.net/kevin_dust/article/details/51903101 http://developer.download.nvidia.com ...
- Unity中的半透明阴影
Unity中的半透明阴影 在Unity中渲染半透明阴影可以使用Unity提供的dither texture.在这之前,先考虑一般半透明物体的渲染流程: 设置render queue为Transpare ...
- Planar Isotropic平面各向同性
Isotropic各向同性 简单的说各向同性就是说物质在各个方向保持同样性质的特性,就想一根金属导线无论是正接反接还是侧接,都能导电,而且电阻等电性参数保持相同. Planar Isotropic平面 ...
- Unity URP Planar reflection 平面反射
利用双休天写的,代码和shader还有不少问题 修复中.... 一开始是用模板测试和后处理写的,后面改成屏幕坐标,更方便了,加入到我的水体康康 主要思想是动态创建一个翻转的反射摄像机 ,但是不打开这个 ...
最新文章
- @responseBody和@RequestBody
- Jquery操作Cookie取值错误的解决方法
- append 换行_代码风格:答应我,让括号换行吧!!
- JS入门之Date对象
- 可编程CDN – EdgeScript应用场景、语言速览和实操演示
- 彻底搞懂javascript中的match, exec的区别
- 如何解决JDK的安装路径中有空格的情况
- git显示分支关系图
- paip..net代码生成器使用总结
- java多线程知识点之wait和sleep的区别
- qt自定义QtWidgets
- EndnoteX9下载并安装
- 常用汉字2504个(无重复)
- 程序员学习必备书单汇总,超全!
- 06_因果图法、判定表法、场景法
- 实行计算机远程网上录取.啥意思,河北高考今年继续实行计算机远程网上录取...
- 作恶可以,但请有底线!
- linux之getcwd函数解析,Linux 中C语言getcwd()函数的用法
- matlab bar3 颜色,matlab中怎么控制柱状图标注的颜色?
- MPB:青岛大学苏晓泉组分享基于分类学和系统发育的宏基因组比较DMS算法
热门文章
- 雷赛运动控制卡_EeIE智博会展商推荐雷赛智能—智能装备运动控制领域的知名品牌和行业领军企业...
- 数组的最长平台c语言,2010台湾省C语言版高级
- 小辣椒2019_小辣椒红辣椒7X尊享版(6GB 64GB)参数大全,好便宜的联发科手机
- php root 启动,php-fpm如何以root身份启动
- eclipse 摁住ctrl 键卡死
- tdd干扰波形_LTE常见干扰排查(中国移动)
- android流程化步骤样式,Android RecyclerView 解析之绘制流程篇
- mac 上安装Homebrew
- html冷门标签,html 冷门
- java压缩流的用法_Java对压缩包的操作(解压缩)