R3F Lightformers in vanilla three js

Trying to get a basic lightformer setup into vanilla JavaScript

after looking into roomEnvironment.js like mentioned in this thread

the thing i noticed are

  • pmremGenerator takes out hdr cubemap renders of the scene/object passed
  • all light emitting meshes have color rgb values much greater than 1 : demo
  • if you pass a mesh with hdri no data seems to be lost: demo
  • using different shapes and sizes of mesh we can have more creative lighting setups like this r3f demo

Also checked out the lightformer/env editor https://env.pmnd.rs/ looks amazing + awesome UI .

Doubts

  • checked the drei lightformers.tsx file but pmrem is never mentioned
  • If i update env on animate loop the on phone the fps drops alot
  • how do you change the resolution of pmrem ?

@drcmda how close am i ?

you do not need pmrem.fromScene, just a regular cubecamera that films a virtual THREE.Scene into a THREE.WebGLCubeRenderTarget. i say virtual because it’s not part of the normal scene you render out. the cube-cam-scene contains light formers, softboxes and so on. the texture result of that rendertarget can plug right into your main scene.background and/or .environment.

now every time you call cubecam.update() it will render into the texture again, and if you render every frame you have a realtime environment map. runtime env doesn’t work on all platforms, that’s why all these r3f demos have <PerfMonitor> which makes it static if it detects problems with the fps.

2 Likes

Is this the code for the cube camera being used here ?, want to check the type, encoding ,filter etc

more or less yes, it happens here drei/Environment.tsx at 5faa042c225d370b4cbacbc8f007ab4cafd3fddd · pmndrs/drei · GitHub

in principle it’s just this:

  // This is the scene that receives the lightformers
  const virtualScene = new THREE.Scene()

  const fbo = new THREE.WebGLCubeRenderTarget(resolution)
  fbo.texture.type = THREE.HalfFloatType
  const cam = new THREE.CubeCamera(near, far, fbo)

  scene.environment = fbo.texture

let count = 1
function loop() {
  if (frames === Infinity || count < frames) {
    cam.update(gl, virtualScene)
    count++
  }
}

btw this is a good opportunity to hash out a generic structure for loop access, resize and overall reactivity. maybe something like a base class from which all your primitives inherit.

1 Like