您当前的位置: 首页 >  Jave.Lin unity

Unity Shader - Custom Shadow Map (New Version)

Jave.Lin 发布时间:2021-09-30 12:23:45 ,浏览量:3

文章目录
  • 环境
  • Shadow map 思路:
  • 效果
  • Project

环境

Unity : Unity 2019.4.30f1 Pipeline : Built-in RP

之前写过一篇:Unity Shader - Custom DirectionalLight ShadowMap 自定义方向光的ShadowMap

但是因为这篇中的部分模型使用到以前公司的模型,所以DEMO没有公开,这篇,因为项目组之前发现内置 unity shadow map 会导致手机上崩溃,所以考虑自己写一个 shadow map

但是最终发现,如果没有 unity 阴影源码,还是不要重新显示 shadow map 阴影这块,因为有很多问题

之前那篇的 Shadow Map 基于 ClipSpace 下比较深度 我们下面是基于 ViewSpace 下比较深度

Shadow map 思路:
  1. 在 DirectionalLight 同向的 LightCamera 拍下所有需要投影部分的对象 的 ViewZ 到一个ShadowDepthRT
  2. ShadowDepthRT 中的深度传入到每个需要接受阴影的 shader 中
  3. 接受阴影的 shader 中的 顶点着色器,获取正在绘制的顶点坐标转为 LightCamera 下的 View 坐标 ShadowPosOnLightCameraViewSpace,并插值后传入 片段着色器中
  4. 片段着色器中,将 ShadowPosOnLightCameraViewSpace.xy / Camera.orthSize 得到投影面中的 -1, 1 坐标,再转为 0, 1 坐标 作为 ShadowDepthRT 的采样 uv 坐标:ShadowDepthRTUV
  5. ShadowPosOnLightCameraViewSpace.z 就是 fragDepth 就是当前片段的深度
  6. 使用 ShadowDepthRTUV 采样 ShadowDepthRT 中的深度,与正在绘制片段的ShadowPosOnLightCameraViewSpace.z 也就是 LightCamera 下的 ViewZ:ShadowMapDepth
  7. 这时已有 fragDepthShadowMapDepth,如果 fragDepthShadowMapDepth 大,说明片段在阴影中

这其中,第 1 点有些非常致命的问题:

  • 灯光视角下的 LightCamera 如果拍的内容有 LODGroup ,并且在 MainCamera 下显示时 LOD0,但是在 LightCamera 下显示时 LOD1,而 LOD1 是简模,因为减模可能模型表面的深度与 LOD0 的原模型深度不一致,那么可能导致阴影效果异常
  • 在 LightCamera.SetReplacementShader 时,只能替换为一种 shader中 pass 来执行,而不能将不同的 Shader 替换成不同的 shader 中的 pass,什么意思呢,就是如果我有两个渲染对象,一个是石头,不透明的 Opaque,一个是树叶 AlphaTest,如果两个渲染对象的 shader 都替换为一个以 Opaque 方式来绘制阴影RT 的话,那么树叶的 AlphaTest 将不会镂空,导致树叶的投影都是一个一个面片,没有树叶的纹理轮廓的形状,所以正常的话,应该:Opaque 的替换才 Opaque 的 Shadow Caster 对应的 shader,而 AlphaTest 的应该就替换成 AlphaTest 的,如果还有顶点动画的呢?所以啊,最终就是想要每个 原始 shader 都应该有一个 对应的 Shadow Caster 的shader,这也为何 unity 内置 shadow map 功能时,为何 每个 shaderLab 中,如果需要有投影功能的话,就需要提供一个 "LightMode="ShadowCaster" 的 pass tags,这是 Camera.SetReplacementShader API 无法满足功能的源码

基于以上两个问题所在,所以我们就不使用 custom shadow map 的方式了,除非我们有 unity 引擎源码,自己封装:

  • Camera.ReplaceShadowCasterShader 的API解决 Camera.SetReplacementShader 无法满足功能的问题
  • Camera.GetUnionRenderWithOtherCamera 的 API 解决 MainCamera 下显示时 LOD0,但是在 LightCamera 下显示时 LOD1 的 模型深度绘制的问题
效果

在这里插入图片描述

Project

因为是自己的 DEMO,没有什么公司的资源,所以可以公开 DEMO TestingShadowMapNewVer 提取码: yfed

unity 版本:2019.3.8f1 实验场景名:CustomShadowMapScene.unity 渲染管线:builit-in

关注
打赏
1688896170
查看更多评论

Jave.Lin

暂无认证

  • 3浏览

    0关注

    546博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0501s