TAG / 图形图像

PBRT 学习:安装编译

去年在前公司看着 leader 用 PBRT 做基于 DX11/SM5.0 的 ray tracing 实验时,还懵懂得云里雾里。而我现在的 manager,在读研的时候就已经在研究 PBRT 了。我, out 了!最近由于工作的原因,终于开始着手学习 PBRT,而这玩意第一道关卡就是安装编译中的一堆问题,记录以备不时只需。

网上关于 PBRT 的资料基本都是 1.03 或更早的,而且基本都跳过了自动生成代码的预处理阶段。这次下载来的最新 pbrt-src-1.04.zip for Windows 虽然在其 release note 里说“a number of bugs and incompatabilities have been fixed”,但从我安装编译的经过来看,问题似乎更多了(斯坦福的大大们不应该这么粗心吧)。

首先把下载的文件解压到任意目录下,我这是“D:\Program Files\pbrt-1.04”,不过推荐还是放到分区根目录或者文件夹名不含空格的路径下,否则后面会多几个体力活。

PBRT 使用了 Bison 和 Flex 这两个工具来生成用于解析 pbrt 脚本文件的代码文件(这话有点绕哈),而这两个工具本是 Linux 下的,现在都有大大做了 Windows 版的移植(Bison for WindowsFlex for Windows)。分别把 Bison Binaries 中的 \bin 和 \share、Bison Dependencies 中的 \bin、Flex Binaries 中的 \bin 目录解压到任意目录下,我这是“D:\GnuWin32”。

这时 PBRT 还是不能编译的,原因是 1.04 中移除了对 OpenEXR 工具包的包含。OpenEXR 本身是三大 HDRI 格式之一,另外两种格式在以前我都处理过,而对 EXR 格式不熟,这里暂时也不做深究。OpenEXR 工具包可以在其官网下载(最新的 1.5.0 没有 VS2005 的预编译版本,我偷懒就直接下 openexr-1.4.0-vs2005.zip 了),也可以从 PBRT 1.03 zip 包中直接拿来用,然后整个解压出来,我这是“D:\Program Files\pbrt-1.04\openexr-1.4.0-vs2005”。这还没完,无论是官网还是 PBRT 1.03 里的 OpenEXR 工具包,在 \lib 文件夹下都缺少 zdll.lib 这个文件,去 zlib 首页下载 zlib compiled DLL zipfile,把压缩包中的 \lib 解压到 OpenEXR 所在文件夹下。

CONTINUE READING »


3D Coordinates

最近碰到 Gamebryo3DS MAX 的坐标系转换问题,顺便花了几分钟研究了下各 3D 坐标系,真是比当下全球形势还混乱:

除了微软当年为了跟 OpenGL 划清界限,特立独行搞出左手坐标系的 DX 外,其他都是右手系(应该都是受 OGL 这个工业标准的影响),不过 Z 轴朝什么方向的都有,哭死了。


WoW Model Viewer 的编译问题

这段时间要搞角色换装系统的改进,参考魔兽世界的换装系统机制,便先拿了 WoW Model Viewer 的代码来参考。

先拷来一个 0.48b 版本的代码,按照这里说的做后编译是通过了,但运行总报错,跟了一下没找到问题,索性去下了 0.5.08 。该版本使用 wxWidgets 2.8.0、CxImage 5.99c、GLEW 1.3.3,其中 wxWidgets 2.8.0 需要自行下载、编译。

然后打开 wowmodelview.sln,打开工程属性,修改 C++ | Additional Include Directories、Linker | Additional Library Directories 中关于 wxWidgets 的路径,然后编译,这时可能会报一些 build error,基本都是类型没有显式强转的问题,改掉即可。

编译完成后,需要修改配置文件 Config.ini,把 [Locale] 下的“Path=”和“MPQFiles=”后的路径都改为 .mpq 文件所在文件夹根目录,就可以运行了。


看,给这位大老粗穿上粉红色紧身T恤是不是很性感呀?


判断一个点是否在 2D 三角形内

这是我拿到公司 offer 时美国老大给我的面试题,对于当时我这种文盲来说,还是杀死了不少脑细胞。最近闲来无事(嗯。。。被危机了),又拿出来琢磨了一下各算法。

设一在在 2D 空间中的三角形 △ABC ,三个顶点向量 A(ax, ay)、B(bx, by)、C(cx, cy),三条有向边 AB、BC、CA,有一点 P(px, py)。

  1. 叉乘法
  2. 原理:

    沿 △ABC 各有向边按一定方向走(顺时针或逆时针),判断点 P 是否在该边的某侧(右侧或左侧),若点 P 在三条边的同侧,则点 P 在 △ABC 内。

    实现:

    分别计算向量 AB、BC、CA 与向量 AP、BP、CP 的向量积(叉乘),若三个结果均同号(正或负,为零表示 P 在边上),则可得点 P 在 △ABC 内。其中AB = B - A,AB×AP = AB.x*AP.y - AB.y*AP.x。

    该算法只需要做 3 次叉乘(6 次普通数值乘法),效率高,且没有浮点误差。
    这是我当时面试想的算法,Azure 等人也用的类似算法。

  3. 面积法
  4. 原理:

    若点 P 在 △ABC 内,则 △ABP、△BCP、△CAP 的面积之和应等于 △ABC 的面积。

    实现:

    利用两个向量叉积的几何意义为该两个向量所围三角形面积的 2 倍,分别计算 AB×BP、BC×CP、CA×AP、AB×BC,若 |AB×BP| + |BC×CP| + |CA×AP| = |AB×BC|,则得点 P 在 △ABC 内。

    这个算法用得比较普遍,需要做 4 次叉乘(8 次普通数值乘法),效率和叉乘法差不多,同时避免了用海伦公式计算面积的低效和精度问题(数值除法和开方运算)。

我昨天想的一个算法有点类似这篇文章中的方法 3,比它简单一点,但同样需要对向量做归一化处理,效率不高,故放弃了。另外的算法还包括划线交点法、解方程组法、复数法等,但计算量都较大,不再赘述。