Figured it out. See code:
const texture = await getSkyboxTexture(textureLoader)
material.colorNode = THREE.Fn(() => {
function rotateVector(vector, axis, angle) {
const vxp = axis.cross(vector)
const vxvxp = axis.cross(vxp)
const a = angle.sin().mul(vxp)
const b = angle.cos().oneMinus().mul(vxvxp)
return vector.add(a).add(b)
}
const q = new THREE.Quaternion()
const e = new THREE.Euler()
const cameraWorldRotation = THREE.uniform("vec3").onRenderUpdate(() => {
camera.getWorldQuaternion(q)
return e.setFromQuaternion(q)
})
let dir = THREE.positionViewDirection.negate()
dir = rotateVector(dir, THREE.vec3(0, 0, 1), cameraWorldRotation.z)
dir = rotateVector(dir, THREE.vec3(0, 1, 0), cameraWorldRotation.y)
dir = rotateVector(dir, THREE.vec3(1, 0, 0), cameraWorldRotation.x)
return THREE.texture(texture, THREE.equirectUV(dir), null)
})()