WebIQ - Render a 3D model

Long-established Member

ThreeJS is a powerful 3D graphics library built on Javascript. This example application renders a .OBJ 3D model of a robot arm and allows user to zoom and rotate about the object. The JQuery library is also used to animate info panel show/hide functionality.


A working knowledge of the Javascript language will be useful in understanding this code. An understanding of the WebIQ Designer will also be helpful. Library packaging will not be covered.

Useful Links

Package Code Libraries for WebIQ
ThreeJS - Home Page
TweenJS - Animation
Three JS - Orbit Controls

  1. Import the WebIQ application attached at the bottom of this article.

    WebIQ Import Project.png
  2. Load the project into your designer workspace.

    WebIQ Load Project.png
  3. Navigate to your project dashboard and select Code Manager.

    WebIQ Open Code Manager.png
  4. Select the 3d-canvas local script and press the "Edit Selected Entry" button to open the code editor.

    WebIQ Edit Local Script.png
Code Overview

A brief breakdown of key sections of the script is provided below.

Execution of the module begins on line 160. Event listeners are added to the window object to handle resizing and mousedown events. The onWindowResize function dynamically updates the camera and renderer to maintain aspect ratio. The onDocumentMouseDown function initiates raycasting to check for intersection with clickable objects in the scene. = function (self) {
        // Event listeners
        window.addEventListener( 'resize', onWindowResize );
        window.addEventListener('mousedown', onDocumentMouseDown);

On line 166, the ThreeJS renderer configuration begins and the associated DOM element is added to the web page to display the scene.

        // Add 3D rendering div to document
        var body = document.body;
        let container = document.createElement( 'div' );
		body.appendChild( container );

        // Configure renderer
        renderer = new THREE.WebGLRenderer();
		renderer.setPixelRatio( window.devicePixelRatio );
		renderer.setSize( window.innerWidth, window.innerHeight );
		renderer.shadowMap.enabled = true;
        renderer.shadowMap.type = THREE.PCFSoftShadowMap;
		container.appendChild( renderer.domElement );

On line 182, the scene perspective camera is configured and positioned.

        // Instantiate and configure camera
        camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
		camera.position.z = -1200;

On line 186, the 3D scene is created and the background is configured.

        // Generate Scene
        scene = new THREE.Scene();
        scene.background = new THREE.Color( 0x72645b );
		scene.fog = new THREE.Fog( 0x72645b, 1000, 2000 );

On line 195, the ground plane is configured and added to the scene.

        // Add ground plane to scene
		const plane = new THREE.Mesh(
		new THREE.PlaneGeometry(4000, 4000),
		new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } ));
		plane.rotation.x = - Math.PI / 2;
		plane.position.y = -350;
		scene.add( plane );
		plane.receiveShadow = true;

Lighting is added to the scene on line 205. Ambient light is added using a HemisphereLight and the shadowed light is directional.

        // Add and configure hemispher and directional lighting
        scene.add( new THREE.HemisphereLight( 0x443333, 0x111122,4) );  
		addShadowedLight( 300, 300, -300, 0xFCFF00, 0.8 );

The robot arm .OBJ file is loaded into the scene starting on line 209. The loadModel function descends the object tree and adds all child meshes to the scene. One important note is that the .OBJ resource is packaged with the project in a directory %AppData%\Roaming\webiq-designer\workspace\resources. WebIQ does not currently support the adding of custom files through the designer, so the \resources directory was created in the File Explorer.

        // Load 3D object
        const manager = new THREE.LoadingManager( loadModel );
        const objLoader = new THREE.OBJLoader(manager);
        objLoader.load("resources/Rmk3.obj", loadResourceCallback);

Starting on line 218, the user Orbit Controls are instantiated and configured.

        // Add and configure orbit controls
        const controls = new THREE.OrbitControls( camera, renderer.domElement );
		controls.minDistance = 500;
		controls.maxDistance = 1500;
        controls.enablePan = false;
        controls.maxPolarAngle = 7*Math.PI/16;

Finally, the animation loop is started on line 227. This function updates the renderer, orbit controls, and all animated properties.

        // Run animation loop

The JQuery and Tween libraries will not be covered here, but their associated documentation can be found in the Useful Links section.

Hello, my name is Sam and I am a Software Applications Engineer supporting ctrlX Automation. Feel free to reach out if you have any questions!

Must Read