Alpha 3.10 Release

Today I’m releasing version Alpha 3.10 of the plugin. The download and changelog pages have been updated and I’ve also included the changelog at the end of this post.

The biggest feature of this release is support for rendering (most of) the 3ds Max Physical Material. This will allow a more artist-friendly approach to creating materials than was previously possible with this plugin. Right now not all parameters are supported, you can read more about supported bits in the FAQ.

I’ve created a couple comparison pictures showing what both the presets “Red Sports Car Paint” and “Copper” look like in Cycles compared to ART. These renders use the Happy Buddha model provided by Morgan McGuire’s Computer Graphics Archive. Click for full size images.

buddha_compare_carpaintbuddha_compare_copper

I’m also still looking for gallery contributions. If you have made something with this plugin you would like me to share on this site, please send it in.

Full changelog:

  • Changed: Improved lighting for material previews
  • Added: Max 2017’s Physical Material can now be used
  • Fixed: Corrected error that could cause non-progressive-refine multi-GPU CUDA renders to hang up
  • Fixed: Objects flagged as not renderable will no longer be rendered

Approximating Max Physical Material – Reflection

I’ve recently been working on building an approximation of the Max Physical Material as a Cycles shader node graph. Once complete, this will allow this plugin to render the Physical Material with a similar appearance to ART. For this post I will be explaining how I built the reflection component of this Cycles shader graph.

To start, we need to know what the reflection component on its own looks like. Fortunately Max makes this easy by simply allowing one to disable all other components. Using default settings, the reflection component looks like this when rendered on a sphere using ART:

reflection_art_default

From this image, we can learn three important things:

  1. Looking closely at the top-left and bottom-right reflection, we can see there are no light gray pixels surrounding the white reflections. This means that the reflection is very sharp.
  2. This surface is only reflecting some of the light that hits it. Were it reflecting everything, the whole thing would be the color of the gray background. Every part that is darker than the background is absorbing some light.
  3. Looking around the edges of the sphere, there is a very noticeable vignetting effect. This is a result of the material reflecting a different amount of light based on the relative angle between the light and the surface. This phenomenon is known as Fresnel reflection. In this case, the material reflects more light at low angles of incidence that at high angles. The gray color around the edge comes from the sphere reflecting the gray background.

With this knowledge, we can begin assembling the shader. The first step is to create a perfectly sharp reflective material. Cycles makes this step easy by providing a Glossy Shader that is exactly what we need, it looks like this:

reflection_cycles_glossy

The light reflections are noticeably bigger in this image, that is just side-effect of the different lighting setup being used Cycles compared with the one used in ART. Later on when we draw direct comparisons between the Cycles and ART versions of the material, we will use a scene where both are lit the same. The spheres are just a quick preview.

The next thing we need to account for is the amount of light that is reflected from and absorbed by this shader. Only three things can happen to light that hits this surface, it can either be absorbed, transmitted, or reflected. This material is completely opaque, meaning there is no transmission, so we know that for this material light can only be absorbed or reflected.

We already have a shader that reflects all light that hits it, so now we should make one that absorbs all light. We can then use a Mix shader and a weighting factor to decide how much of the light gets directed to the glossy shader, which will reflect it, and how much gets directed to the black shader, which will absorb it. Our black shader looks like this, as you may expect from its name:

reflection_cycles_black

We can combine these using a Cycles Mix node. This node takes a weighting factor and two other shaders as inputs. By default the weighting factor is 0.5 across the sphere’s entire surface, meaning that half of the light hitting the surface will be directed to one of the sub-shaders, and half to the other. Combining our glossy and black nodes using a weight of 0.5 produces the following output:

reflection_cycles_black_glossy_const_blend

This is closer to what we want, but it isn’t there yet. Now we need to account for the Fresnel reflection that is occurring in the ART render. To start, we’ll just make a Cycles Fresnel node and connect it to the color channel of an Emission shader. This will allow us to visualize what the Fresnel weighting factor looks like on its own in Cycles:

reflection_cycles_fresnel

Plugging this in as the weighting factor between the reflective and absorptive shader, such that lighter means more reflection and darker means more absorption, we get this:

reflection_cycles_fresnel_blend

Recreated in Blender, our node graph looks like this:

reflection_blender_blend_graph

Now we have a Cycles shader the closely resembles how the physical material is rendered in ART, but there is still another parameter that is part of the reflection component that we need to account for: roughness. So far all the pictured renders have used a roughness of zero.

To see how roughness changes the appearance of this material in ART, I set up a simple scene with a number of reflective planes of differing roughness all reflecting the same light source. In this image the left-most plane has roughness of 0.0 and every other plane has roughness of 0.04 higher than the plane to its left, with the right-most plane having a roughness of 0.24

reflection_art_roughness

Our Cycles Glossy node also takes a parameter named roughness. To start off, lets just take the roughness value from the physical material, plug it straight in to the Cycles shader, and render the above scene again, this time with Cycles.

reflection_cycles_roughness_100

In this image the plane with 0.0 roughness looks good, but everything else is far too rough. At 1.0 roughness both look about about the same (not pictured), so we need to find a way to map the [0, 1] range of the ART shader to visually identical values in the range [0, 1] for the Cycles Shader. Both roughness of 0.0 and 1.0 render correctly in Cycles, so it is the values in between that we must focus on.

For this, we will need to create a function to convert from Physical Material roughness to Cycles roughness. For an input of 0, it must produce a value of 0, and for an input of 1, it must produce a value of 1. For values between 0 and 1, the output (Cycles roughness) should be some amount lower than the input (material roughness), which we know from observing the above two renders.

This can be easily achieved with a power function, which is simply: out = in ^ power. For any power greater than 1, this matches the criteria we specified in the previous paragraph. Now we must find exactly what this power should be.

Just by eyeballing the above 2 images, we can see that 0.24 roughness for the Physical Material is approximately equal to 0.04 roughness for Cycles. Substituting those numbers into the power equation gives us:

0.04 = 0.24 ^ power

Solving for power, we get ~2.25. Now that we have a function that we expect will correctly convert from Physical Material roughness to Cycles roughness, we can plug it in to our Cycles shader graph and render again.

reflection_blender_final_graph

reflection_cycles_roughness_225

Much closer than before, but now we have the opposite problem. In this render, the reflections in Cycles are a bit sharper than equivalent reflections in ART. This means we need to reduce the power. I’ll skip over the tedious part here, but after a few rounds of altering the power and re-rendering I found that a value of 2.05 makes the Cycles render closely, though imperfectly, resemble the ART render.

reflection_cycles_roughness_205

And that is it, we’re done. Now we have a Cycles shader graph that approximates the reflection component of the Physical Material. Here is a quick comparison of their appearance at 0.0, 0.2, 0.5, and 1.0 roughness.

reflection_final_comparison

Alpha 3.09 Release

Today I’m releasing version alpha 3.09 of the plugin, the download and changelog pages have been updated.

This update largely focuses on correcting a few problems with multi-GPU rendering that were brought to my attention by Alex Atiq. Big thanks to him for helping me test this latest version.

This release also adds support for configuring render options via MAXScript, which is a feature that was recently requested by a user.

Full changelog:

  • Changed: Reworked CUDA device options
  • Added: Render options can now be configured with MAXScript
  • Added: Most render options now have tooltips
  • Fixed: Corrected various errors with multi-GPU rendering

Downloads Temporarily Unavailable [Update: Downloads are back]

Quick update about the site here and the downloads page. All of the installer downloads are hosted on Amazon S3 which seems to be having some difficulties today. This means that for now all of the download links are dead.

There isn’t anything I can do to fix this for now, but I expect the downloads should work again soon. Sorry for any inconvenience.

Update: Downloads appear to be working again.

Multi-GPU problems in 3.08

It seems that some users are having problems with the multi-GPU support I added in yesterday’s release of Alpha 3.08. I’m trying to find the source of this problem now and expect to have a fix prepared in a few days.

Apologies for any trouble you may have encountered.

Update as of Feb 12: I’ve found the source of these problems but fixing it is a bit more complex than I anticipated. I now expect to have a fixed version available by the end of the month.

Alpha 3.08 Release

Today I am releasing version Alpha 3.08 of the Cycles for 3ds Max plugin. The download and changelog pages have been updated. Importantly, this release introduces support for multi-GPU rendering with CUDA.

Full changelog:

  • Changed: Updated internal Cycles code to version 1.8.1
  • Changed: Default render tile size is now 192×192 pixels
  • Added: Multi-GPU CUDA support
  • Added: Light path configuration options
  • Added: Option to set sampling RNG seed
  • Updated third-party libraries
    • Boost to version 1.63
    • libjpeg-turbo to version 1.5.1
    • libpng to version 1.6.28
    • OpenImageIO to version 1.6.18
    • zlib to version 1.2.11

Road Map to Version 1.0

I had posted a road map to this blog several months ago about what features remain to be implemented before the release of version 1.0. Here is an updated version covering my current plans for future development of this plugin.

I’m still open to suggestions for future development, so if there is a feature you would like to see in the plugin that isn’t listed here please post a comment and I’ll consider it.

Features to be added before 1.0

  • Max Physical Material
    • I am working to build an approximation of the Max Physical Material as a Cycles shader. Once this is ready the Max Physical Material will be usable in renders. I’ll likely dedicate a blog post and video to this feature when it is released.
  • Max Physical Camera
    • Motion blur support will be added through the Physical Camera.
  • Multi-GPU CUDA Support
    • Currently the plugin will only use the display GPU when rendering with CUDA. In addition to the display GPU I will be adding options to run on either a non-display GPU or all available GPUs.
  • Light Path Configuration
    • Cycles allows for configuring a number of options to tweak how light bounces in a scene. I’ll be exposing these parameters through the max GUI.
  • Max Light Support
    • Support for default max light types such as point light and spot light will be added.
  • Node Editor Updates
    • More nodes will be coming. Ideally I’ll have support for every node that can be used in Blender.
    • Support for defining environment maps through the node editor will be coming as well.

Features to be added after 1.0

  • Material Viewport Overhaul
    • The current real-time shaders used to render Cycles materials in the viewport are very poor approximations of how the materials will appear in a render. I’ll be re-making these to better resemble their appearance at render time.
  • Cycles Micro-polygon Displacement
    • Adding this will require substantial work. I’d love to support this soon but in the interest of getting to version 1.0 sooner rather than later I have to delay this feature for now.
  • Texture Baking Support
  • OpenCL Support
  • OSL Support

Alpha 3.07 Release

I have just posted an updated download link for version Alpha 3.07. The changelog has also been updated.

This release bring support for ActiveShade rendering. I’ve put together a short video showing this off here:

As I mentioned in previous blog posts and this video, later in December I will be posting an updated roadmap detailing what features still remain to be implemented in this plugin before the release of version 1.0.

Upcoming 3.07 Release – ActiveShade

It’s been over a month since I last posted here so I wanted to give everyone a short update on what has been happening with plugin development lately.

For the past month I’ve been rewriting all the bits of the plugin responsible for translating meshes and materials to work with Cycles. The result of this rewrite is that the Cycles plugin will now support real-time rendering in Max through Max’s ActiveShade mode. This will allow for real-time Cycles rendering in a floating render window as well as in a viewport.

Alpha 3.07 will be coming some time in the first half of this month and will likely have no new features apart from ActiveShade support. Along with the release I’ll be posting a new youtube video showing off how this works as well as posting an updated roadmap to this blog regarding what features still remain to be implemented before version 1.0 is complete.