• Stars
    star
    280
  • Rank 142,399 (Top 3 %)
  • Language
    JavaScript
  • Created about 7 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

GPGPU physics for Three.js

GPGPU rigid body physics for Three.js

Launch demo or watch the video. NOTE: Works only on desktops with good GPUs.

Demo

Full examples

Demos

Usage

Include gp.js into your Three.js project HTML:

<script src="gp.js"></script>

Sample code below. See the examples/ directory for full examples.

// Create a simulation world
var world = new gp.World({
    renderer: threejsRenderer,            // Must be a THREE.WebGLRenderer
    maxBodies: 128 * 128,                 // Max number of bodies
    maxParticles: 128 * 128,              // Max number of particles (each body consists of a number of particles)
    radius: 0.05,                         // Size of a particle in the simulation
    stiffness: 100,                       // Contact stiffness
    damping: 0.4,                         // Contact damping
    fixedTimeStep: 1/60,                  // Simulation timestep
    boxSize: new THREE.Vector3(10,10,10), // World collision bounds

    // The "grid" is a box where collisions can occur. Specify its position and resolution.
    // The size of the grid box is gridResolution * radius * 2
    gridPosition: new THREE.Vector3(0,0,0),
    gridResolution: new THREE.Vector3(128,16,128),

    gravity: new THREE.Vector3(0,-1,0),
    friction: 0.4,
    drag: 0.3,
});

// Create a body
//                         position   rotation   mass  inertia
var bodyId = world.addBody(0, 0, 0,   0,0,0,1,   1,    0.1,0.1,0.1);
world.addParticle(bodyId, 0,0,0); // Add a particle in the center of the body

// Get the UV coordinate for the body
var uv = world.getBodyUV(bodyId);
myCustomShaderMaterial.uniforms.bodyUV.value = uv;

// A simple render loop can look like this:
var prevTime;
function render(time) {
    requestAnimationFrame(render);
    
    // Calculate time since last frame
    var deltaTime = prevTime ? (time - prevTime) / 1000 : 0;
    prevTime = time;
    
    // Update physics    
    world.step( deltaTime );

    // Use textures from the world, they contain positions and rotations of all bodies.
    // Note: you need to fetch these textures every frame from the World, since they are swapped by the World every step.
    myCustomShaderMaterial.uniforms.bodyPositionTex.value = world.bodyPositionTexture;
    myCustomShaderMaterial.uniforms.bodyQuaternionTex.value = world.bodyQuaternionTexture;

    // Render scene
    renderer.render( scene, camera );
}
requestAnimationFrame(render);

Implementation

The demo is largely based on GPU Gems 3 ch. 29, Real-Time Rigid Body Simulation on GPUs. It heavily relies on the THREE.WebGLRenderTarget class and custom shaders.

The simulation loop is in short:

  1. Create float render targets of size N*N for bodies: position, quaternion, velocity, angular velocity, force, torque.
  2. Create float render targets of size M*M for particles: local position, world position, relative position, force.
  3. Create float render target of size 4*M*M for a broadphase grid.
  4. While running:
    1. Calculate particle properties: world position, body-relative position, velocity.
    2. Set up "broadphase render target". Stencil buffer is set up for stencil routing (see this presentation, slide 24) by clearing once (to set stencil values to zero) and drawing point clouds thrice to set values 1, 2 and 3 into the stencil buffer. An alternative is using PBOs to set these values, but it doesn't seem to be available in WebGL1.
    3. Particles are drawn to the "broadphase render target" using GL_POINTS with point-size 2. This maps them into the correct "grid bucket" and writes the particle ID's there. The stencil routing guarantees four particle ID's can be drawn into the same grid bucket in this single draw call.
    4. Particle forces are calculated using spring-and-dashpot model equations. Neighboring particles are easily looked up in the broadphase render target.
    5. Forces are added to the bodies' force render target using GL_POINTS with additive blending. Other forces such as gravity is added here too.
    6. Torque is added to bodies' torque render target in the same way.
    7. Body velocities are updated: velocity += deltaTime * force / inertia.
    8. Body positions are updated: position += deltaTime * velocity.
    9. Render each body by looking up body position and quaternion in the correct render target texture.

More Repositories

1

cannon.js

A lightweight 3D physics engine written in JavaScript.
JavaScript
4,584
star
2

p2.js

JavaScript 2D physics library
JavaScript
2,607
star
3

poly-decomp.js

Decompose 2D polygons into convex pieces.
JavaScript
416
star
4

ammo.js-demos

Demo application base class and 3D physics demos based on ammo.js. Support for several scenegraphs including Three.js and SceneJS.
JavaScript
114
star
5

imgui-wasm

imgui/wasm boilerplate
C++
42
star
6

cartridge.js

HTML5 retro game engine
JavaScript
38
star
7

codegif

Use Canvas API to make a gif animation
JavaScript
36
star
8

motionblur

WebGL shader effect
JavaScript
34
star
9

remote-physics

A node.js app that runs a physics engine and lets clients download physics data in real time.
JavaScript
24
star
10

occlusion-culling.js

Occlusion culling tests using three.js
JavaScript
20
star
11

vehicle-editor

A goofy vehicle editor made using Cannon.js physics and Goo Create.
JavaScript
19
star
12

floatcompress.js

Simple library for doing lossy compress of floats. Can be used to pack floats into a typed array when high precision is not needed.
JavaScript
16
star
13

goo-cannon-softbody

Experimenting with soft body simulation using Cannon.js in Goo Create
JavaScript
16
star
14

physicstoy

2D physics editor
JavaScript
12
star
15

voronoi-cube

Exploding cube in WebGL/GooEngine using 3D Voronoi tessellation data. (Goofy Day project)
JavaScript
12
star
16

sweep-and-prune

2D collision detection for AABBs
HTML
11
star
17

doc.js

Web based on-the-fly documentation generator targeted for JavaScript.
JavaScript
11
star
18

gpu-springs

GPU accelerated spring simulation
JavaScript
9
star
19

smart-signal-routing

Orthogonal connector routing for use in interactive diagram editors
JavaScript
8
star
20

m.js

JavaScript matrix math library that uses typed arrays.
JavaScript
7
star
21

velvet-drop

GPU cloth simulation (a.k.a Velvet Drop) made in Goo Create
JavaScript
6
star
22

tinygoon

8-bit style WebGL multiplayer game using the GamePad API
JavaScript
5
star
23

CreateForge

Visual shader editor for Goo Engine
HTML
5
star
24

dansa

Dance game for the web
JavaScript
5
star
25

taptruck

Mobile 2D WebGL game. Drive the truck to the goal without tipping over.
JavaScript
5
star
26

jox

Source code documentation generator for JavaScript
JavaScript
5
star
27

hyper-cube

Spinning Cube made with Goo Create
JavaScript
4
star
28

goo-p2-platformer

Simple physics based platformer scene built using Goo Create and engine.
JavaScript
4
star
29

refract

2D WebGL puzzle game. Guide the laser beam to the goal.
JavaScript
4
star
30

goo-bunnymark

Tribute to Pixi.js bunnymark. This time in 3D, made with Goo Engine.
HTML
3
star
31

multibody-xml

An XML markup language for descibing a physical multibody system.
3
star
32

bomb-sorting-game

Sort the boxes into their containers!
JavaScript
3
star
33

fuffrboxing

3D WebGL mobile game made for Fuffr
JavaScript
2
star
34

schteppe.github.com

2
star
35

node-mysql-querycache

Query caching to relax your MySQL database. Layer on top of node-mysql.
JavaScript
1
star
36

wasm_test

WebAssembly
1
star
37

ragdoll-goon

Almost-working goofy project. Need to be fixed!
JavaScript
1
star
38

goon-yoga

Yoga for the Goon. Built with Goo Engine.
JavaScript
1
star
39

fb-node-issues

Public Issue tracker
1
star