My coding journey: deploying an interactive three.js app with react and supabase during the next 30days

Hey :slight_smile:
I’m a designer and frontend developer and it’s been few days that I am diving into threejs, mostly following the threejs journey course by Bruno Simon.
Apart from learning the technology and start exploring generative art, I decided to build a side project I had in mind since years, and that finally I decided to take the time to code it (at least a working demo).
Here I try to explain what the project is about: https:nooverse.xyz
I’m quite scared as a beginner to approach threejs to build something like that, therefore I thought that sharing my thoughts, progresses and blockers here in the open may help me to overcome the pain and frustration that they will accompany me during the large part of the development :joy: :sweat_smile:

DAY 1
I’m collecting a bunch of code snippets or visual references that may resonate with nooverse to take inspiration from (aka copy as much code as possible :face_with_monocle: )
Given that I do not know yet the precise effect I want from the ocean, I am basically picking what I like or just useful bits:

I’ve decided to recreate the codepen listed above made in three.js with react-three-fiber. It has some features that are pretty good for my demo:

  • Each rain drop is a new emotion submitted
  • I love the concentric circles effect that the rain drop produces when it touches the floor
    Of course, it’s not straightforward as I hoped :grimacing:

That’s what I accomplished for today:

Here the code

Time for a :beer:

1 Like

wow, just found this forum entry that shows an amazing scenario :star_struck:

1 Like
for (let i = 0; i < 60; i++) {
  for (let j = 0; j < 30; j++) {
    array.push(
      <mesh receiveShadow key={Math.random() * 5} position={[(i/2)-15, 2, (j/2)-10]}>
        <boxBufferGeometry attach="geometry" args={[0.3, 0.3, 0.3]} />
        <meshStandardMaterial attach="material" metalness={0.3} roughness={0.8} color="hotpink" emissive={'#000000'} />
      </mesh>
    )
  }
}

i have some hints if you dont mind :partying_face:

  1. this creates 1800 drawcalls, 1800 geometries and 1800 programs (materials). you could have the entire thing in a single one if you instance these meshes: Instanced vertex-colors - CodeSandbox think of drawcalls as something to avoid in general. it can be a real downer digging into webgl thinking it’ll be much faster only to have it run slower than the dom ever could. webgl can be super fast, but it’s working with tricks like occlusion and instancing to achieve that.
  2. key={Math.random() * 5}, better key={i + "/" + j} because it’s stable. but again, if you do #1, you won’t need it at all.
  3. <boxBufferGeometry attach="geometry" args={[0.3, 0.3, 0.3]} /> it’s <boxGeometry ... />, no need for the attach, and this will create 1800 geometries. better create one, in global space if you want: const box = new THREE.BoxGeometry(0.3, 0.3, 0.3) and re-use it: <mesh geometry={box} ...>
  4. <meshStandardMaterial attach="material" ... /> you don’t need the attach, and same for the material, 1800 materials. this is perhaps the most expensive bit in your code.
3 Likes

Thanks a ton! This is exactly the kind of feedbacks I was hoping to receive to point me to the right direction :smile:
I was pretty sure I was taking the more resource-draining approach for such a simple scene - but I wasn’t aware of InstancedMesh.
Now I’ve updated the scene using it as you suggested, and thanks to a code snippet created on the fly by the react-three-fiber discord community I now have a cool sphere made by thousands of boxes (icosahedrons to be more accurate :nerd_face: ).
I was thinking that a sphere representing group of emotions will result in a better UX, instead of a simple plane geometry - probably it is a good moment to draw some sketches of the result I want to obtain before move further…
Here the codesandbox

DAY 2
I drewn a preliminary UI on figma to get a better overview of which features and steps I need to tackle first…
It’s quite dumb and will likely dramatically change over time but here the draft:

Next steps

  1. Use 3 different colors to represent the icosahedrons (eg. the 34% of icosahedrons will be painted blue, 29% red, 37% pink). That should be trivial, apart from the fact that I do not want the colors to be applied randomly, but they should create uniformly colored bands. The colors in the future will depend by the % of different emotions submitted, but let’s do small steps…

  2. Each icosahedron needs to be animated, in a way that the whole sphere looks like a blob…
    Here some references I’m gonna use:

  3. Apart from the blob effect, I need to apply some sort of magnetic and or gravitational forces (??) so that the icosahedrons will be constantly moving within the sphere surface and change position among them. This is because I want different colored icosahedrons to constantly mix between them.
    Here an awesome reference for the final effect I want to obtain:

I think for point 2. I should be able to do it messing with sin and cos within useFrame hook…
For point 3. i’m gonna use useCannon hook to add physics effects, but at present I do not know much more than this.
I think this will take a while :sweat_smile: :see_no_evil::man_dancing:

Apart from the blob effect, I need to apply some sort of magnetic and or gravitational forces (??)

this is usually just a noise function on the shader, curl noise most likely. https://twitter.com/0xca0a/status/1434941585934934022

1 Like

GPGPU is the way: GPGPU - Particles and the box

1 Like

Thanks, btw do you know why the demo returns “Error creating WebGL context.” ?

gpgpu uses shared floating point datatextures, they are not supported on every device.

DAY 3 - 4: Despair & frustration.
I kinda expected it :sweat_smile: I am confident on the react and supabase part, that is building the UI and the logic to fetch and update the datastructure built with supabase. But as a noob with three.js (and R3F), even the most basic things seem overwhelming. I’m still having hard times porting a simple three.js file in R3F, something that I imagined pretty trivial. Therefore trying to achieve a thousands particles system gravitating as a sphere, adding magnetic attractions and raindrops and so on - seems way to much to digest. ATM I’m thinking if a better solution would be to ease the visualisation to something I could reasonably achieve without losing my mental health :crazy_face: or keep struggling for a few more days to eventually find a workable path…