The main goal is to bring a bit of structure to the use of quaternions
in the Cycles kernel.
Prior to this change there was no dedicated quaternion type and float4
was used instead, and quaternions are stored as (x, y, z, w) matching
naming between the quaternion and float4 fields. However, Blender uses
(w, x, y, z) quaternion order for attributes, which is different from
what Cycles uses. Without dedicated type this either leads to different
quaternion orders depending whether it comes from attribute, or makes
it intrinsically not possible to use implicit sharing.
This change introduces Cycles Quaternion type which is compatible with
Blender attribute math::Quaternion in both layout and alignment, making
it possible to benefit from implicit sharing and use a nice structure
in the kernel.
This change does not modify the existing quaternion usage in the kernel
which is currently used for transform decomposition and interpolation.
There is currently no SIMD for the Quaternion type, which allows to
avoid any special alignment requirement and share attributes with
Blender, but performance might not be ideal.
This attribute type will be used for representing gaussian splat
rotation.
The attribute access and interpolation matches behavior prior to this
change. Added some basic tests for quaternion attribute access for RGB
and alpha, mesh and volume attributes.
Ref #159470
Pull Request: https://projects.blender.org/blender/blender/pulls/163342
Motion is now part of the position attribute. On the kernel side, this
position is now stored as an attribute as well, replacing the previous
motion only attribute.
Pull Request: https://projects.blender.org/blender/blender/pulls/158728
Replace the single buffer/sharing_info pair on Attribute with a Buffer
struct, with one buffer for the center step and a vector of buffers for
the other motion sub-steps. Each step is its own allocation, so a single
step can be replaced or implicitly shared without disturbing the others.
Add Attribute::add_motion(), remove_motion(), and has_motion() to manage
motion sub-step allocations relative to the owning geometry's
motion_steps, and add data_motion_*() accessors for reading/writing the
sub-step data.
This is preparation for moving motion blur position/normal storage from
separate ATTR_STD_MOTION_* attributes into the corresponding base
attributes. No call sites are updated yet.
Pull Request: https://projects.blender.org/blender/blender/pulls/158728
Use packed_float3 instead of float3 for geometry positions and various
other arrays.
Add and use unified accessor methods get_position() and get_radius() for
all geometry, as well as num_verts(), num_points() and num_keys().
Pull Request: https://projects.blender.org/blender/blender/pulls/158728
This commit extends Cycles to allow using Attribute array implicit
sharing info from Blender. This is used to avoid a copy of the evaluated
attribute arrays before they're added to the final buffer for their type.
We can only do this when the attribute type layout match between Blender
and Cycles, which means float and float2 attributes can skip the copy on
the point or curve domain, and also the face corner and face domains in
the adaptive subdivision case.
The buffer stored in attributes is now a raw pointer rather than a
std::vector. As a side effect, resizing the attribute no longer
zero-initializes new values. That was wasted work in practice anyway.
Unfortunately float color and float4 attributes are not covered here
because Blender does not allocate these types with the necessary
alignment. That can be addressed later; I've started it here: !156035.
Besides that, there are some other next steps:
- Use implicit sharing to avoid copying data that Cycles doesn't process
as attributes, like topology arrays for adaptive subdivision (and
maybe investigate removing padding so that float3 can be shared too).
- Add some sort of global cache to avoid creating multiple Cycles arrays
for attributes that aren't layout compatible or are on non-matching
domains.
- Add some way to delay the attribute type conversion and flattening
until constructing the final arrays, to benefit non-layout-compatible
types.
- Looking much further into the future, completely avoid the "large
buffer per data type" system that Cycles uses to hold geometry data
(just mentioning this because "completely avoid all copies of Blender
data" is an interesting prospect).
Pull Request: https://projects.blender.org/blender/blender/pulls/155970
Implement the missing code for this, which is just copying the attribute
without interpolation.
This issue existed in Blender 5.0 already, however in Blender 5.1
attributes with constant values on other domains can get optimized
to a mesh attribute.
Pull Request: https://projects.blender.org/blender/blender/pulls/156307
When the attribute data is shared, retrieving a non-const pointer to
attribute data might trigger a copy in order to create a mutable version
of the data. Adding a "_for_write" is an established (in Blender) way to
make it clear when the non-const overload is called.
Sharing will be added later on in #155970
Pull Request: https://projects.blender.org/blender/blender/pulls/156169
This is more consistent with Blender and fixes various discrepancies
between Cycles and Blender with sharp edges and mixed flat and smooth
faces. This uses more memory, but is compensated by earlier octahedral
mapping and in the benchmark scenes memory is always the same or lower.
Fix#152812: Mix of flat and smooth faces has incorrect sharp edges
Fix#152496: Smooth faces that share one vertex have bad normals
Fix#100425: Issues with motion blur and autosmooth or edge splitting
Pull Request: https://projects.blender.org/blender/blender/pulls/153836
To reduce memory usage, store in a 32 bit packed_normal.
This requires more processing to read the normals, which may or may not be
offset by reduced cache misses. For CPU there is SIMD to decode 3 normals at
once. Overall performance impact seems minimal.
Co-authored-by: Alex Fuller
Pull Request: https://projects.blender.org/blender/blender/pulls/153836
Previously with adaptive subdivision this happened to work with the N
attribute, but that was not meant to be undisplaced. This adds a new
undisplaced_N attribute specifically for this purpose.
For backwards compatibility in Blender 4.5, this also keeps N undisplaced.
But that will be changed in 5.0.
Pull Request: https://projects.blender.org/blender/blender/pulls/142090
* Perform attribute interpolation as part of dicing.
* Remove temporary subd uv and face index attributes.
On a MacBook M3 with 12 P-cores and 4 E-cores, these changes overall give
a 10x-14x speedup on various scenes. Note that splitting is still single
threaded and can be expensive, and UV subdivision can be optimized more.
Pull Request: https://projects.blender.org/blender/blender/pulls/136411
* Add SubdAttributeInterpolation class for linear attribute interpolation.
* Dicing computes ptex UV and face ID for interpolation.
* Simplify mesh storage of subd primitive counts
* Remove kernel code for subd attribute interpolation
* Remove patch table packing and upload
The old optimization adds a fair amount of complexity to the kernel, affecting
performance even when not using the feature. It's also not that useful as it
does not work for UVs that needs special interpolation. With this simpler code
it should be easier to make it feature complete.
Pull Request: https://projects.blender.org/blender/blender/pulls/135681