HtoA 3.0.0

9 April 2018


This is a major release, bringing alembic packed primitives to HtoA. It also introduces the new Arnold 5.1 core including Optix and Noice (Arnold denoiser), adaptive sampling, operators for parameter overrides, toon shader, layer shaders and more.

  1. Get the install files on Solid Angle Downloads.
  2. Follow these installation instructions.

This release uses Arnold and OpenVDB 4.0.0.

Binaries available for the following Houdini, Houdini FX, Houdini Indie and Houdini Education production builds:


and for the following platforms:

  • Linux x86_64 (gcc4.8)
  • Windows 7 x64 (vc14)
  • Mac OS X 10.8+ (clang7.3)


Please note that Houdini Apprentice does not support third-party renderers and thus cannot run HtoA.

  • Alembic Packed Primitive: support of alembic packed primitives using the new alembic procedural (htoa#591)
  • Non-Photorealistic Rendering: a non-photorealistic rendering (NPR) solution is provided as the combination of the contour filter and toon shader. The contour filter draws contour lines using the information provided by the toon shader and it works even for reflected or refracted objects. The toon shader can be used to obtain a cell animation look. A variety of interesting effects can be achieved by, for example, changing the line width using the edge_width_scale parameter, connecting a procedural texture to mask_color, or using stylized highlights. (core#5591, core#6848)
  • Adaptive sampling: Arnold now has the capability of adapting the sampling rate of each pixel when the enable_adaptive_sampling render option is enabled, allowing it to dedicate a greater number of camera samples (and thus also a greater amount of render time) to the pixels that show a greater variation in their sample values. When used, all pixels will receive a sampling rate of at least AA_samples, but no more than AA_samples_max. The adaptive sampler's sensitivity to noise may be controlled through the AA_adaptive_threshold render option, where lower threshold values will apply higher sampling rates to a greater number of pixels. The -asmax command-line option has been added to kick as well. (core#3165, core#6090, core#6686, core#6883)
  • Denoiser (noice): a stand-alone, post-process denoiser executable called noice is now bundled with Arnold. This is a high-quality denoiser that takes into account multiple frames and multiple light AOVs. It requires variance information for all AOVs and optionally uses normal, depth and albedo. (core#6322)
  • Denoiser (OptiX): the fast, GPU-powered Nvidia OptiX AI denoiser is now available in Arnold as a filter called denoise_optix_filter (core#6513). This filter has one parameter blend which is a float and controls the linear interpolation between the denoised and original pixel values. The filter can be applied to an output just like other filters, with the following limitations:
    • The filter must be unique for each output it is applied to. Meaning that you must create a new OptiX denoise filter for each output you wish it to be applied to.
    • The filter will only work with single-channel EXR images.
    • Outputs with the OptiX denoise filter applied will be received by the driver later than the outputs without. As the OptiX denoiser works on full frame images, driver_prepare_bucket and driver_process_bucket will be called again after the full frame has completed providing bucket data for only the denoised output.
    • If you want to render the same AOV with and without the OptiX denoise filter, we have added a feature to allow you to do so and avoid AOV name conflicts. You can add the suffix _denoise onto the end of an AOV name and the filter will source the name from the original AOV. For example, if we wanted to apply the OptiX denoise filter to the RGBA AOV, but already had an RGBA AOV added to the outputs, we could add an AOV named RGBA_denoise and the OptiX denoise filter will source the RGBA AOV as the input.
  • Alembic procedural: a procedural node called alembic which is capable of reading Alembic .abc files has been added. It resides in an external dynamic library that is by default located in the "plugins" directory of the Arnold core package. (core#6547)
  • Automatic loading of plugins from Arnold installation: Arnold looks for a directory "../plugins" relative to where the core shared library is installed and automatically loads procedurals, shaders, etc from that location. This is also the default location of the newly introduced Alembic procedural. (core#6808)
  • Operators: Operators are a new node type which perform per-object (node) parameter assignments and overrides, including late-bindings and deferred overrides on procedurally generated nodes. Operators can also create nodes and carry out general scene inspection and modifications. Operators can be chained together in a graph which is evaluated from a given target operator, set using AiOpSetTarget(node) or kick -op node_name. Multiple disconnected operator graphs can exist in the scene, where only the graph connected to the target operator will be evaluated for rendering. Operators can be ignored by setting options.ignore_operators to true or using kick -iops. Some operators provide a selection parameter which determines, using a wildcard expression, what nodes are processed by the operator. A series of operator nodes are now available: materialxset_parameterdisablecollectionswitch_operator, and set_transform. (core#6209, core#6210, core#6530, core#6606, core#6662, core#6699, core#6676, core#6700, core#6701, core#6878)
  • More efficient texture mapping: the performance of certain types of texture lookups, including opacity masks, skydome_lights, and certain kinds of specular and diffuse rays has been optimized. (core#6387, core#6391, core#6480, core#6603)
  • Faster scene initialization: scene initialization and update can be much faster as they are now performed in parallel by default. Multiple threading issues were fixed that also make the scene initialization code more stable. Finally, procedural contents are initialized asynchronously, in parallel with the rest of the nodes, to make full use of all available threads. In the case of interference with non-threadsafe scene construction techniques involving custom procedurals, parallel initialization can be manually disabled by setting options.parallel_node_init to false. (core#5724, core#5406, core#6744)
  • Difference filter: an auxiliary diff_filter for denoising that measures AOV variance has been added. (core#6462)
  • EXR metadata for AOVs: additional metadata tags (filter, filter width, LPE, original AOV source) have been added to describe output AOVs. (core#6461)
  • Matte shader opacity: the matte shader has gained an opacity parameter, so it can honor transparency the same way the built-in matte object parameter does. (core#6415)
  • Per-lightgroup shadow mattes: The shadow_matte shader has a new aov_group parameter that when enabled makes the shader sensitive only to lights with a matching aov setting. (core#6609)
  • Trace sets in ambient occlusion shader: the ambient_occlusion shader now supports the trace_set parameter to specify which objects are included or excluded. (core#6602)
  • extra_samples in hair shader: the standard_hair shader now supports the extra_samples parameter to use additional GI samples on a per-shader basis. (core#6443)
  • Improved uniformity in hair shader: like the classic hair shader, the standard_hair shader will now display a uniform result over a strand's cross-section, which can reduce sampling noise. (core#6444)
  • image tile tags optional offset: the <tile> tag in the image shader's filename now accepts an optional tile offset, instead of being hard-coded to one, e.g. <tile:0> is now possible. (core#6429)
  • New wrap mode in image shader: similar to the preexisting black wrap mode, there is now a missing wrap mode where lookups to the image shader that are outside the texture will use the missing_texture_color. (core#6430)
  • ID AOVs in standard_surface and standard_hair: the standard_surface and standard_hair shaders now support ID AOVs. These are useful for creating mattes. (core#6693)
  • Face mode option in color_jitter: with the new face_mode option, color can be randomized per quadrangle as well as triangle. (core#6495)
  • Reference positions from rgb/rgba array: procedural texture shaders (noiseflakes triplanar, and car_paint) can now read reference positions (Pref) from an rgb or rgba array as well as a vector array. (core#6729)
  • Arbitrary name for reference positions: users now can specify the name of the reference position user-data array in procedural texture shaders such as noise. Previously, the name was hard-coded as "Pref", which is still the default. (core#6709).
  • New AOV-write shader: an aov_write_rgba shader has been added which complements the existing rgbfloat and int variations of this shader. (core#6639)
  • Layer shaders: the newly added layer_float and layer_shader shaders can be used to mix float values and closures respectively. layer_rgba allows to composite textures. The maximum number of layers in these shaders is limited to 8. (core#6549)
  • normal parameter in passthrough shader: the passthrough shader now has a normal parameter that allows for the assignment of a normal or bump map that affects the entire network of shaders it is connected to. (core#6435)
  • Self-intersection detection in OSL trace: OSL shaders can now more easily inspect the self-intersection status of probe rays via the "hitself" trace message like so: getmessage("trace", "hitself", hit); This function assigns a 1 or 0 to the hitvariable depending on whether the ray intersects the same object or not. (core#6326)
  • Oren-Nayar transmission in OSL: the translucent closure in OSL, which is based on a back-facing Oren-Nayar shading effect, can now be fed a second parameter indicating the surface roughness in a similar fashion to the oren_nayar closure. (core#6424)
  • ginstance can override step sizeginstance nodes can now override the step_size parameter of volume containers such as points, polymeshes, cubes and spheres. This allows, for example, an instance of a volume shape to be shaded as a surface (by setting the instance step size to zero, opaque off, and using a surface shader). (core#6627)
  • Less confusing stack traces: Arnold would often misleadingly print out AiShaderGlobalsEdgeLength or AiCreateAtStringData_private in the call stack. These functions should no longer be displayed. (core#6439)
  • Structured statistics: render statistics can now be output to JSON files at the end of each render pass, either appended to or overwriting an existing .json file. This is much easier for tools to inspect rather than attempt to parse out the raw-text statistics in the logs that were meant for human consumption. (core#6108)
  • Better time statistics: additional timing statistics, organized by both nodes and categories, will now be output. This makes it possible to know which objects are most expensive to render and what parts of the renderer took the most amount of time. Detailed information about rendering performance can be output to a file in JSON format, such as "my_profile.json", by calling AiProfileSetFileName("my_profile.json") or kick -profile "my_profile.json", and then visualized in Google's Chrome web browser "chrome://tracing/". (core#5106)
  • Frame and fps global options: current frame and frames per second attributes have been added to options as options.frame and options.fps. This information will also be exported to rendered images as EXR metadata. (core#6474)
  • lmutil: a licensing tool called lmutil, which can be used to diagnose and solve certain FlexNet/AdLM/Clic licensing issues, is now distributed in the Arnold core package. (core#6528)
  • Progressive refinement (EXPERIMENTAL): a new rendering mode that completes a render call in multiple passes has been added to Arnold. During each of the intermediate passes, drivers that do not output to a file will be invoked after each tile has completed, which allows for display drivers to show a result whose noise progressively converges towards the result at the final AA sample settings. This mode can be enabled through the enable_progressive_render render option (default: false). Note that, in its current unoptimized state, this mode is not recommended for batch rendering at high AA samples, as the final passes can take very long to filter. This will be addressed in a future update. (core#6146)
  • Normal map issue using strength parameter with back facing normals (core#6734)

  • Reference positions do not work in triplanar (core#6264)

  • Clear up indirect node usage (core#6302)

  • Small bug fixes in car_paint (core#6396)

  • Zero-radius problem in random-walk SSS (core#6402)

  • NURBS and polymesh common parameters not copied (core#6576)

  • Fix bug in procedural name scope that was causing a race condition with parallel_node_init (core#6730)

  • Fix race condition in overrides (core#6731)

  • Fix bug in transformation of lights contained in procedurals when using parallel_node_init (core#6732)

  • Artifact with intersecting object in polymesh-based volumes (core#6736)

  • Fix race conditions in node name manipulation code (core#6741)

  • <attr> tag with index but without default value crashes (core#6752)

  • Implement missing `bsdf_merge` for hair BCSDFs (core#6756)

  • Python AtArray get and set functions crashing on error due to missing arguments (core#6766)

  • AiNodeLookUpByName() and AiNode() crash with non-procedural parent (core#6777)

  • Point and Vector functions in not returning correct type (core#6799)

  • NaN in Zinke BCSDF (core#6810)

  • High res opacity masks sometimes have incorrect regions (core#6837)

  • kick -ar (aspect ratio) is broken (core#6652)

  • AiMakeTx() fails with single-channel input and DWAA compression (core#6872)

  • Fix random crash with unnamed nodes (core#6738)

  • kick -ipr default value not working (core#6791)


See also the Arnold release notes for the full list of core enhancements and fixes.


  • No labels