java - 在 raytracer 中使用 SVG 文件作为纹理

标签 java svg 3d rendering vector-graphics

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

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

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

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

最佳答案

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

  1. 大多数库都是用来渲染图片的,不适合随机查找。
  2. 更重要的是,SVG 纹理数据不能很好地自然过滤。我们知道如何构建良好的图像 mipmap 并过滤它们可以轻松减轻光线追踪器 super 采样需求的压力。
  3. 然后是 SVG 本身的复杂性,像 SVG 滤镜(模糊)这样的东西在随机采样上下文中计算起来会非常昂贵。

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

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

    enter image description here

    图 1:相交测试。 (最初发布 here)必须排除扫视命中(即使在 3D 中,大多数示踪剂仍认为无论如何都是未命中)

    将此跟踪与 BSP 树或四叉树配对应该可以充分发挥其性能。您所需要的只是实现与标准光线追踪器类似的着色器支持,并且您可以处理 alpha 和 gradfients + 一些过滤器,如噪声。但是,如果不进行大量采样,就无法实现模糊。

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

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

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

关于java - 在 raytracer 中使用 SVG 文件作为纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34123880/

相关文章:

javascript - D3 钢筋间距

math - 如何将3x3旋转矩阵转换为4x4矩阵?

java - android Activity 类构造函数工作

javassist.CannotCompileException : [source error] no such class: TestDebug

java - 是否可以说每个运行时绑定(bind)都是编译期间的静态绑定(bind)?

algorithm - "false 3D"棱镜墙的渲染顺序

Java - LWJGL 加载纹理,只有我加载的最新纹理有效

java - 在草稿状态 Microsoft Graph API Java 中发布消息创建消息

html - 使用 SVG 和渐变作为填充

javascript - 自动将 SVG 缩放到其父级