3

I am creating my own ray-tracer for fun and learning. One of the features I want to add is the ability to use SVG files as textures directly.

The simple and straight forward way to do this would be to simply render the SVG to another more "lookup-friendly" raster format first and feed that as a regular texture to be used during ray tracing. However I don't want to do that.

Instead I want to actually "trace" the SVG itself directly. So I would like to know are there any SVG libraries for Java that has an API that would lend it self to be used in this manner? It would need some call that takes as input a float point2D[] and returns float colorRGBA[] as an output.

If not what would be the best approach to do this?

Mr. Developerdude
  • 9,118
  • 10
  • 57
  • 95
  • Not exatly an answer to you're question but if you don't rasterize the SVG file you are going to take a HUGE hit in performance if your SVG file is anything but the simplest shapes. With a rasterized file the method you need is only a few lines of assembly but it could be very complex with an arbitrary SVG. – nikdeapen Dec 06 '15 at 23:17
  • I agree with you for existing SVG libraries, because they are optimized for "top down" rendering, however I would argue that the principles used to optimize raytracing such as creating a bounding volume hierarchy are possible to extend into an SVG rendring engine making it at least feasible, especially if the rendering pipeline is memory bound. – Mr. Developerdude Dec 06 '15 at 23:20
  • Then I believe if you want to go this route then you'll have to implement it yourself. The only libraries I could find rasterize the images. See http://www.jfree.org/jfreesvg/javadoc/index.html. – nikdeapen Dec 06 '15 at 23:36

1 Answers1

2

I don't know much about Java libraries but most likely they do not suit you too well. The main reasons are:

  1. Most libraries are meant to render pictures and are unsuitable for random look up.
  2. More importantly the SVG texture data does not filter naturally all that well. We know how to build good mipmaps of images and filtering them is easy reducing pressure on your raytracers super sampling need.
  3. Then there is the complexity of SVG itself, something like SVG filters (blur) will be prohibitively expensive to calculate in a random sampling context.

Now if we sidestep option three (3), which is indeed a quite hard problem as it really requires you to do rasterization or something other out of the ordinary. Then there are algorithmic options:

  1. You can actually raytrace the SVG in 2D. This would probably work out well for you as your doing a ray tracer anyway. So all you need to do is shoot rays inside the 2d model and see if your sample point is inside the shape or not. Just shoot a ray to a arbitrary direction and count intersections to see if your inside the shape or not. Simply your ray will intersect the shape a odd number of times if your inside the shape.

    enter image description here

    Image 1: Intersection testing. (originally posted here) Glancing hits must be excluded (most tracers consider that a miss anyway for this reason even in 3D)

    Pairing this tracing with a BSP-Tree or a Quadtree should make this sufficiently performant. All you need is to implement a similar shader support as your standard raytracer and you can handle alpha and gradfients + some of the filters like noise. But sill no luck with blurs without a lot of sampling.

  2. You can also use a texture as a precomputed result for a mipmap and only ask for rendering for a small view box when reaching a mipmap level that does not exist yet using a standard library with a limited window size. This would naturally work better for you and by caching the data you can remove the number of calls. Without the caching it might be too expensive to use. But you can try, (if the system supports clipping your svg). Thsi may not be as easy as it sounds.

  3. You can use your 3d raytracer for this, so instead you shoot rays head on. All you need to do is implement a tracing set logic and you can then triangulate the SVG and use your normal tracing logic to do this. How to describe bezier curves as triangles is described in this nvidia publication. So your changes might be minimal.

Hope this helps even if its not a use this library answer. There is a reason why you do not see this implemented very often.

Community
  • 1
  • 1
joojaa
  • 4,354
  • 1
  • 27
  • 45