【问题标题】:Using an SVG file as texture in raytracer在光线追踪器中使用 SVG 文件作为纹理
【发布时间】:2016-03-11 11:36:36
【问题描述】:

我正在创建自己的光线追踪器以供娱乐和学习。我要添加的功能之一是能够直接将 SVG 文件用作纹理。

执行此操作的简单直接的方法是首先将 SVG 渲染为另一种更“便于查找”的光栅格式,并将其作为常规纹理提供,以便在光线追踪期间使用。但是我不想这样做

相反,我想直接“跟踪”SVG 本身。所以我想知道是否有任何用于 Java 的 SVG 库有一个 API 可以让它自己以这种方式使用?它需要一些调用,将float point2D[] 作为输入并返回float colorRGBA[] 作为输出。

如果不是,最好的方法是什么?

【问题讨论】:

  • 不是你的问题的答案,但如果你不光栅化 SVG 文件,如果你的 SVG 文件不是最简单的形状,你的性能会受到巨大影响。对于光栅化文件,您需要的方法只是几行汇编,但对于任意 SVG,它可能非常复杂。
  • 我同意你对现有 SVG 库的看法,因为它们针对“自上而下”渲染进行了优化,但我认为用于优化光线追踪的原则(例如创建边界体积层次结构)可以扩展进入 SVG 渲染引擎,使其至少可行,尤其是在渲染管道受内存限制的情况下。
  • 那么我相信如果你想走这条路,那么你必须自己实现它。我能找到的唯一库对图像进行光栅化。见jfree.org/jfreesvg/javadoc/index.html

标签: java svg 3d rendering vector-graphics


【解决方案1】:

我对 Java 库了解不多,但很可能它们不太适合您。主要原因是:

  1. 大多数库旨在渲染图片,不适合随机查找。
  2. 更重要的是,SVG 纹理数据并没有自然过滤得那么好。我们知道如何构建良好的图像 mipmap 和过滤它们很容易减少对光线追踪器超级采样需求的压力。
  3. 然后是 SVG 本身的复杂性,像 SVG 过滤器(模糊)这样的东西在随机采样环境中计算起来会非常昂贵。

现在,如果我们回避选项三 (3),这确实是一个非常困难的问题,因为它确实需要您进行光栅化或其他不寻常的事情。然后是算法选项:

  1. 您实际上可以在 2D 中对 SVG 进行光线追踪。无论如何,这对你来说可能会很好,因为你在做一个光线追踪器。因此,您需要做的就是在 2d 模型内发射光线,然后查看您的采样点是否在形状内。只需向任意方向发射光线并计算交叉点,看看您是否在形状内。如果您在形状内部,您的光线将与形状相交奇数次。

    图 1:交叉点测试。 (最初发布here)必须排除扫视命中(大多数追踪者认为无论如何都是未命中的原因,即使在 3D 中也是如此)

    将此跟踪与 BSP-Tree 或 Quadtree 配对应该可以使其具有足够的性能。您所需要的只是实现与标准光线追踪器类似的着色器支持,并且您可以处理 alpha 和渐变 + 一些过滤器,如噪声。但是如果没有大量采样,模糊就没有运气。

  2. 您还可以将纹理用作 mipmap 的预计算结果,并且仅在使用具有有限窗口大小的标准库达到尚不存在的 mipmap 级别时才要求渲染小视图框。这自然会更好地为您工作,并且通过缓存数据,您可以删除调用次数。如果没有缓存,使用起来可能太昂贵了。但你可以试试,(如果系统支持剪裁你的 svg)。这可能不像听起来那么容易。

  3. 您可以为此使用 3D 光线追踪器,因此您可以正面发射光线。您需要做的就是实现一个跟踪集逻辑,然后您可以对 SVG 进行三角测量并使用您的正常跟踪逻辑来执行此操作。 in this nvidia publication 描述了如何将贝塞尔曲线描述为三角形。所以你的改变可能很小。

希望这会有所帮助,即使它不是使用这个库的答案。您不经常看到此实现是有原因的。

【讨论】:

    猜你喜欢
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    相关资源
    最近更新 更多