Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Speeding up rendering in SceneKit

So, I am using SceneKit to render a collection of parametric surfaces (the sum of which make an object). To put these on screen I am creating custom geometries by sampling the points and creating triangles. Here is a quick over view of how I do it.

Loop through the collection of surfaces
    Generate a random color C
    For each surface calculate a grid of N x N points (both positions and normals)
    Assign all vertexes for that surface the color C
    Add groups of 3 vertexes from this surface to the face index list

And that seems to work. After I get all this data, I make it into the proper structures (SCNGeometrySource and SCNGeometryElement) and make a SCNGeometry like so

SCNGeometry(sources: [vertexSource, normalSource, colorSource], elements: [element])

This works and displays my surfaces on the screen fine as one single geometry element. My problem is, I have some really complicated objects that I am trying to work with and it is just running really slow to move the camera around when looking at the object. Rendering is taking around 500 ms. Which is making my frame rate and experience awful.

So the question is, what steps can I take to speed up SceneKit performance? I did this same project with WebGL using Three.js with the same amount of data and was able to use an orbiting camera fine, so I can't believe that scene kit couldn't at least compete with that. What features can I tweak and turn off to speed up performance? I am using the triangle primitive type, the allowsCameraControl = true for the orbiting camera, and metal for the SCNView.

For those curious, the model I am struggling on generated 231,900 vertices and 347,850 indices for faces (11.1312 MB of vertex data (position and normal) and 1.3914 MB of face data (essentially just index positions of vertexes in order for triangles.))

like image 935
Red Avatar asked Nov 09 '15 00:11

Red


1 Answers

1) If you are "standing" on center of your generated surface, then your problem maybe that you drawing alot offscreen (no frustum culling) and you need to split your sufrface (single node) into subsurfaces (child nodes), so only nodes that is visible in camera view space is drawn.

That being said, 231,900 vertices is really not much, I draw several milions @60fps with SceneKit Metal renderer (+20% faster than using OpenGL renderer) on OSX.

2) If you are looking on your surfaces from distance and have bad performance, check what ammount of bytesPerComponent: you feeding when creating SCNGeometrySource. I experienced big performance drop when using CGFloat (double) instead of plain float on GeForce GTX (while okay on integrated Intel graphics).

like image 83
Ef Dot Avatar answered Sep 19 '22 00:09

Ef Dot