jjzjj

c++ - 行星渲染的最佳 CLOD 方法

coder 2023-11-16 原文

我目前正在研究我的论文,它是一个渲染行星大小地形的引擎。

我还在完成我的研究,我遇到了很多关于这个主题的东西,问题是我无法决定我应该使用哪种 LOD 方法。

我知道 Ulrich 的 geomipmapping、几何裁剪图 (GPU) 和分块 LOD,它们在大型地形上效果很好,可用于渲染立方体的 6 个面,然后通过 this method 将立方体“球化”。并且我了解如何使用 C++/OpenGL/GLSL 在 GPU 上实现所有这些方法(使用 ROAM 之类的方法或任何其他不使用立方体的方法是我无法实现的,因为纹理是一种痛苦)。

所以,我没有时间实现所有的方法,看看哪种方法是最好的,更适合行星尺度,我在这里问是否有人进行过这种比较并帮助我决定哪种方法我应该实现和使用(我的导师有点疯狂,想让我用二十面体做点什么,但除非使用 ROAM,否则我无法理解这种方法)

无论如何,如果您能帮助我决定或有任何其他建议或方法,我将不胜感激。一个条件是该方法应该能够实现 GPU 端(至少是大部分)以防止 CPU 瓶颈。

另一个要求是,我知道在获取地形中的大量细节时存在有关浮点数精度的数值问题,我不知道如何解决它,我在论坛上阅读了一个解决方案,但无法理解如何解决实现,我忘记了那个线程,我想知道如何解决这个精度问题。

PD:对不起我的英语。

[编辑] 我目前正在阅读一些矩阵变换来解决浮点精度、z-fighting 问题、使用动态 z 值的视锥体剔除以及块的数据表示(使用带浮点数的补丁空间及其在世界坐标中的位置作为double)所以我想我可以轻松解决精度问题。我仍然需要将 LOD 方法与您的意见和建议进行比较,以决定哪种方法更适合该项目。考虑到实现难度 vs 视觉质量 vs 性能,我想要最好的。

我忘了提及的是,这一代是混合的,我的意思是,我应该能够完全使用 GPU(动态计算的高度)和/或使用基本高度图图像并使用 GPU(顶点着色器)添加细节.纹理将是我稍后会遇到的一个侧面部分,现在我很高兴根据高度仅使用颜色,或者可能使用在片段着色器上生成的某种噪声纹理。

最佳答案

最后,经过大量研究,我可以得出结论,正如之前有人所说,没有普遍的“最佳”方法。但是我的研究使我了解了以下事情:

根据您最终将使用的网格:

  • 球面立方体:任何具有四叉树实现的 LOD 方法都可以正常工作,您只需要注意特殊情况,例如面之间的边界,在这种情况下,您的四叉树必须有一个指向每个级别中相邻面的邻居的指针。
  • 任何其他:我认为 ROAM(较新的 2.0 版或任何其他扩展,如 BDAM、CABTT 或 RUSTIC)会做得很好,但是,这些算法很难使用,需要更多内存,并且比其他使用多维数据集的方法要慢一些。

  • 有许多 LOD 方法可以很好地适应,但我个人的前 5 种方法是:
  • Continous Distance-Dependent LOD (CDLOD)
  • GPU Based Geomety Clipmaps (GPUGCM)
  • Chunked LOD
  • 使用 OpenGL GPU segmentation 渲染地形(书籍:OpenGL Insight,第 10 章)
  • Geometrical MipMapping

  • 每一种都提供了一种独特的地形渲染方式,例如,CDLOD 使用着色器(GLSL 或 HLSL)非常容易实现,但也能够在 CPU(对于传统硬件)上实现,但是 Planet Rendering 的目标是爆炸在现代 GPU 上最好,所以当你想压缩你的 GPU 时,GPUGCM 是最好的。它们都适用于基于数据、程序或混合(基于固定数据或高度图的地形以及通过程序工作添加的细节)渲染大型地形。

    也存在基本几何裁剪贴图方法的球面扩展,但存在一些问题,因为高度图的平面样本必须使用球坐标进行参数化。

    另一方面,分块 LOD 非常适合传统硬件,不需要任何 GPU 端计算即可工作,非常适合大型数据集,但无法实时处理程序数据(也许可以进行一些修改)

    使用曲面 segmentation 着色器是另一种技术,非常新,自从 OpenGL 4.x 出来后,在我看来它可能是最好的,但是,我们谈论的是行星渲染,我们遇到了其他方法可以很容易处理的问题,它是关于精度。

    除非您只希望顶点之间的精度为 1 公里,否则请使用曲面 segmentation 着色器。这种方法的真正大地形的问题是抖动有点难以解决(或者至少对我来说,因为我是 segmentation 着色器的新手)。

    Geomipmapping 是一项很棒的技术,它利用了四叉树并且具有较低的投影像素误差,但是,对于行星渲染,您需要设置至少 16 级以上的细节,这意味着您将需要(用于拼接倾倒姿势)一些额外的补丁连接不同的级别并照顾邻居的级别,这可能会很乏味解决,尤其是使用 6 个地形面。

    还有另一种方法,它自己很特别:"Projective Grid Mapping for Planetary Terrain"非常适合可视化,但有其缺点,如果您想了解更多信息,请转到链接。

    问题:
  • 抖动 :当今的大多数 GPU 仅支持 32 位浮点值,这
    不能提供足够的精度来操纵行星尺度地形中的大位置。当观看者放大、旋转或移动时会发生抖动,然后多边形开始来回弹跳。

    对此的最佳解决方案是使用“相对于眼睛使用的渲染”
    GPU”方法。这种方法在《3D Engine》一书中有描述
    Design for Virtual Globe”(我相信你可以在互联网上找到它
    以及)基本上你必须在其中设置所有位置
    在 CPU 上加倍(补丁、剪贴图、对象、视锥体、相机等)
    然后 MV 通过设置其翻译以观众为中心
    到 (0, 0, 0)T 并且 double 以定点编码
    使用两个浮点数的小数(尾数)位表示,低
    并通过某种方法提高(阅读有关使用 Ohlarik 的实现
    和 DSFUN90 Fortran 库)。

    虽然顶点着色器只需要额外的两个
    减法和一次加法,GPU RTE 使顶点数量加倍
    位置所需的缓冲存储器。这不一定要翻倍
    内存要求,除非只存储位置。
  • 深度缓冲精度 : Z-战斗。由于我们正在渲染非常大的地形,在这种情况下:行星,Z 缓冲区必须很大,但是您为 znear 和 zfar 设置的值并不重要,总会有问题。

    由于 Z 缓冲区取决于浮点间隔,而且它也是
    线性(虽然透视投影是非线性的)值接近
    眼睛因缺乏 32 位精度而遭受 Z-fighting
    花车有。

    解决这个问题的最好方法是使用“对数深度
    缓冲”
    http://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html

    对数深度缓冲区提高了深度缓冲区精度
    通过对 zscreen 使用对数分布,远处的物体。它
    用近距离物体的精度换取远距离物体的精度。
    由于我们使用 LOD 方法进行渲染,因此远对象需要更少
    精度,因为它们的三角形较少。

  • 值得一提的是,由于四叉树基础,列出的所有方法(投影网格除外)在进行物理(主要是碰撞)时都非常好,如果您打算制作游戏,这是必须的。

    总之,只需检查所有可用选项,然后选择您觉得更舒适的选项,我认为 CDLOD 做得很好。不要忘记解决抖动和 Z 缓冲区问题,最重要的是:玩得开心!

    有关 LOD 检查的更多信息 this link .

    有关球形立方体的完整演示,请查看 this link .

    有关解决抖动和 Z 缓冲区精度的更好解释,请查看 this book .

    我希望你觉得这篇小评论很有用。

    关于c++ - 行星渲染的最佳 CLOD 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16494699/

    有关c++ - 行星渲染的最佳 CLOD 方法的更多相关文章

    1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

      我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

    2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

      很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

    5. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

      我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

    6. Ruby 方法() 方法 - 2

      我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

    7. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    8. ruby-on-rails - 渲染另一个 Controller 的 View - 2

      我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

    9. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

      我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

    10. ruby - Highline 询问方法不会使用同一行 - 2

      设置:狂欢ruby1.9.2高线(1.6.13)描述:我已经相当习惯在其他一些项目中使用highline,但已经有几个月没有使用它了。现在,在Ruby1.9.2上全新安装时,它似乎不允许在同一行回答提示。所以以前我会看到类似的东西:require"highline/import"ask"Whatisyourfavoritecolor?"并得到:Whatisyourfavoritecolor?|现在我看到类似的东西:Whatisyourfavoritecolor?|竖线(|)符号是我的终端光标。知道为什么会发生这种变化吗? 最佳答案

    随机推荐