Can't override function of three.js classes within my extended class

Hi, I encountered an issue. Maybe due to a lack of some important knowledge about JS.

I’m using Typescript and trying to extend the THREE.WebGLRenderer.

So I’m doing it with the extends keyword pattern like so:

class NewRenderer extends THREE.WebGLRenderer {
	constructor() {
		super();
	}

	render(scene, camera) {
                console.log("Do my stuff");
		super.render(scene, camera);
	}

	render2(scene, camera) {
		console.log("Do my stuff");
		super.render(scene, camera);
	}
}

However, when I new NewRenderer().render() it’s seemed didn’t call my NewRenderer’s render function. But skipped to THREE.WebGLRenderer’s render function.

Even when I changed the function name to avoid the name collision (render2).
The function has been invoked but I still can’t use super.render to call THREE.WebGLRenderer’s render function.

Here is a little sample.

Can someone guide me on what am I missing here? :disappointed_relieved:

It’s because THREE.WebGLRenderer is not an ES6 class or a function implemented in such a way that you can extend from it and expect it to behave like one.

If you look at the source code, you can see that the “methods” are implemented like this.render = function (...) {... in its constructor. Had they been implemented like WebGLRenderer.prototype.render = function (...) {..., then it would have behaved like you expect.

2 Likes

In this example, render is overridden, but of course you can no longer render the scene since it is overridden with a function than only logs text to to the console.

example : Threejs Boilerplate - JSFiddle - Code Playground

image

2 Likes

here - based on what was explained by @adamringhede

3 Likes

Aw nice, This is hacky but worked.

Thanks all you guys.

So the function is treated as property of the object instead of a function in prototype.

I’m curious tho why three.js choose to implement this way rather than using the prototype.

Maybe to avoid the requirement to bind the function like this.render.bind(this);?

Or it’s the performance reason?