Trying load gltf model, but see nothing (lights are added, camera is set) (blender) (react + three)

Hello guys!
Trying my first steps in three.js + react. I’ve made a simple application and load simple scene from Blender. But I see nothing. Below my code for index.js. I’ve trying added light source, trying connect camera from gltf file. But nothing so far. Can you help me please?

Repo for this project https://github.com/iamruletik/ruletik-main
Models and sources can be find in this repo.
Thanks so much.

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

class App extends Component {
  componentDidMount() {
     // === THREE.JS CODE START ===

    const width = window.innerWidth;
    const height = window.innerHeight;

    var gltfLoader = new GLTFLoader();
    var scene = new THREE.Scene();
    var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
	var renderer = new THREE.WebGLRenderer();

	const ambientLight = new THREE.HemisphereLight( 0xffffbb, 0x080820, 1 );

	//var controls = new THREE.OrbitControls(camera, renderer.domElement);
    
    
    
	gltfLoader.load( './isometric-ruletik-test.glb', gltf => {
		console.log(gltf);
 		scene.add( gltf.scene );
 		camera = gltf.cameras[ 0 ];
 		scene.add( ambientLight );
	} );


    renderer.setSize( window.innerWidth, window.innerHeight );
    this.mount.appendChild( renderer.domElement );
  
    
    var helper = new THREE.CameraHelper( camera );
	scene.add( helper );

    renderer.setClearColor(0x808080);
    renderer.render(scene,camera);
    
    // === THREE.JS EXAMPLE CODE END ===

  }

 

  render() {
    return (
      <div ref={ref => (this.mount = ref)} />
    )
  }
}

export default App

ReactDOM.render(<App />, document.getElementById('root'))
1 Like

I’ve polished your code a bit so you have proper camera and light settings. Besides, the animation of the sphere should correctly play:

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

class App extends Component {
	componentDidMount() {
		// === THREE.JS CODE START ===

		var mixer;

		var gltfLoader = new GLTFLoader();
		var scene = new THREE.Scene();
		scene.background = new THREE.Color( 0x808080 );

		var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
		camera.position.set( 50, 50, 50 );

		var renderer = new THREE.WebGLRenderer();
		renderer.setPixelRatio( window.devicePixelRatio );
		renderer.setSize( window.innerWidth, window.innerHeight );
		this.mount.appendChild( renderer.domElement );

		var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
		hemiLight.position.set( 0, 20, 0 );
		scene.add( hemiLight );

		var dirLight = new THREE.DirectionalLight( 0xffffff );
		dirLight.position.set( - 3, 10, - 10 );
		scene.add( dirLight );


		gltfLoader.load( './isometric-ruletik-test.glb', gltf => {
			console.log(gltf);
			scene.add( gltf.scene );

			mixer = new THREE.AnimationMixer( gltf.scene );
			mixer.clipAction( gltf.animations[ 0 ] ).play();

		} );


		const helper = new THREE.CameraHelper( camera );
		scene.add( helper );


		const controls = new OrbitControls( camera, renderer.domElement );

		const clock = new THREE.Clock();

		function animate() {

			requestAnimationFrame( animate );

			var delta = clock.getDelta();

			if ( mixer ) mixer.update( delta );

			renderer.render(scene,camera);

		}

		animate();

		// === THREE.JS EXAMPLE CODE END ===

	}

	render() {
		return (
			<div ref={ref => (this.mount = ref)} />
		)
	}
}

export default App

ReactDOM.render(<App />, document.getElementById('root'))

The most important bit is the usage of an animation loop. Besides, you get better visuals by using an perspective camera.

Thanks so much. It really helps!
So, the big mistake it was the need to make animation loop?

I have a few questions:

  1. How to use camera from scene? I need specific orthographical camera. In fact I just need isometric camera. That’s all.
  2. Why code lights instead of using one from file?
  3. What exactly AnimationMixer do? If I don’t use this i will be able to see the scene?
  4. How i can custom controls? If i use isometric camera I need it moving but without rotations.
  5. Any documentation or articles about how the renderer works? What types of lights and materials I can use? How it differs from ray-tracing engines? It’s something like what Eevee does in Blender? Or it’s more similar to games engines? How make good loking render?

When loading a glTF via THREE.GLTFLoader, then you can of course use the camera from the asset. Your original code already looks correct.

Yes, you can load punctual lights via THREE.GLTFLoader but not other (ambient) light types like THREE.AmbientLight or THREE.HemisphereLight. So it really depends on your use case. I’ve just copied over some lighting code and was not aware that the asset already contains light sources.

AnimationMixer just manages the playback of animations. It it not necessary to render the scene.

You have to import one of the existing control classes from the examples directory. The setup really depends on the respective class. Fortunately, there is an example and documentation page for each of the controls: https://threejs.org/examples/?q=controls

I suggest you read one of the three.js books mentioned at the homepage (section Books).