Unity - Projector - 实时[假]阴影

本文探讨了在Unity中使用Projector和自定义Shader实现阴影的两种方法,包括真投影和假投影的思路,以及它们的优缺点。在解决Unity内置ShadowMap可能导致的崩溃问题时,提出了使用Projector组件和自定义替换Shader来创建假阴影的解决方案,但这种方法存在投影穿透的问题。文章还对比了其他类型的阴影实现,如shadowmap、shadowvolume和raymarching,并提供了相关Shader代码示例。


制作原因

因为项目运营中,有部分崩溃的日志显示的是,ShadowMap Jobs 中的 GetLocalKeywords 导致崩溃

当时有同学提出的:

  • 可以尝试更新 unity 的版本,因为在网上查了,也有人遇到类似的问题,还说了部分 unity 的版本是修复了的,所以才提议可以升级 unity 版本,出问题的时候我们使用的是:unity 2019 4.0f1 的版本的,这个也是我比较推荐的方式
  • 可以自己重写一个简单的 shadow map,但是 shadow map 会增加大量 DC,但是基于 unity 先用的一些 API 来制作的话,会有很多限制问题
  • 可以使用 shadow projector ,而 unity built-in 管线中的 projector 组件只是和 projector 有碰撞的才会重绘被投影的网格,所以相对 shadow map 来说只是少了另一份 render texture 的内存消耗,但起码可以绕过 unity 内置 projector 崩溃的问题
    • 但是projector 方式也有很多限制
      • 一般固定视角
      • 不会有高于投影物体的场景
      • 阴影并不会有遮挡的情况
        • 即投影穿透,假设有 A,B,C 三个物体,A 里 projector 最近,看似挡住了 B,C 的投影效果,但是 B,C 如果与 projector 有碰撞都会有投影效果,这就是投影穿透

(但是由于这个 Projector [假]阴影显示太多,最后我们没去使用该方案,但是预研的过程当作是学习,所以记录在此博客)


其他阴影

一般阴影又多种方式实现:


Projector 的思路

  • 将所有与 Projector 的 OOB 有碰撞的,都有会有投影效果
  • 被投影的物体都会重新绘制一次,使用 投影材质来绘制
  • 将被投影物体的逐片段坐标作为 投影器下的投影面坐标转为 投影时的 cookie 纹理采样坐标
  • 使用 投影面的 uv 坐标采样 cookie 纹理作为像素颜色,至于如何混合,就是根据投影器使用的 材质的混合系数配置来决定,如:Blend SrcAlpha OneMinusSrcAlpha 就是混合透明度的方式叠加上去

Projector [假]阴影的思路

  • 先得有一个 DirectionalLight 方向光,关闭 DirecitonLight 的 shadow
  • 创建 Shadow Projector 添加上 Projector 组件,transform.forward 与 DirectionalLight 一致
  • 创建 Shadow Camera 添加上 Camera 组件,transform.forward 也与 DirectionalLight 一致
  • 将 Shadow Camera.ReplacementShader 替换渲染视角中的物体在一张 ShadowRT 上
  • 将 ShadowRT 纹理给到 Shadow Projector 上的 Projector 组件的材质中的 Cookie 纹理

ReplacementShader 都替换为以下 shader 渲染:

// jave.lin 2021/08/17
// 绘制到 Projector Cookie RT 上的 shader

Shader "Test/Draw2ProjCookieRT"
{
   
   
    SubShader
    {
   
   
        Tags {
   
    "RenderType"=
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值