PVS BSP
链接:https://www.zhihu.com/question/38060533/answer/84432973
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
传统标准PVS
标准 PVS其实就是两步:
1. 先求解简易模型:减面,枚举模型上每个顶点,找到一个点使得删除该顶点,模型变形最小,不停的寻找并删除影响最小的点直到模型变形超过一定阀值。最终求解出简易场景模型,为第二步计算做准备。
2. 划分成小的三维格子,再格子里面均匀或随机选取 N个采样点做为摄像机位置,每个采样点 360度全方向做一定数量的射线出去,和场景中的模型判断交点,求解出该采样点的PVS,然后合并格子里N个采样点的结果为该格子的PVS。有离线计算好的,也有实时计算摄像机周围空间未计算格子的,等摄像机移动到那里时已经计算好了,无外乎精度不同。实际绘制时将所在格子的PVS提取出来再做一次视锥剔除就行。
-----
误差:当然有,有些游戏从室外某些堆叠的山石间隔处本来是可以看到后面的东西的,但是换个角度有时候就看不到了,再往前走两步又看得到了,这些效果在游戏里面很常见,其实就是PVS求解不精确的问题。
优化:更小的格子划分,格子内更密集的采样点,同采样点内更密集的射线模拟,多计算一下,可以解决大部分问题。相邻格子的PVS集合如果差异不大可以归并(比如基于八叉树的格子归并),降低存储空间。
BSP:如果场景完全使用bsp进行构建的话,pvs的计算可以基于bsp的叶子节点进行。
精确性:QA测试或者美术检查的时候在场景中主要位置多跑跑,发现这种问题就在编辑器里手动更改一下pvs结果。其实主要位置跑完,每跑一个位置四处看看,也就差不多了。
这是标准的 PVS做法。
光线投射子划分
将场景内相交的多边形进行切割,保证场景内的三角形没有相交(如bsp),将屏幕分成8x8的像素网格,做8x8条从视点开始的射线出去即可,这样做能保证比较高效。然后对光线进行碰撞检测看光线落到哪个多边形上。如果相邻射线没有落在同一个三角形上,那么以这两条射线的中点再做出一条新的射线出去,直到相邻射线落在相同的三角形上或者同一个像素上。这样相交多边形中围绕每束光线的多边形基本都能被绘制了。性能很好但存在一定误差,两束光线中间极小的多边形可能被错过。
光栅化线段遮挡法
不同于光栅化z,光栅化z计算量大些,这只是将待渲染多边形光栅化为有左右两个端点的水平扫描线,然后与同一行的扫描线进行比较和切割,只保留最靠近摄像机的线段,如果待绘制线段在该像素行比较下来全部被其它更靠近摄像机的线段覆盖了,则该行不可见,三角形所有行不可见则该包围体不可见。光栅化z适合gpu,这个方法更适合cpu,特别适合分辨率很高而多边形数量不算太高的时候,优化方法是x轴均匀分为8个区间,这样可以迅速的定位。
八叉树简易PVS
说道简易版本的 PVS,其实就是八叉树了,这是很多3D引擎的偷懒版本实现:八叉树组织空间,下面接 BSP, Portal,地形四叉树lod,先判断顶层包围盒在不在视锥,不再就直接退出了,再的话,递归八个子节点的包围盒再不再视锥,不再就直接剔除,再的话再在该节点递归下去:

八叉树建立时先将场景放入个唯一的盒子里,然后切成八块,再递归切下去,直到单个节点内多边形数量/模型数量少于阀值。交界处的三角形/模型可以切到两个叶节点里或同时属于两节点。
先全部放一个cube里面,然后切割成八分,递归下去:
继续将节点内多边形数高于阀值的叶子进行切割递归
比如:
最终类似:
切割好以后,按照视锥范围,从顶部开始剔除,不再视锥范围的直接跳过,根本用不着再往下递归它的子节点了。再视锥范围内才往下递归,直到碰到没有子节点的纯粹包含实际多边形集合的叶子节点,然后渲染出来,这是简易PVS方法。
不少3D引擎还停留在这种简陋的做法上,因为实际场景复杂度没上到一定量的话,用它也可以一战,只是有些过于简陋罢了。
上面几个都是一周内能实现的切实可行的计算方法,建议的话先上简陋版本,你的瓶颈如果真的出在这里,octree解决不了,就上其他方法吧。
PVS BSP的更多相关文章
- q3 bsp随笔(2)
看完了q3的port生成,以及pvs的生成 做个记录 由于q3 bsp树生成时,将场景中所有的brush平面都参与, 所以就可用bsp树的分割平面来切分port port从根节点开始,初始windin ...
- 转:场景管理--BSP
对于一个3D引擎来说,最核心的部分应该算是场景组织(scene graph)了,如果这部分你都没有设计好, 那么就别指望开发一个成熟的3D引擎了.为了开发3d引擎,所以我首先就研究这方面的内容,对一个 ...
- 新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树
1. 什么是BSP树 BSP算法的初始数据是一个多边形集,BSP在预处理的时候先在多边形集中选取一个多边形作为支持平面,然后根据这个平面将集合划分成两个部分,每个部分是一个新的子节点,递归进行该过程, ...
- 空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)
目录 网格 (Grid) 网格的应用 四叉树/八叉树 (Quadtree/Octree) 四叉树/八叉树的应用 BSP树 (Binary Space Partitioning Tree) 判断点在平面 ...
- 从BSP模型到Apache Hama
一.什么是BSP模型 概述 BSP(Bulk Synchronous Parallel,整体同步并行计算模型)是一种并行计算模型,由英国计算机科学家Viliant在上世纪80年代提出.Google发布 ...
- Vivado SDK 2014.2 创建新工程后,BSP版本不对的解决办法
问题描述如下: 1. 使用Vivado SDK 2014.2已经创建了工程,但是此时,hdf文件增加了外设,需要重新创建工程以更新SDK中的外设描述: 2. 使用新的hdf创建工程后,发现system ...
- Provisioning Services 7.6 入门到精通系列之一:PVS前期规划
1. Provisioning Services 产品概述 Provisioning Services (简称PVS)采用了一种与传统映像解决方案截然不同的方法,从根本上改变了硬件与依托硬件而运行的 ...
- SAP web 开发 (第二篇 bsp 开发 mvc模式 Part2 )
单击第一个图标,第一个图标突出显示,单击第二个图标,第一个变灰,第二个突出显示,反之一样.单击history读取历史记录. Controller ZCL_SUS_C_ORDER_CHANGE 1. ...
- bsp STEP
Web开发不仅现在比较流行,将来也会.我来谈一下最近bsp application项目的体会吧,属初学者,请各位多多指教. SAP 的web开发方法有很多种,bsp只是其中一种,而bsp开发有可以分 ...
随机推荐
- windows下Mysql5.7.10免安装版配置
免安装配置: 在环境变量 Path 中追加 %mysql_home%\bin; 配置mysql目录下的 my-default.ini 文件,在mysql 根目录下新建 data 文件夹 使用管理员权限 ...
- spring源码解析之AOP原理
一.准备工作 在这里我先简单记录下如何实现一个aop: AOP:[动态代理] 指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式: 1.导入aop模块:Spring AOP:(s ...
- UsePass & GrabPass
[UsePass] The UsePass command uses named passes from another shader. [Syntax] UsePass "Shader/N ...
- laravel phpstorm IDE 代码提示
第一步:在项目的composer.json中添加如下一行 "require": { "laravel/framework": "5.0.*" ...
- Python基础:面向对象基础(二) 继承
子类在继承的时候,在定义类时,小括号()中为父类的名字,父类的属性.方法,会被继承给子类,Python中允许多继承. 多继承 # 父类 Master class Master(object): def ...
- 刷题向》关于一道尺取法的神题目(BZOJ4653)(HARD-)(BZOJ 30题纪念)
不得不说,这也许会是一道长期在我的博客里作为“HARD”难度存在的题 这道题能很好的考验选手的思考能力,但本蒟蒻最后还是听了省队爷讲了之后才会...(默默面壁) 题目里,说对于每一个点,是用当前选出的 ...
- Oracle和Mysql的区别 转载
一.并发性 并发性是oltp数据库最重要的特性,但并发涉及到资源的获取.共享与锁定. mysql:mysql以表级锁为主,对资源锁定的粒度很大,如果一个session对一个表加锁时间过长,会让其他se ...
- C#中接口声明属性,但是提示“接口”中不能有属性。
C#中接口定义属性如下所示: using System; using System.Collections.Generic; using System.Linq; using System.Text; ...
- ubuntu 16.04 nfs服务的搭建
nfs服务是实现Linux和Linux之间的文件共享,nfs服务的搭建比较简单. 现在介绍如何在ubuntu16.04系统中搭建nfs服务,ubuntu的搭建比红帽的还要简单. 1.安装nfs服务 s ...
- centos7.0查看有没有运行mysql
centos7自带是mariadb,一个mysql的变种. 查看有没有安装过:yum list installed mysql*rpm -qa | grep mysql* 安装mysql软件(mari ...