Scott Benson's profile

Resource Management: Polygons for Octane Render/C4D

Resource Management
03: Polygons
Version 1.0, Updated January 2023 using Octane 2022.1 and C4D 2023.1.3

About This Guide

This is part of an ongoing series on the exciting world of resource management!

The goal of this series is to explore what C4D and Octane are doing under the hood, and how to tune our system resources and habits to make our workflow as zen and frustration-free as possible. Part 01 is an overview of how the whole system works. Part 02 is a rollup of all the findings of the rest of the series (including what we discovered in this Polygons guide if you just want a quick summary). This guide is a deep dive into a particular area of interest - namely polygons.

Guides in this series
· 01: Overview
· 02: Findings Summary
· 03: Polygons <--This one
· 04: Instances
· 05: Textures

PDF
This guide is also available in 📄PDF format here.
 
I. Intro
Geometry (polygons) can affect the performance of the system in a variety of ways. In this guide we’re going to investigate what happens when the number of polys gets high enough to break everything and cause weeping, gnashing of teeth, and rending of garments.

There are two areas to investigate when talking about geometry - the number of polygons in a single object, and total number of polygon objects in the scene (mostly in instances, but also just a ton of single objects). Both have different challenges and considerations. This guide will focus on the number of polygons in a single object, and a future guide on Instances will cover the number of objects.

The first chunk of this guide is some background info about how geometry is treated in C4D and Octane. The rest of the sections are various testing scenarios that show the impact of a ton of polygons on our system’s resources.

Testing system
We’ll be using a 2021 Razer Blade 15 for these guides. Specs: i9-11900H CPU/64GB RAM/RTX3080 Laptop GPU/16GB VRAM/4K 60Hz OLED. OS: Win 11 Home 22H2. Cinema 4D 2023.1/Octane Render 2022.1

Test scenes are 1280x1280, 30FPS. All unnecessary apps and processes have been shut down.

The Gold Standard
An Octane render is at its absolute best when all of the scene data (polygons, textures, instances, overhead, and everything else) fits completely in VRAM, and the system RAM does not fill up to 100% while processing.

C4D’s performance is at its absolute best when the frames per second reported in the viewport does not drop below the target FPS of the scene. This is covered in detail at the end of the Intro guide for this series.

Overhead
When we first launch C4D (assuming we remembered to shut everything else down), we have ~12.5 GB out of 16 GB of VRAM to use for Octane, ~57 GB out of 64 GB of system RAM to use for pre-processing, and are running at 300-350 FPS in the viewport. This leaves us a lot of room to add geometry, textures, and other stuff so our render isn’t just a white square.

II. How geometry is treated
Polygons
A polygon is the smallest building block of a geometry object (or mesh). C4D’s concept of “polygons” includes triangles (3-sided), quads (4-sided), or n-gons (more than 4-sided) polygons. Octane can only use triangles, so all polygons must be reduced to triangles in the pre-processing phase before Octane can render it.

When a mesh is subdivided (we’ll go into this later), each polygon is split into smaller quads, regardless of whether it started life as a tri, quad, or n-gon. Those quads must then be broken into triangles to be sent to Octane.

Baked vs. Generated Polygons
C4D has two ways of handling how polygons are created and stored. They can either be baked (C4D refers to this as “editable”) or generated.
 
If the polygons are baked, points/edge/face data permanently exists for each and every polygon, and it’s stored in the C4D file. When the file loads, all that data is copied over into RAM and it sits there until the file is closed (or the object is deleted). All of that individual point/face data takes up space, so it makes the C4D file a lot larger than if a generator was used (70 MB vs 300 KB for a million polys).

If the polygons are generated, a small bit of code is stored in the C4D file which is copied over when the file loads, and then it runs, immediately generating the required number of polygons and storing them in RAM. They stay there until the generator is turned off (green check next to the object), or something triggers it to rebuild them (changing the number of segments, for instance).

Regardless of whether they’re baked or generated, polygons take up the same amount of space in RAM. All polygon objects need to be temporarily baked prior to being sent to Octane for a render.
 
Subdivisions
Subdivision is a common method of splitting polygons into smaller ones. This is typically done to smooth out a mesh or add more detail for things like displacement.
Rather than specifying a number of polygons, subdivision works in levels. Levels always work in powers of four.

Level 0 is the original geometry (one quad in this case)

Level 1: Each quad is split in four for a total of 4 quads.

Level 2: The four quads from Level 1 are divided in four for a total of 16 quads.

Level 3: The sixteen quads from Level 2 are divided in four for a total of 64 quads.

...up to Level 10 where each quad becomes 1,048,576 quads.

For a single polygon like in our illustration above, this is no big deal, but it adds up quickly at higher levels if the base mesh is already in the thousands of polys.

Subdivision Methods
Cinema 4D has a built-in Subdivision Surface object (SubD or SDS for short). This is a generator that subdivides the geometry of any polygon object nested in it. The advantage to this method is that we can see the results of the subdivision in the viewport. The disadvantage is processing time and a hit in the viewport performance.

Important: Octane only recognizes the Viewport subdivision number in C4D’s SubD object, not the render one.

Octane also has a a method of subdividing via the Octane Object Tag. The subdivision level can be set in the Subdivision Group tab. This subdivides the polygons at render time, meaning the viewport moves at full speed, but the final subdivided model can’t be visualized until the render happens. This method also causes C4D to use a little less VRAM in overhead, so it’s a better choice for cases where VRAM is tight.

III. Polygons and Memory

Keeping both the RAM and VRAM from filling up is important from an optimization standpoint, so getting an estimate of how much our scene is using is important.
There are two good tools to track memory usage. The Ctl-I/Cmd-I window shows the amount of RAM the polygons are using, and in Octane Settings>Settings Tab>Device Settings will show a breakdown of the VRAM being used.

One million quads takes about 70 MB (0.07GB) when loaded into RAM. It’s “about” and not “exactly” because it matters how the mesh is constructed (shared edges/vertices/etc).

If we were to take those million quads, make them editable, select them, and use the “triangulate” command in C4D, we’d end up with two million triangles. This is what happens during the pre-processing phase before being sent to Octane. If we wanted only one million triangles in Octane, we’d have to start with a half million quads.

Storing 2 million tris in C4D brings the RAM Usage up to 117 MB (~0.17 GB) - not quite twice as much as one million quads, because there are shared points and other nerdly math stuff that impacts how it’s stored in memory.

The interesting part is that once these two million triangles are sent to Octane, they use 367 MB (~0.37 GB) of VRAM.

How to Think About This

The geometry in our scene impacts both the VRAM and RAM.

Both of these resources have some overhead shaved off the top, so we’re left with ~12.5 GB VRAM and ~57 GB RAM to play with. Both of these numbers have some flex in them because of optimization and other trickery, but they’re good guidelines.

Any given amount of polygons take up more VRAM than RAM. We have 4x less VRAM than RAM, so we’re more worried about the VRAM impact because we’ll hit that limit long before the number of polygons start having a noticeable effect on the RAM.

If a single object consumes too much VRAM, it needs to be put into Out-of-core RAM (more on this later).

Unfortunately we can’t know the true impact of the polycount on the VRAM until AFTER we render, but we can use the .37 GB per 1,000,000 polygons number as a good guess.

Depending on what else is in the scene, we should start getting nervous around 20 million quads with this hardware, and look for ways to reduce and optimize.

IV. Getting a polygon count
The number of polygons in the scene affects all of our resources. When this number gets up really high (tens of millions), our viewport starts lagging, RAM and VRAM start filling up, the file size on disk gets unmanageable, and render pre-processing times start going into the minutes (or even hours).

Simply put, the experience starts to suck.

Knowing where to find the number of polygons in the scene (and per-object) is a pretty important diagnostics concept. There are several places to get this count, and each one has its pros/cons.

Octane
The easiest way to get an accurate triangle count for the whole scene is to just start the render in the Live Viewer and see what Octane reports back. There are a few different places to access this information:

Live Viewer: This is the quickest and easiest way if we’re using the Live Viewer (which we are for most of this guide). There are data overlays on the Live Viewer itself, one of which says “tris” and has two numbers. The second number is the one we’re interested in. If those overlays aren’t there, while the Live Viewer is running, we can right-click in the image area somewhere and choose “Toggle Info”, or just click in the middle of the image area a few times to toggle them on and off.

GPU Information: This is under the Help menu in the Live Viewer - it pops up a small window that gives a more accurate tris number (to the tri, rather than to the thousands or millions like the overlay).

Octane Log: This is also under the Help menu in the Live Viewer. This only gives a polycount if we’re rendering to the picture viewer instead of the Live Viewer.

Important: Octane needs to actually be able to complete a render to get this number. If the polycount is super high and it’s taking forever to pre-process and display the tri count (or if it’s running out of VRAM and can’t render), we have other methods at our disposal in C4D to see what’s going on.

Octane only gives a polycount for the geometry that’s sent over to it. If there are 20 million polygons in the C4D scene, and 19 million of them are in objects that have Render Visibility turned off (bottom traffic light set to red), then Octane will only see the one million polygons it’s sent and return a value based on that.

C4D
Ctl-I (or Cmd-I on Mac) brings up a handy little info window that tells us the total polycount for both generated and baked polygons.
It’s fast, easy, and gets us a nice ballpark, but there are two big gotchas to be aware of.

1. This is a total polygon count. Since we know that C4D considers a tri, a quad, and an n-gon to be polygons, A 14,000 polycount could either be 14,000 quads (which must be split into 28,000 tris for Octane), or 14,000 tris which will still be 14,000 tris for Octane, or 14,000 n-gons which is some arbitrary number of tris (or some mix of all of them).

2. The math is really weird. It ends up double-counting generated nested objects. For instance, if we have a plane with 1,000,000 quads nested in a level 1 subdivision surface object, it counts the 4,000,000 polygons from the SubD, but also adds the 1,000,000 quads from the original plane! This means it returns a value of 5,000,000 polys which is a million quads off (or two million triangles) when baking it and sending it to Octane.

This gives a more accurate RAM usage value, but it throws off the polycount data that we need for Octane. So we’ll just use this to estimate how heavy the scene is, not for any kind of accuracy.

The next two tools are for baked polygons only (not generated ones).
HUD: We can hit Shift-V in the perspective viewport, and in the HUD tab, make sure Total Polygons is checked. Then if we go into Polygons mode at the top and select our object, we can see the total baked/editable polygons there. It doesn’t count generated polygons. If we know that the model is all triangles (like from a CAD project or sculpt), then we know what our tri count is. If we know it’s all quads, we can multiply it by two to get the tri count. If it’s n-gons or a mix, it’s anyone’s guess.
Project Info: To get a breakdown of the types of polygons in our scene, we can go to the Attributes manager, and under Mode, select Project Info. This also does not work with generators, only editable polygons.

If we’re in Polygons mode, we can use the Structure tab to see what the breakdown is in quads, tris, and n-gons. We can pretty easily estimate the polycount from the tris and quads, but for the n-gons we’re still in the dark.

V. Testing
This is the real nitty-gritty part of this guide. We’re going to test out a bunch of different scenarios and see what happens.

Test 1: Baseline
Setup Phase
Let’s launch C4D and get a brand new scene going with nothing in it. Our scene will be 1280x1280 at 30 FPS, and we’re going to get the Live Viewer up. Cool.

C4D immediately uses ~3 GB of RAM on launch, which when added to the 4 GB the system is using accounts for close to 1/8 of the total RAM.

C4D uses about 1.25 GB of VRAM on launch. Not bad - still plenty of room left to add some scene data.

FPS fluctuates a lot, but it’s well over 60 FPS - we’re in no danger of slowdown. Playback FPS is over 300, so we’re good to add a bunch of stuff and still be able to time animations properly.

If we were to go into Octane’s settings (gear menu), go to the Settings Tab and hit Device Settings, we’d see a whole lot of nothing. Octane hasn’t been asked to do anything yet, so it’s unaware of anything in the scene.
Render Phase
When we render to the Live Viewer, we see a white screen (or black, depending on what you set your default environment color to).

During the render, C4D peaks at 4 GB of RAM, and adds another gig of overhead to the VRAM to bring it to 2.3 according to the Task Manager.

Now that we’ve sent something to Octane, it has some information to show us. The overlay says 1.119 GB used, and 12.48 GB available. If we go back to Octane Settings>Settings>Device Settings, we now see a breakdown of what was last sent. Octane has seven categories here. The ones that will impact us in this guide are:

Engine Runtime Data - this is the overhead Octane needs to be able to render at all. It’s always 1.1GB.

Geometry is the one we’re most concerned with, since that’s all the triangles. Right now we have no geo, so it’s 0.

Unavailable is chunk of VRAM that C4D and the rest of the system is using. Since we were really good about closing all other apps, this is going to mostly be about C4D’s VRAM usage, which we can look at in the Task Manager as well.

So we’ve re-established our baseline. As expected, a scene with nothing in it is in no danger of running us out of resources. If it was going to be a problem, we’d have to consider upgrading our computer or doing some troubleshooting to figure out what else is running that’s eating RAM and VRAM, or killing the framerate.

Test 2: One object with one million quads

Setup Phase
Next, let’s add some geometry.

We’re going to use a Plane object, which is a generator, so it’s just a small bit of code that produces the required number of polygons on-demand and stores them in RAM. Let’s add one in, and make the segments 1000x1000 so it makes a million quads for us, and then save the file.

It doesn’t matter whether C4D is using generated or baked polygons - both take up the same amount of RAM (70 MB in this case). Generated polygons take up less space than baked ones in the actual C4D file on disk (300KB vs 70MB), but with only a million polygons, this isn’t a huge deal unless the file needs to be emailed or something.
A million quads has very little impact on FPS, both while navigating and during playback - we’re still looking at more than enough for real-time performance and smooth operation of the app.

The RAM and VRAM usage is also pretty minimal - C4D adds a little bit to VRAM and RAM to store the million polygons, but we’re still in no danger of having issues on either front.

Render Phase
When we hit render, our Plane generator runs one last time to produce the final mesh. That 1 million quad mesh is cut into two million triangles, bundled up with some extra data and sent to Octane to render.

During this phase, some RAM is used as temporary storage (our scene here peaks around 6GB, leaving a ton of extra room, and therefore operating at full speed).
If we go into the Octane Settings now (gear icon), go to the Settings tab and click the Device Settings button, we get a breakdown of Octane’s data package that it sent over to render.

The Engine Runtime Data (Octane overhead) is the largest chunk here. It’s 1.1GB as expected.

The Geometry now comes in at 367.3 MB (or ~0.37 GB). Nothing to be concerned with.

Unavailable jumped to 3GB - That’s mostly C4D temp data plus a little extra from the system.

This whole process takes less than two seconds, which is totally acceptable for quick lookdev. The polygons are stored until something else flushes them out or until the mesh changes, so subsequent renders where the just the camera changes will happen in near realtime.

Test 3: Subdividing the Plane
1000x1000 segments is the most C4D can do with a Plane object, so we’ll need to start subdividing to get more geometry on the card. If we want to procedurally subdivide it, we have two options. We can either use C4D’s Subdivision Surface object and do the subdivision in the editor view, or Octane’s Object tag and do it at render time. There isn’t too much of a difference until we start putting in a massive amount, so let’s just try a few quick tests first to see about how high we can go.
At 4M quads (1K x 1K seg plane in a L1 SubD), we start seeing a little bit of pre-processing time (7 seconds). FPS, VRAM, and RAM are still fine.

At 16M quads (1K x 1K seg plane in a L2 SubD), we’re looking at 20-25 seconds of pre-processing time, which isn’t horribile, but it’s not great. RAM isn’t maxing out quite yet, but it is peaking at 42 GB, so probably better make sure we’re not running anything else in the background. FPS for the viewport is hovering around 60, so that’s still more than enough.

At 32M quads (500 x 1K seg plane in a L3 SubD) we’re at a minute and 45 seconds of pre-processing time. That’s annoying. RAM is the bottleneck here - it peaked at 62GB during the render and is starting to make Windows do some acrobatics to stop from running out, hence the slow processing time. VRAM is still ok - we have a little breathing room there. FPS dropped below 60, but it’s still above 30 in the viewport, so that’s still considered real-time.

40M quads (625 x 1K seg plane in a L3 SubD) seems to be about as many as we can have before we run out of memory on this hardware config. RAM usage peaked at 62.3, causing all kinds of slowdown. There’s still a couple hundred megs left of available VRAM, so we could jam in maybe another half a million polygons, but it’s just going to make things slower. Viewport FPS is around 35, so that’s starting to get close to dropping below real-time.

We should really start to consider methods of reducing the polycount at this point if we’re looking at animation.

Test 4: Subdivision Surface Methods

In the last test, we used C4D’s native Subdivision Surface object. It would be worth testing this against Octane’s native subdivision method (available in the Octane Object Tag), and also against a fully baked poly version.

It turns out that the fully baked version of the 40M poly geometry runs us out of memory and crashes Octane, so we’re going to have to back down to 32M quads for this comparison.
So none of them were great, but that’s kind of to be expected with such a high poly object.

Subdivision Surface Object

We already explored the Subdivision Surface Object scenario in the last test (500x1000 segment Plane in a L3 SubD), so no surprises here.

Octane Object Tag

The Octane Object Tag scenario takes the same 500x1000 segment Plane and puts an Octane Object Tag on it instead of putting it in a C4D SubD. The Subdivision Group tab in the tag controls the subdivision level in this case. If we set it to 3, we’ll notice it has no effect on the viewport! That means we can wing around at >60FPS and play back at full speed with no issues.

The subdivision will happen at render time, which frees up a little more VRAM when rendering as well. C4D only needs 2.3GB as opposed to 4GB when it had to store all those polygons prior to the render, so we could conceivably fit more than even 40M polygons if we were feeling lucky.

RAM usage is the same though, so we probably wouldn’t want to push it and try to put too many more polys in.

The pre-processing time was aslo a little lower than the SubD scenario, but 1:23 is still a long time to wait, so no huge savings there. The real star here is the viewport performance, but this comes at the expense of not seeing what the final subdivided object looks like in the viewport.

Baked Polygons

The Baked Polygon scenario was pretty interesting. This was acheived by taking the 500x1000 seg Plane, putting it in a L3 SubD, and then making it editable. This brought the C4D file size to over 2GB - definitely won’t be emailing that to anyone we don’t hate. The really weird thing here is that the baked polygons took 12.4 GB of VRAM as opposed to 8.1 GB like both subdivision methods reported, which is closer to what our estimations would have been (0.37 GB per million polys * 32 should have been around 11.85 GB). This means there’s some compression or other black magic going on with the subdivision methods to get the geo down to 8.1 GB.

The baked poly scenario also reported that the Unavailable VRAM was only at 151 MB, meaning that it somehow forced C4D to remove a lot of its overhead.

Lastly, the viewport was hovering around 30FPS, which isn’t bad, but it’s getting close to dropping us down below real time.

Test 5: Out-of-Core
So what if we’re given a 100-million triangle model and need to render it, but can’t be bothered to retopo it or otherwise reduce the polygon count? Using some quick back-of-the-napkin math, we can guess that 100 million tris should eat up around 36 GB of VRAM, but only about 13 or 14 GB of system RAM.

We’d have to get an eGPU setup and stick an A100 in there if we had any chance of getting this thing into VRAM, but we do have one last hail mary tool that we can use when presented with a problem like this: Out-of-core memory!

We can sacrifice some of our pre-processing RAM (and a lot of our speed) to gain more memory for a render. We have 64GB of RAM, so what happens if we assign 20GB of that to out-of-core (figure we’ll give it a few extra gigs of leeway)? In Octane’s settings (gear icon), in the OOC tab, we can do just that.

Shall we commence with the beatdown?
 
Setup Phase
Let’s load up our insane 3.5 GB C4D file with a baked ~50M quad model in it. It was based on a 900x900 plane in an L3 SubD, so the total polycount for this piece of geometry is 51,840,000 quads, which will split to 103,680,000 triangles when sent to Octane.

It takes a few seconds to actually load the file, and then once we’re in, the viewport is really choppy and laggy. We’re getting about 22 FPS, but there are times where it has to think for a second or two before it even lets us navigate. Not a lot of fun. Playback isn’t so bad though - we’re still somehow getting about 150 FPS.

C4D immediately dumps 4GB into VRAM and eats about 9 GB of RAM just to have the model loaded in. Not terrible if we’re just bringing something in and rendering, but certainly not a fun experience if we want to actually manipulate it in the viewport.

Render phase
Let’s send this puppy to the Live Viewer.

After nearly 13 minutes, it does actually render. If we bring up the Octane Settings window, the first thing we’ll notice is that there’s no bar for geometry in the VRAM readout. This is because the model was too large to fit in VRAM, so it had to be moved to RAM (Out-of-core). It came in right around 13 GB, which means C4D only had about 50 GB to do its pre-processing. This is why we were sitting around for 13 minutes before we saw anything on the screen.

C4D saw all that open VRAM and decided to toss in another couple gigs, bringing its total up to 5.2 GB.

If we look at the log, we’ll see that RTX is also disabled when OOC is used - this greatly impacts the render speed, depending on the scene. This is 13 minutes without any textures or difficult render calcs, so we’d need to be very sure that we don’t want to spend time doing some retopo work.

Fallout
At this point, C4D starts freaking out. Even 10 minutes after the render is done, and with the Live Viewer paused, it’s continually swapping huge chunks in and out of RAM and using a ton of CPU cycles. FPS drops to seconds per frame as the CPU is overloaded, and basically all hell is breaking loose.

To avoid this, we can render to the Picture Viewer rather than the Live Viewer. C4D is a lot more stable after that.

Wrap Up
So that about does it for this installment on Polygons. If you’ve made it this far, you probably have a much better understanding of how geometry affects C4D and Octane, and hopefully this will help you with future projects!

Author Notes
OG030 Resource Management: Polygons, version 1.0, Last modified January 2023.

This guide originally appeared on https://be.net/scottbenson and https://help.otoy.com/hc/en-us/articles/212549326-OctaneRender-for-CINEMA-4D-Cheatsheet

All rights reserved.

The written guide may be distributed freely and can be used for personal or professional training, but not modified or sold. The assets distributed within this guide are either generated specifically for this guide and released as cc0, or sourced from cc0 sites, so they may be used for any reason, personal or commercial. The emoji font used here is Noto Color Emoji.
Resource Management: Polygons for Octane Render/C4D
Published:

Resource Management: Polygons for Octane Render/C4D

Published: