前面几篇阴影相关的:

https://www.cnblogs.com/crazii/p/5443534.html 这个是在做bh3 MMD角色自阴影时的笔记

https://www.cnblogs.com/crazii/p/7227269.html 这个是blade的CSM笔记和相关思考

这次在项目里对unity又做了新的改进,  整体思路还是沿用第二篇的方式:

1.使用足够长/远的视锥(view/projection)剔除场景 (渲染shadow map总是要剔除的,所以先用足够远的视锥,保证所有可见阴影的shadow caster都在)

2.根据剔除后的包围盒,代替场景包围盒,做凸包体相交
3.重新计算并设置渲染用的view/projection

也就是说(shadow) scene culling和rendering用的view/projection是不一样的,后者基于前者的culling结果重新计算。

记录几个要点:

1. shadowmap剔除以后的结果, 可以是一组世界空间的caster(的包围盒), 变换到光空间, 再合并; 也可以是他们合并后的结果, 再变换到光空间. 建议使用前者, 因为合并后包围盒已经变大, 再做空间变换,会导致包围盒(AABB)变更大. blade为了偷懒使用了后者, 最近在unity的项目里里使用了前者.

2.一般CSM的cascade判断,可以简单的用场景相机的视距分割. unity使用的是球体. 最好的方式是用光视锥(Light Frustum OBB, xy without z), 几个cascade的光视锥方向一样. 比如4个cascade: shader里需要光空间UP,光空间RIGHT, 然后4个viewpoint和4个视锥的width, height. 按球体/距离划分很容分到质量更低的cascade, 但是前一级很可能有深度可以采样. 极端的例子: 光接近平行地面的时候, 影子被拉很长, 相机近处的物体投影很远, 如果按光视锥OBB, 近处物体的影子就只会采样cascade0, 不会采样更低的cascade. 另外, receiver的范围可以忽略, 只考虑caster的范围, 否则为了显示拉长的阴影, 使用更大的阴影范围, 阴影质量也会下降.
另外OBB检测会多出4个dot指令和一组比较指令, 对于收益来说时可以接受的

比如下图里shadow range只有10, sm利用率几乎沾满整个cascade 0. 实际投影距离却很长,30多米, 质量也没有降低:

3.基于第2点, OBB是完全契合shadowmap视锥的, 所以只要在OBB内的receiver,一定可以在对应的cascade采样到阴影, 所以如果一个物体的阴影完全渲染在cascade0里时, 就可以不用再画到cascade1里. 这个优化可以根据caster的个数来决定要不要做, 比如一个只有10个caster物体的手游, 可以考虑迭代检测. 可能出现的结果是: cascade0里有2个object, cascade1里只有1个object, 又因为紧凑包围盒, 所以cascade1的质量比cascade0还要高.

4.一直在说的重新计算紧凑包围盒, 不仅在blade里做了实现和验证, 在mmd视频渲染里得到了验证, 也在实际项目里也得到了验证, 特别是有CSM时, cascade0(视点近处几米内)的质量会有明显提升, sm利用率变高, 阴影会占据大部分区域.

下面时图示 (光视锥的视角):

5. 在考虑使用light space的投影体的bounding volume, 用stencil标记receiver的范围(类似shadow volume的标记方式), 圈出来的部分才做阴影采样, 这样对于soft shadow和pcss可以有优化. 但是依赖于early stencil, 也要看游戏场景是否适用. 目前6s测试, 1.2ms=>0.6ms, 节省了0.6ms, 用unity tent7x7 softshadow, 4=>1.5ms 省了2.5ms, 60%左右, 目测和阴影站整个地面的比例有关, 符合优化的原理. 根据理论来推测, 对于地面阴影占据绝大多数的情况, 优化不明显.

[工作积累] shadowmap 改进的更多相关文章

  1. [工作积累] shadow map问题汇总

    1.基本问题和相关 Common Techniques to Improve Shadow Depth Maps: https://msdn.microsoft.com/en-us/library/w ...

  2. [工作积累] Google/Amazon平台的各种坑

    所谓坑, 就是文档中没有标明的特别需要处理的细节, 工作中会被无故的卡住各种令人恼火的问题. 包括系统级的bug和没有文档化的限制. 继Android的各种坑后, 现在做Amazon平台, 遇到的坑很 ...

  3. [工作积累] 32bit to 64bit: array index underflow

    先贴一段C++标准(ISO/IEC 14882:2003): 5.2.1 Subscripting: 1 A postfix expression followed by an expression ...

  4. [工作积累] bitfield

    ISO/IEC 14882:2003: 9.6 Bit-fields [class.bit] A member-declarator of the form identifieropt : const ...

  5. [工作积累] GCC 4.6 new[] operator内存对齐的BUG

    对于用户没有定义dctor(包括其所有成员)的类来说, new CLASS[n] 可能会直接请求sizeof(CLASS)*n的空间. 而带有dctor的 类, 因为delete[]的时候要逐个调用析 ...

  6. [工作积累] UE4 并行渲染的同步 - Sync between FParallelCommandListSet & FRHICommandListImmediate calls

    UE4 的渲染分为两个模式1.编辑器是同步绘制的 2.游戏里是FParallelCommandListSet并行派发的. mesh渲染也分两类,static mesh 使用TStaticMeshDra ...

  7. [工作积累] D3D10+ 中 Pixel Shader 的input semantic和参数顺序

    由于semantic的使用,我们有理由相信 vertex shader的output 和 pixel shader的input是按照semantic来匹配的,而跟传入顺序无关.印象dx9时代是这样. ...

  8. linux-日常工作积累

    Linux常用命令之envsubst https://blog.csdn.net/banche163/article/details/101369495 Linux中的EAGAIN含义 https:/ ...

  9. HAL层Camera模块Dump图片--工作积累

    Camera的raw data一般都是YUV420的格式,数据的特点是: YUV 4:2:0采样,每四个Y共用一组UV分量 YUV420格式: 先Y,后V,中间是U.其中的Y是w * h,U和V是w/ ...

随机推荐

  1. 简单的 vector

    #pragma once #include <memory.h> #include <stdlib.h> #include <iostream> using std ...

  2. 《RabbitMQ》如何保证消息不被重复消费

    一 重复消息 为什么会出现消息重复?消息重复的原因有两个:1.生产时消息重复,2.消费时消息重复. 1.1 生产时消息重复 由于生产者发送消息给MQ,在MQ确认的时候出现了网络波动,生产者没有收到确认 ...

  3. 5、Java 修饰符

    引言:Java的修饰符根据修饰的对象不同,分为类修饰符.方法修饰符.变量修饰符,其中每种修饰符又分为访问控制修饰符和非访问控制修饰符. 1.访问控制修饰符的总结 四个关键字:public.protec ...

  4. Vue3 为何使用 Proxy 实现数据监听

    博客地址:https://ainyi.com/93 vue3 响应式数据放弃了 Object.defineProperty,而使用Proxy来代替它 我们知道,在 vue2 中,实现数据监听是使用Ob ...

  5. XCTF-WEB-新手练习区(9-12)笔记

    9:xff_referer X老师告诉小宁其实xff和referer是可以伪造的. 界面显示需要我们 添加X-Forwarded-For:123.123.123.123 添加Rerferer:http ...

  6. C#LeetCode刷题之#27-移除元素(Remove Element)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3624 访问. 给定一个数组 nums 和一个值 val,你需要原 ...

  7. shazidouhui的使用体验

    这个软件有三个界面,一个是我的,一个是已批改作业,一个是未完成作业,但是,我不知道怎么用除了“我的”这个界面以外的其他两个界面,这一点还是需要优化优化,另外就是登陆界面确实还存在一点问题,有待改进.

  8. Spring Boot 2.x基础教程:使用集中式缓存Redis

    之前我们介绍了两种进程内缓存的用法,包括Spring Boot默认使用的ConcurrentMap缓存以及缓存框架EhCache.虽然EhCache已经能够适用很多应用场景,但是由于EhCache是进 ...

  9. 计算机网络要点---Http

    计算机网络要点---Http 1.工作流程 一次HTTP操作称为一个事务,其工作过程可分为四步: 首先客户机与服务器需要建立 TCP 连接.只要单击某个超级链接,HTTP的工作开始. 建立连接后,客户 ...

  10. iNeuOS工业互联平台,WEB组态(iNeuView)集成rtmp和websocket视频元件,支持海康、大华等摄像头实时显示视频

    目       录 1.      概述... 1 2.      平台演示... 2 3.      硬件摄像头... 2 4.      视频流协议转换管理... 2 5.      组态视频元件 ...