Simple Point Cloud System not working on WebGPU

Requirement: I have a dynamic point cloud, whose rendering rate changes per frame. The value of the point cloud is read from some I/O or file so you can consider that each frame a new values are uploaded from host to device.

I have small code below from PCS example:-

const scene = new Scene(engine);

const camera = new ArcRotateCamera("my first camera", 0, Math.PI / 3, 10, new Vector3(0, 0, 0), scene);
camera.setTarget(Vector3.Zero());
camera.attachControl(canvas, true);

const light = new HemisphericLight("light1", new Vector3(0, 1, 0), scene);
light.intensity = 0.7;

var pcs= new BABYLON.PointsCloudSystem("pcs", 1, scene)
var initRedParticles = function(particle : BABYLON.Particle) {
    particle.position = new BABYLON.Vector3(0.5 - Math.random(), 0.5 - Math.random(), 0.5 - Math.random());
    particle.color = new BABYLON.Color4(1.0, 0.0, 0.0, 1);
    particle.lifeTime
}

const pointCloudCount = 50000;
pcs.addPoints(pointCloudCount, initRedParticles);
pcs.buildMeshAsync().then(() => {});

pcs.updateParticle =((particle: BABYLON.CloudPoint) : BABYLON.CloudPoint => {
    particle.position._x += 0.01;
    return particle;
});

scene.registerAfterRender(() => {
    pcs.setParticles();
});

return scene;

Query 1: This program works nicely on WebGL2 however on WebGPU it crashes with errors. How can I make it work on WebGPU, am I missing something in this example?

Error on WebGPU(OS: Mac, Canary Version 100.0.4887.0 (Official Build) canary (x86_64))

BJS - [20:43:00]: Babylon.js v5.0.0-beta.8 - WebGPU1 engine
:8081/#/:1 Entry point "main" doesn't exist in the shader module [ShaderModule].
 - While validating vertex stage (module: [ShaderModule], entryPoint: main).
 - While validating vertex state.
 - While calling [Device].CreateRenderPipeline([RenderPipelineDescriptor]).

logger.ts:118 BJS - [20:43:01]: WebGPU uncaptured error (1): [object GPUValidationError] - Entry point "main" doesn't exist in the shader module [ShaderModule].
 - While validating vertex stage (module: [ShaderModule], entryPoint: main).
 - While validating vertex state.
 - While calling [Device].CreateRenderPipeline([RenderPipelineDescriptor]).

Logger._WarnEnabled @ logger.ts:118
(anonymous) @ webgpuEngine.ts:628
250[Invalid RenderPipeline] is invalid.
 - While encoding [RenderPassEncoder].SetPipeline([Invalid RenderPipeline]).

logger.ts:118 BJS - [20:43:01]: WebGPU uncaptured error (2): [object GPUValidationError] - [Invalid RenderPipeline] is invalid.
 - While encoding [RenderPassEncoder].SetPipeline([Invalid RenderPipeline]).

Logger._WarnEnabled @ logger.ts:118
(anonymous) @ webgpuEngine.ts:628
249[Invalid CommandBuffer] is invalid.
    at ValidateObject (..<URL>)
    at ValidateSubmit (..<URL>)

logger.ts:118 BJS - [20:43:01]: WebGPU uncaptured error (3): [object GPUValidationError] - [Invalid CommandBuffer] is invalid.
    at ValidateObject (../../third_party/dawn/src/dawn/native/Device.cpp:564)
    at ValidateSubmit (../../third_party/dawn/src/dawn/native/Queue.cpp:396)

Logger._WarnEnabled @ logger.ts:118
(anonymous) @ webgpuEngine.ts:628
logger.ts:118 BJS - [20:43:01]: WebGPU uncaptured error (4): [object GPUValidationError] - [Invalid RenderPipeline] is invalid.
 - While encoding [RenderPassEncoder].SetPipeline([Invalid RenderPipeline]).

Logger._WarnEnabled @ logger.ts:118
(anonymous) @ webgpuEngine.ts:628
logger.ts:118 BJS - [20:43:01]: WebGPU uncaptured error (5): [object GPUValidationError] - [Invalid CommandBuffer] is invalid.
    at ValidateObject (../../third_party/dawn/src/dawn/native/Device.cpp:564)
    at ValidateSubmit (../../third_party/dawn/src/dawn/native/Queue.cpp:396)

Query 2: Is it possible to update on first N elements and draw only those first N elements, the rest element which are not updated from the buffer should not be visible?

For example: I created a point cloud with 10 points in total.
In Frame 1: Only 3 point have updates so I like to update the first 3 points and draw them, I like hide the rest seven points in the buffer.
In Frame 2: Only 6 point have updates so I like to update the first 6 points and draw them and rest 4 remain hidden or invisible.

@Evgeni_Popov is the gl_PointSize is a culprit here? Is this bug a duplicate of Custom mesh with Point primitive does not renders in WebGL2 and gives error on WebGPU ?

Yes, it is the same problem.

Regarding drawing only some particles and not others, it seems it is not supported by PCS. What you can do is updating only some particles by passing a start/end index to the setParticles call but all the particles will still be displayed.

Thanks for confirming the first part. I will wait for the another next beta to test it.

I believe that’s the case with PCS I am faced this issue and thought to double check.

Closing this. Highly appreciate your help.

If I use Custom Meshes in place of PCS will it help or be the same case?

Otherwise, what would be the best class to serve transient geometry(who’s vertex and vertex count changes per frame). I want to avoid constant allocation and deallocation per frame as it may drain performance. So my expectation was to allocate a big chunk and update on first N element and execute draw called with N elements.

Yes, creating a custom mesh may be the solution. You would have to handle yourself the creation/updating of the vertex and index buffers.

Sure let me approach with custom mesh and implement it. Thank you. Closing this issue.

1 Like