Performance: clearing a texture quickly and texture rendering for simulation

Hi fellow Babyloner, this is a three part question on performance, but you get triple fake internet points! :slight_smile:

  1. What is the fastest way to clear a texture on every frame?
  2. Can I bind a texture to a thinInstanceBuffer without getting it back to the CPU?
  3. What’s a simple way to do a compute shader without WebGPU? :slight_smile: Do I need to do this a RTT with a separate pass, or could I somehow do it as part of the main render with some kludge? Any reference PGs?

For context, I’m trying a boids GPU implementation that uses some smart shortcuts to get a O(n + k) simulation on the GPU, nothing fancy or new: the idea is to store boid data (position, velocity) on float32 textures that are updated by a shader. I’ll need a sort of index texture that has to be zero-ed on every frame, and the texture with the positions will be used by thin instances to update the position/orientations. But this is going for > 1k meshes, so I’m trying to squeeze some basic bottlenecks.

For the texture clearing, the standard approaches seem to be clearRect, which apparently is CPU bound and vary a lot based on the platform and browser, and a GL call such as glCopyImageSubData or glClearTexImage, which seems to use ARB_clear_texture if available, but I couldn’t find how common that extension is on webgl. I don’t really care when the clearing is done, before or after rendering. I just want to do it as asynchronously and quickly as possible.

For the thin instance buffer, since I’m not updating a Float32Array on the GPU, I wonder if I can share the same buffer as the texture and get zero-copy. It looks like RawTexture.CreateRGBATexture() does this, but I’m not sure if the changed texture is sent back to the CPU.

1 Like

Maybe @sebavan can bring his incredible WebGL knowledge to this thread :slight_smile:

1 Like

I believe that for texture clearing there is a function scene.cleanCachedTextureBuffer()
Example - https://playground.babylonjs.com/#AS54U8#10

Thanks, but I don’t think this clears the texture (i,e, paint it with 0.0). It seems to set the buffers of all textures in the scene to null, which is something quite different.

Apparently there’s a OpenGL call not mirrored in WebGL. Perhaps gl.copyTexSubImage2D would work, but it’s still unclear if it’s a good way to do it.

2 Likes

@sebavan can I bother you once again to see if you have any input about this one?

w0000t, I completely missed this thread…

About clear a pretty fast one is to use the gl.clear command from a render target :slight_smile: you could use a scissorRect to only clear a certain area.

As there are no compute shaders on WebGL you can not share renderBuffer and GpuBuffer.

You should look into WebGPU for those :slight_smile: as you could leverage everything available there. And I think @Evgeni_Popov already did a simulation for boyids

The boid compute shader sample is in https://doc.babylonjs.com/advanced_topics/webGPU/computeShader but it’s a 2D one and obviously only working in WebGPU.

To clear a render target texture use engine.clear(...).

Textures can’t be bound to thinInstanceBuffer, only arrays of numbers (Float32Array, etc).

Textures must be passed as inputs to shaders. In WebGPU, storage textures can be filled by a compute shader and passed to the vertex/fragment shaders (but you must write your shaders with WGSL). See Writing shaders for WebGPU in WGSL | Babylon.js Documentation

Compute shaders are not supported in WebGL. You can do a RTT pass and fill your texture by the fragment shader.

2 Likes