Wordpress and Three rendering

Hi Everybody,

Sorry for my awful French-English.

Hi dear admin,
In my entire life, that’s the first time I write on a forum… so sorry in advance : I might not be at the good place to ask my question. I’ll follow this topic and move it if it needs to be done.

I’ve been trying desperately to use the rendering addons with wordpress.
I’ve got no problem using three.js, GLTFLoader and OrbitControls, but when it comes to render, it’s seems to generate a world of problems.

My will is to use a bloom effect on a basic scene with a basic GLTF object (let’s say a ball). I try to adapt the UnrealBloomPass from the documentation. So I charge in the wordpress functions.php all the scripts I need, which are those ones (don’t pay attention to the “true” or “false” in_footer, that’s a problem I’l talk about later :

	wp_enqueue_script( 'three', get_template_directory_uri() . '/js/three.js', array(), true );

wp_enqueue_script( 'OrbitControls', get_template_directory_uri() . '/js/OrbitControls.js', array(), false );

wp_enqueue_script( 'GLTFLoader', get_template_directory_uri() . '/js/GLTFLoader.js', array(), false );

wp_enqueue_script( 'EffectComposer', get_template_directory_uri() . '/js/EffectComposer.js', array(), true );

wp_enqueue_script( 'RenderPass', get_template_directory_uri() . '/js/RenderPass.js', array(), false );

wp_enqueue_script( 'UnrealBloomPass', get_template_directory_uri() . '/js/UnrealBloomPass.js', array(), true );

The fact is : when I do it in a basic HTML index, it works and I manage to render a scene. When I’m on the wordpress project (all JS files loaded in the same order), my js code seems not to reach three.js.

For example, if I write this in the JS containing my three scene : composer = new THREE.EffectComposer(renderer);

Even if EffectComposer is loaded, I get this message composer = Cannot read property ‘getSize’ of undefined.
Or this error : RenderPass is not a function (athough RenderPass is fully loaded.

Then comes my question :
Where to load my JS files in wordpress. It seems to have no importance when it’s about OrbitControls or GLTFLoader, but a lot of importance when it’s about the rendering .js files.
Do I put them all at the bottom of the body ?
My second question is about the “Uncaught TypeError: Cannot read property ‘getSize’ of undefined
at new THREE.EffectComposer (EffectComposer.js?ver=1:18)
at (index):196” error.
How to get rid of that ? Did I miss something so important that makes me noobest that I already am ?
If somebody has a working WP example that would allow me to learn a bit more…

Thanks a lot.

All my version are the last versions from the official three GitHub repository…
Last version of Worpress.
Very last version of myself, I think I will pass out if it does not work tomorow.

1 Like

Thanks for the topic update !

Any chances to provide a live link to your current work of progress? This will make it much easier to investigate your issue.

In terms of the loading order, you could try and set the scripts as dependencies of your three.js file? (https://developer.wordpress.org/reference/functions/wp_enqueue_script/)

I think it would look something like this:

wp_enqueue_script( 'three', get_template_directory_uri() . '/js/three.js', array(
'OrbitControls',
'GLTFLoader',
'EffectComposer',
'RenderPass',
'UnrealBloomPass'
), true );

wp_enqueue_script( 'OrbitControls', get_template_directory_uri() . '/js/OrbitControls.js', array(), false );

wp_enqueue_script( 'GLTFLoader', get_template_directory_uri() . '/js/GLTFLoader.js', array(), false );

wp_enqueue_script( 'EffectComposer', get_template_directory_uri() . '/js/EffectComposer.js', array(), true );

wp_enqueue_script( 'RenderPass', get_template_directory_uri() . '/js/RenderPass.js', array(), false );

wp_enqueue_script( 'UnrealBloomPass', get_template_directory_uri() . '/js/UnrealBloomPass.js', array(), true );

Ok I cannot acces FZ and my server from where I am so I’l try do this tonight ! Thx a lot.

Here it is for the link ! I reproduced it exactly, just aded a random GLTF import. The same thing occurs when I use the basic scene, with the basic cube.
https://vunce.fr/eoperk/

Using this solution, it looks like Three.js is loaded after all its dependencies…so i’ll try to adapt it… but i’m not sure yet it could work.

wp_enqueue_script( ‘three’, get_template_directory_uri() . ‘/js/three.js’, array(
‘OrbitControls’,
‘GLTFLoader’,
‘EffectComposer’,
‘RenderPass’,
‘UnrealBloomPass’
), false );

wp_enqueue_script( 'OrbitControls', get_template_directory_uri() . '/js/OrbitControls.js', array(), false );

wp_enqueue_script( 'GLTFLoader', get_template_directory_uri() . '/js/GLTFLoader.js', array(), false );

wp_enqueue_script( 'EffectComposer', get_template_directory_uri() . '/js/EffectComposer.js', array(), true );

wp_enqueue_script( 'RenderPass', get_template_directory_uri() . '/js/RenderPass.js', array(), false );

wp_enqueue_script( 'UnrealBloomPass', get_template_directory_uri() . '/js/UnrealBloomPass.js', array(), true );

And then in the debugger :

There is actually a programming error in your code. You create the instance of EffectComposer before your create the instance of WebGLRenderer. Hence you pass undefined as a parameter to EffectComposer constructor.

The solution for this issue is to create the composer right after the renderer’s creation in init().

All problems solved using node, cause there were too much dependencies (I’m totally new on this kind of devs, but it appeared it would work fine using the imports & modules). Thanks a lot anyway. If dependencies needed but there’s no node, @Danlong solution works fine = use the functions.php to declare dependencies (and seems, in my case, to be the only functional solution). Thanks !!! :slight_smile:

Hi! I’m actually struggling with a similar problem, as I cannot get wordpress to correctly load threejs (I assume) and I get errors as “: Cannot read property ‘width’ of null”". When you talk about using node, are you referring to node.js? Any clue about how to do it for a correct wordpress and threejs integration?
A lot of thanks in advance, all the best.

Hi ! Yes, I figured it was possible to charge it like you’d do with other javascript files in wordpress.
In a “normal” wordpress theme, you have to go to the functions.php file and then enqueue your .js script (masonry.js for example) like this :

function test_scripts() {
	wp_enqueue_style( 'test-style', get_stylesheet_uri(), array(), _S_VERSION );
	wp_style_add_data( 'test-style', 'rtl', 'replace' );
	wp_enqueue_script( 'test-navigation', get_template_directory_uri() . '/js/navigation.js', array(), _S_VERSION, true );
	wp_enqueue_script( 'splidejs', get_template_directory_uri() . '/js/splide.min.js', array(), _S_VERSION, true );
	wp_enqueue_script( 'app', get_template_directory_uri() . '/js/app.js', array(), _S_VERSION, true );
	wp_enqueue_script( 'masonry', get_template_directory_uri() . '/js/masonry.pckgd.min.js', array(), _S_VERSION, true );
	wp_enqueue_script( 'imagesloaded', get_template_directory_uri() . '/js/imagesloaded.pckgd.min.js', array(), _S_VERSION, true );
	wp_enqueue_script( 'test-skip-link-focus-fix', get_template_directory_uri() . '/js/skip-link-focus-fix.js', array(), _S_VERSION, true );
	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
		wp_enqueue_script( 'comment-reply' );
	}
}
add_action( 'wp_enqueue_scripts', 'test_scripts' ); 

What seems to be more difficult is to charge scripts as modules, because it’s easier to charge the Three dependancies once it has been done.So you can use that hook in the functions.php :

/**
 * Enqueue three scripts and styles and declare as module.
 */
function three_scripts() {

	wp_enqueue_script( 'three-init', get_template_directory_uri() . './js/robot.js', array(), false );
	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
		wp_enqueue_script( 'comment-reply' );
	}
}
add_action( 'wp_enqueue_scripts', 'three_scripts' );

function add_type_attribute($tag, $handle, $src) {
	    // if not your script, do nothing and return original $tag
	    if ( 'three-init' !== $handle ) {
	        return $tag;
	    }
	    // change the script tag by adding type="module" and return it.
	    $tag = '<script type="module" src="' . esc_url( $src ) . '"></script>';
	    return $tag;
}
add_filter('script_loader_tag', 'add_type_attribute' , 10, 3);

And then you can work in the js module file you declared (robot.js here), and call three dependancies like this :

import * as Three from '../node_modules/three/build/three.js';
import { GLTFLoader } from '../node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import { OrbitControls } from '../node_modules/three/examples/jsm/controls/OrbitControls.js';


	let container, renderer, scene, camera, controls;

Now ( and i’m not sure I’ll be able to make this work ) I’ll try to pack the whole js with webpack, cause as far as I’m concerned, I don’t understand if I need to upload node dependencies on my server or if the best practice is to webpack them (In fact I don’t fully understand nodejs, and I don’t know how to compilate the whole thing - but I don’t only have this problem on worpdress).

Also, this is my personal profile. I’d like to get rid of the other one that was here for a professional purpose, and that’s why I did not see your answer.

You can check my open source plugin for wordpress that includes asset uploading and viewing through Three.js: https://github.com/DigiArt-project/wordpressunity3deditor

Demo site: https://heliosvr.mklab.iti.gr/
I used EffectsComposer to highlight selected items in the scene editor:

and
edit-wpunity_scene.php