Giter Site home page Giter Site logo

Comments (6)

RenaudRohlinger avatar RenaudRohlinger commented on June 8, 2024 3

Interesting topic here! drawIndirect is also part of my roadmap for achieving a new type of 'static' scene that I have in mind for threejs. I have started working on it here, with the support of the CAD software Plasticity.

Here is how I envision my roadmap:

  • Add RenderBundle support with this pull request.
  • Implement a single buffer pass with the pull request of @aardgoose #27388 to batch all the writeBuffer commands in one command, already bundled by a RenderBundle.
  • Add a global UBO pipeline (UBO for the camera and scene elements such as fog, etc.) to update only a single UBO per frame, (instead of pre-calculating the modelViewMatrix on the CPU per mesh per frame) and multiply camera matrices by model matrices directly on the GPU instead of on the CPU.
  • Add frustum culling support via indirect draw calls and compute shading as described in Toji's article Render Bundles and Object Culling.

Each feature on this roadmap should be cherry-pickable once shipped to three.js.
I have never studied Unreal Nanite technology, but I believe all these features combined would be what's needed for this type of GPU rendering

from three.js.

CodyJasonBennett avatar CodyJasonBennett commented on June 8, 2024 1

I've been implementing that exactly, and you may take an interest to #28103 in lieu of indirect draw or some of my GPU driven experiments with meshlets and culling/visibility tests particularly https://twitter.com/Cody_J_Bennett/status/1736555185541886407, https://twitter.com/Cody_J_Bennett/status/1730911419707842973.

from three.js.

AIFanatic avatar AIFanatic commented on June 8, 2024

Hi @CodyJasonBennett I have came across your gpu-culling code before and if im understanding it only discards the fragment shader by setting the w value to 0 if not visible in the vertex shader. This is my issue with current solutions, same with BatchedMesh.
I have done some tests and discarding geometry in the vertex shader gives some performance boost but not a lot, specially considering that most meshlets won't be rendered. Also would be great to discard things on a geometry level and not on a geometry vertex level, if a whole meshlet is not visible I would like to just discard the whole thing in one go instead of discarding each vertex, wasting gpu.

With drawIndirect we can do something like (each is a compute pass):

  1. With meshlets AABB's and indices perform visibility culling
  2. Prefix sum
  3. Reindex
  4. Count visible meshlets
  5. Create indirect buffer based on above

After all done drawIndirect can be used with the GPU data to directly render the visible meshlets only, no need to go over invisible ones, also no gpu->cpu transfer is needed. Keep in mind that rendering the meshlets is not the issue, I have implemented something akin of an InstancedMesh for meshlets that can draw many instances in one draw call. The visibility culling is the problem, in non web environments this is easily solvable by using mesh shaders.

Offtopic but big fan of four, planning on using it as a base for what im trying to do above.

from three.js.

CodyJasonBennett avatar CodyJasonBennett commented on June 8, 2024

FWIW those experiments were as close as I could get to GPU driven rendering which is comparably trivial in WebGPU. The use of transform feedback performs culling at the instance or batch level and then the vertex shader will short circuit if the resulting instance buffer is zeroed. Doesn't work so great for virtualized geometry where you have a fixed number of vertices or vertex buffer memory; you want to move data and this can only be done with compute or carefully vectorized CPU code via WASM with GPU driver overhead from upload (introduces latency). May be the easiest path for you in the near term since you're already using METIS and Meshoptimizer.

On the topic of indirect drawing in WebGPU, or more specifically the WebGL compatibility side, my knee-jerk thought is to fallback to multi-draw (hence the backlink to my PR), but the data is different. WebGPU expects an interleaved buffer with draw arguments, but multi-draw expects separate buffers per argument, and they have to be consumed on the CPU. It may be best to consider this feature WebGPU only and consider compatibility only when proven feasible (cc @RenaudRohlinger, curious of your opinion here). This is one of the flagship features of WebGPU people migrate specifically for, alongside GPU shared memory, atomics, multisampled textures, etc. There is no WebGL 2 equivalent, even if it can be ported in a strictly worse fashion.

from three.js.

CodyJasonBennett avatar CodyJasonBennett commented on June 8, 2024

I'm not sure how that relates to this issue. What's described here is indirect drawing which would benefit from an interface with compute. That seems like a backlog of issues which affect WebGPURenderer generally.

from three.js.

CodyJasonBennett avatar CodyJasonBennett commented on June 8, 2024

I won't hijack this issue any further, but I'm happy to explore this topic in WebGPU and later WebGL 2 (with expected latency). Today, I would lean with WASM + multi-draw which could use #28103. This is an area I've incidentally been studying which was the motivation behind all the prior work I linked. Awesome progress and great to see I'm not alone on the web, Bevy aside.

from three.js.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.