用置换映射对球体进行光线追踪

4

我有兴趣开发一个简单的“谷歌地球”类型的应用程序(用于叠加我的自有信息,而不是谷歌那样海量的数据)。我希望它只是一个简单的X11应用程序,可以射线追踪带有位移(地形)信息的球体。射线-球体相交很简单,但当加入位移映射时,我的思路开始变得混乱。

我想知道是否有一种简单的技术可以扩展基本的射线-球体相交以包括位移数据...

4个回答

2

在此输入图片描述

我知道距离第一篇文章已经过去了12年,但是我在这里上传了一个完整的解决方案: https://github.com/ramakarl/just_math

请查看math_displace_sphere样例。它可以在任意细节上对位移球体地形进行光线追踪,而不需要任何网格。代码纯CPU,可以移植到着色器/GPU。采用MIT许可证。

解决方案是沿着射线行进,同时将射线样本点投影回纬度和经度,并对地形纹理进行采样,以确定该样本的位移高度。高度相对于球体中心指定。

伪代码:

for ( ; ray_hgt >= terrain_hgt && ray_hgt <= shell_hgt; ) { 

        sample += ray_dir * dt; 

        ray_hgt = (sample - sphere_center).Length();

        // given sample, compute surface_pnt and lat, long
        ComputeSphereUV ( sample, surface_pnt, lat, long ); 
                
        pixel_val = terrain_map->GetPixelUV ( lat, long ).x;                                    

        terrain_hgt = sphere_radius + pixel_val * terrain_depth;    
}

1
谢天谢地你发了帖子,我的老板对我已经拖延了12年感到非常愤怒! ;) - gct
这是一个非常出色且非常简单的答案。完全值得等待12年。 - Sebastian Gudiño

1
位移映射非常容易 - 只需将球面细分,根据从地图中采样的高度添加偏移量到顶点位置,并对所有部分进行光线追踪。
相机距离球体/地球有多远?如果您离表面很近,那么完全没有必要制作整个“球”,只需要制作一个“高度场”。如果您离得很远(一次查看整个星球),那么即使最高的山也不应该明显改变表面,因此您应该使用简单的凸起映射。还考虑使用组合-粗略的细分是真正被位移的,而残差高度差上使用凸起映射。
但无论如何,我无法想象您为什么要像您描述问题那样进行光线追踪。只需将其划分为三角形并使用OpenGL。您可能不需要任何光线追踪效果。

请看我对Vuk的回复评论,我希望保持地球呈球体表示,这样交叉计算就尽可能简单。OpenGL不适用,因为我们经常希望能够从服务器上通过网络运行事物,而GLX往往会在套接字上出现问题。 - gct

1

你知道这个算法的实际实现吗?我有一个应用程序,我很想尝试一下。 - David Given
嘿,我目前正在尝试实现这个。这是我为参加一门课程而设定的最终项目目标之一(其中一位作者是我的教授,但他没有进行核心写作)。这被证明非常难,但我已经接近成功了。我正在项目上保留进度日志 在这里 。我还没有发布关于高度图的任何内容,因为它还没有完成,但如果我成功了,我会发布一个胜利的条目。到目前为止,我已经基本把形状搞对了,阴影有些不对劲,法线完全偏离了 :| - Fab Castel

0

无论您使用简单的 20 个多边形球体还是复杂的具有 2k 个多边形的球体,光线追踪过程都是相同的。射线在场景中穿行,无论它包含什么。但是,它用于实现视觉效果,例如透明度、反射、折射等。根据您在问题中提到的内容,我认为您的项目可能没有这些功能。在这里,您很可能可以使用简单的低成本射线投射

因此,一旦您放置了渲染引擎,就可以向场景添加所有位移量。修改几何形状最常用的两种方式是:

  1. 凹凸贴图和
  2. 位移贴图。

位移映射会在现有几何体上添加真实的多边形,而凹凸贴图仅通过弯曲表面法线来模拟视觉效果,从而影响物体的阴影。虽然弯曲法线比细分几何体并添加新多边形要快得多且成本更低,但它不能产生精确的阴影结果,因此如果这对您的应用程序很重要,请注意。

此外,考虑使用自适应细节级别算法和数据结构,因为距离几何体越远,所需的细节就越少。


我原本希望由于我正在模拟地球,所以可以将其保持为几何球体,这样就不需要场景遍历或多边形测试。 - gct
是的,这取决于上下文,例如你是否只会在代表地球的球体上放置地形形成物,如山脉,或者你还需要有洞穴、半透明河流等需要双面的东西。当你说“无场景遍历”和“多边形测试”时,你具体指的是什么?我有一个重要的问题是——你计划自己从头编写渲染引擎,还是会使用现有的引擎? - Vuk
我会自己编写代码。我只需要一个地球,上面可能覆盖着蓝色大理石数据,并带有正确的高度信息。我不需要像洞穴或透明河流之类的花哨效果。如果可能的话,我可能会将水保持为平面蓝色。 - gct
1
选择亲自实现渲染器,你做得很好,一定会从中受益。位移只是添加了一些数学方程,对你来说应该很简单明了。赞一个! - Vuk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接