PointCloud Feature Implementation - Need Guidance


I am a blender user who very frequently uses Houdini to generate large point cloud simulations, and I’d like to see proper support for alembic pointclouds in Blender:

My goals were:

  • A. Be able to use Alembic import to import points as a pointcloud, not verts on a mesh. This created the limitation that colors and attributes had to exist on face loops, which pointclouds do not have.

  • B. via geo nodes, be able to instance other geometry onto the points, and use “transfer attribute” with index and have it work. (This works by using “index / [num vertices on instancing geometry]”).

  • C. even better, have Cycles X render point clouds as spheres, as approached in this differential D9887.

  • D. ensure point cloud renderings had access to attributes imported in step A for alembic files.

tldr I created some branches, and I need to know the way to submit differentials.

Branch A - Alembic → Pointcloud Importer
This was pretty straightforward, though it was important to also change the procedural renderer (alembic_read.cpp) to be consistent with the rest.

Once I was able to get the pointclouds into Blender here, I had achieved goal A but I still needed to support B - transfer attribute by index.

Branch B - Mesh and Point Cloud Info Geometry Nodes

Each point input has attributes that must be instanced by realized geometry.

When instancing these points to geometry, (say a 4 point plane), the 1 point attribute could be transferred to the 4 points of the plane if they referred to the same source point.

The source point index for any destination point is (index_realized / vertices_per_instance).

tldr Mesh Info provides the verticies_per_instance.

This is loads faster than using geometry searches for the same purpose.

Branch C - Cycles Point Cloud as Spheres

This branch took the work from branch A and combined D9887 which was then refactored to commit 7b530c6096112c9a15db2e637d44012e248f1ab4 (origin/blender-v3.0-release).

I learnt a lot about Optix kernel rendering, kernel textures, woof - ultimately I have this rendering on CPU, CUDA, and OPTIX on my 3090 on Manjaro. The material issues that were mentioned in the original diff appear to be resolved.

Now what?

Due to the complexity of the work spanning across various modules, and the result ultimately being one diff, with large parts ultimately being authored by pmoursnv and brecht, how best should I submit diffs?

Can I present the Alembic and Mesh and Point Cloud Info nodes as 1 diff, and somehow present the D9887 refactor as another?

Thanks for your help, looking forward to contributing!


Here’s a sample render of 1.77mil points as spheres (normals modified by noise texture to create faceted appearance):


For Cycles point cloud rendering, feel free to submit that as a new diff. I plan to finish that in 3.1 but have not gotten around to updating it yet, so that will be helpful.

For the Alembic changes, that should be submitted as a separate diff. It sounds like that may overlap with this work, which we also hope will be in 3.1:

New geometry nodes should be submitted as their own diff as well.

Right, I agree with @brecht here, generally it’s helpful when diffs are smaller rather than larger combinations of changes from multiple areas.

Design-wise, personally I would really like to have an alembic import node to avoid having to use a separate modifier.


Thanks! I’ll split up the diffs and submit them.

Also, just to test what I’ve learnt, it seems that when we used Optix to build a BVH tree, that we are not populating a number of kernel textures: __prim_index, __prim_type, etc… - or is this potentially just a bug I noticed, or rather that they were unavailable at time of point_intersect? ;shrug; I did get it to work by using the arguments already in the stack instead of kernel_tex_fetch:

#ifdef __KERNEL_OPTIX__ /* __prim_index is not on OPTIX */
  const int prim = prim_addr;
  const int prim = kernel_tex_fetch(__prim_index, prim_addr);

I thought this was weird but I would get cuda illegal address errors without it.
I also saw in the optix API that getPrimitiveIndex() has the geo->prim_offset applied already.

Lots of learning :slight_smile:

1 Like

Thanks for your help!
Here’s the rendering diff:

These are now only populated for the BVH2 as used by CUDA.

For curves we now do the prim_index lookup in the BVH2 traversal code, points should do the same.

Thanks, should I update the diff to move the logic? It’s a bit messy to read in the kernel.

Related diffs:
“Mesh Info” and “Point Cloud Info” Geometry Nodes
Alembic PointCloud import from point samples

1 Like

I’ve been testing the new Alembic import implementation from @KevinDietrich because it can read arbitrary attributes, but I woud like to be able to use point clouds and render them efifciently, so does your implementation read arbitrary attributes?

Also to get the point rendering feature, do I have to apply those other two patches?

Hi - you don’t need the other patches.
I’m using alembic with arbitrary attributes, but I use my alembic pointcloud import from point samples diff: ⚙ D13250 Alembic PointCloud import from point samples – I have not tried Kevin’s but I’d be surprised if didn’t work.

1 Like

I’ll test it, because I’m having some instability issues with the @KevinDietrich version, I already told him and will wait until he can fix things, so meanwhile I’ll test your implementation.

BTW is it compatible with 3.0 branch?

Actually, I already fixed the issues you told me about in the chat, I just pushed the branch.

As for @soundofjw work, it does not support as many attribute types as my version.

Also, for the GeometrySet implementation, since ModifierTypeInfo.modifyGeometry has precedence over the ModifierTypeInfo.modifyMesh, we cannot just have the Alembic part of the modifier to use GeometrySets, USD has to be changed as well, otherwise the modifier is broken. I already did this work in my branch (so both Alembic and USD make use of GeometrySets), so my patch mentioned in a previous post is quite outdated. I’ll compare @soundofjw’s patch with mine and see what I can take from there.


Then I’ll update it with your version and apply the point cloud render patch :+1:

Thanks Kevin! I’m not attached to my work on the alembic experience - thanks for being far more diligent. I should imagine this will all work with your alembic patch. :slight_smile:

I think the only odd thing I did was a quality of life from houdini to change “pscale” into “radius”, which likely wouldn’t have been canon anyway.

edit: and oops yes all my work came off the v3 release branch.

1 Like

@KevinDietrich I updated my branch with yours, so far so good, I tested the “wood.abc” that was crashing and it’s ok, I have not tested the mantaflow one yet, but I assume it should work, I’ll test it later.

@soundofjw I tried applying the patch and I succeded without any trouble, however I can’t seem to be able to render, do I have to enable something specifically?

This is my result with your .blend file, so clearly something is not working:

I’ll come back with more info after I investigate it a bit more.

Ok, after testing a pure blender-v3.0-release branch where I just applied the render patch, I cannot render point clouds.

Is there something more I need to apply?

EDIT: May be a Cmake option?

I have been testing it with make full - have you tried other render devices, GPU vs CPU, maybe we can single out the issue!


Yes, it does not work in any of them, you can find my branch here, I use Cmake-gui to configure the build:

This has the @KevinDietrich alembic implementation and your point cloud rendering patch :slight_smile:

1 Like

I need to learn more myself - can you ensure that the points have a “radius” attribute? Are there any other changes on the branch?

Yes, Light Groups, but it’s easy, try applying your patch to the branch blender-v3.0-release, I tested this precisely to discard any conflict with my branch.
Also, regarding the radius, I used also your own scene to test it, and you can see the result in the screenshot I posted :slight_smile: