作者:韦易笑
链接: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的更多相关文章

  1. q3 bsp随笔(2)

    看完了q3的port生成,以及pvs的生成 做个记录 由于q3 bsp树生成时,将场景中所有的brush平面都参与, 所以就可用bsp树的分割平面来切分port port从根节点开始,初始windin ...

  2. 转:场景管理--BSP

    对于一个3D引擎来说,最核心的部分应该算是场景组织(scene graph)了,如果这部分你都没有设计好, 那么就别指望开发一个成熟的3D引擎了.为了开发3d引擎,所以我首先就研究这方面的内容,对一个 ...

  3. 新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树

    1. 什么是BSP树 BSP算法的初始数据是一个多边形集,BSP在预处理的时候先在多边形集中选取一个多边形作为支持平面,然后根据这个平面将集合划分成两个部分,每个部分是一个新的子节点,递归进行该过程, ...

  4. 空间划分的数据结构(网格/四叉树/八叉树/BSP树/k-d树/BVH/自定义划分)

    目录 网格 (Grid) 网格的应用 四叉树/八叉树 (Quadtree/Octree) 四叉树/八叉树的应用 BSP树 (Binary Space Partitioning Tree) 判断点在平面 ...

  5. 从BSP模型到Apache Hama

    一.什么是BSP模型 概述 BSP(Bulk Synchronous Parallel,整体同步并行计算模型)是一种并行计算模型,由英国计算机科学家Viliant在上世纪80年代提出.Google发布 ...

  6. Vivado SDK 2014.2 创建新工程后,BSP版本不对的解决办法

    问题描述如下: 1. 使用Vivado SDK 2014.2已经创建了工程,但是此时,hdf文件增加了外设,需要重新创建工程以更新SDK中的外设描述: 2. 使用新的hdf创建工程后,发现system ...

  7. Provisioning Services 7.6 入门到精通系列之一:PVS前期规划

    1.  Provisioning Services 产品概述 Provisioning Services (简称PVS)采用了一种与传统映像解决方案截然不同的方法,从根本上改变了硬件与依托硬件而运行的 ...

  8. SAP web 开发 (第二篇 bsp 开发 mvc模式 Part2 )

    单击第一个图标,第一个图标突出显示,单击第二个图标,第一个变灰,第二个突出显示,反之一样.单击history读取历史记录. Controller ZCL_SUS_C_ORDER_CHANGE 1.   ...

  9. bsp STEP

    Web开发不仅现在比较流行,将来也会.我来谈一下最近bsp  application项目的体会吧,属初学者,请各位多多指教. SAP 的web开发方法有很多种,bsp只是其中一种,而bsp开发有可以分 ...

随机推荐

  1. oracle按照时间过滤

    select * from uc.uc_customer a where to_char(a.create_date,'YYYY-MM-DD')>'2017-07-21'

  2. 【301】IDL与C#混合编程

    目录: 一.COM_IDL_CONNECT 1. 添加组件 2. 组件初始化 3. 功能调用 4. 数据传递 二.IDLDrawWidget组件 C# (C Sharp)是微软公司在2000年6月发布 ...

  3. Linux重置管理员密码

    对于一些非专业的Linux运维工程师或者偶尔使用Linux系统的学习者而言,比如我,经常会碰到忘记密码的尴尬,那这时候,快速的重置密码就相当重要了.废话不多说,今天我们就一起来学习一下如何快速重置密码 ...

  4. Promethus安装指南

    由于Prometheus是go语言写的,所以不需要编译,安装的过程非常简单,仅需要解压然后运行.Prometheus官方下载地址:https://prometheus.io/download/ 安装P ...

  5. textarea文本域的高度随内容的变化而变化

    用css控制textarea文本域的高度随内容的变化而变化,不出现滚动条. CSS代码: 复制代码 代码如下: .t_area{ width:300px; overflow-y:visible } & ...

  6. Perl 获取时间函数

    Perl 时间日期 Perl中处理时间的函数有如下几种:    1.time() 函数:返回从1970年1月1日起累计的秒数    2.localtime() 函数:获取本地时区时间(多用这个)    ...

  7. Spark角色介绍及spark-shell的基本使用

    Spark角色介绍 1.Driver 它会运行客户端的main方法,构建了SparkContext对象,它是所有spark程序的入口 2.Application 它就是一个应用程序,包括了Driver ...

  8. cardBattle游戏启动场景设计

  9. 解剖Nginx·模块开发篇(1)跑起你的 Hello World 模块!

    1 学习 Nginx 模块开发需要有哪些准备? 需要的预备知识不多,有如下几点: 有过一些 C 语言的编程经历: 知道 Nginx 是干嘛的,并有过编写或改写 Nginx 的配置文件的经历. OK,就 ...

  10. 647. Palindromic Substrings 互文的子字符串

    [抄题]: Given a string, your task is to count how many palindromic substrings in this string. The subs ...