Why don't I need a class call THREE. prefix

Why don’t I need THREE. to write in front of the WebGPURenderer? If I do that, it won’t work anymore.
I only know it with the THREE. prefix

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" typ="text/css" href="resources/css/style.css">
    <title>Vite App</title>
    
  		<script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/",
					"three/nodes": "./jsm/nodes/Nodes.js"
				}
			}
		</script>  
  </head>

  <body>

    <div id="container"></div>

    <script type="module" src="./src/main.js"></script>
  </body>
</html>

The main.js

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { CopyShader } from 'three/examples/jsm/shaders/CopyShader.js';
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
import { ShaderPass } from 'three/examples/jsm/postprocessing/ShaderPass.js';
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';

import WebGPU from 'three/addons/capabilities/WebGPU.js';			
import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';



const canvas = document.createElement('canvas');

//const renderer = new THREE.WebGLRenderer({canvas, antialias: true});
const renderer = new WebGPURenderer({ canvas, antialias: true });

const container = document.getElementById('container');
renderer.setSize(container.clientWidth, container.clientHeight);
container.appendChild( renderer.domElement );
const aspect = container.clientWidth / container.clientHeight;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
camera.position.z = 5;

const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

function animate() {
	requestAnimationFrame(animate);
	cube.rotation.x += 0.01;
	cube.rotation.y += 0.01;
	renderer.render(scene, camera);
}

animate();

It’s a purely subjective thing but I find it with THREE. very good. So you know immediately where it belongs. I’m glad it works but I don’t understand why I have to omit the prefix to make it work.

THREE isn’t really a class or prefix, it’s just a regular (although read-only) variable you’re creating by doing:

import * as THREE from 'three';

So whether or not you need a prefix is unrelated to the library itself - it depends on how you import the modules. Since you’re importing WebGPURenderer from examples subdirectory, it does not belong to THREE. There’s no longer a way to import examples as part of THREE namespace, so the only workaround I could imagine is to manually assign it:

import * as THREE from 'three';
import WebGPU from 'three/addons/capabilities/WebGPU.js';

THREE.WebGPU = WebGPU;
1 Like

The practice was called IIFE, immediately invoked function expression. Something would pollute the global space with a variable THREE = {} and now you would script include files mutating it in specific order. One by one files would add themselves into that object.

It has been abolished, it is gone for good. There are modules and namespaces now. WebGPURenderer isn’t part of the namespace that threejs belongs to.

1 Like

Ah I understand. I’m looking forward to the possibilities that webGPU offers. I had already looked into the webGPU renderer and I was surprised that it accesses all or nearly all core files and is a world of its own. But then I didn’t think about it any further.