Is it an intentional behavior?
The functions are called on meshes, it is working fine there.
I wanted to redraw images on sprites depending on the distance to the camera, but onBeforeRender is not called. it is fixed now. thank you!
I wanted to make the objects inside a group always facing the camera, but onBeforeRender is not called on the group.
Just for reference: There is already an existing issue forSprites
: #10579.
Yeah, Sprite
is lacking but objects and groups are not really being "rendered" so I guess it makes sense this way.
Say, I have an Object3D with some meshes as children sharing a common material and thus uniforms. The latter are updated each frame. Then it would make sense to have onAfterRender/onBeforeRender on the Object3d to avoid the logic needed to ensure only a single updates of the uniforms.
This approach allows to adapt to e.g. differently implemented maxVertexUniforms by creating meshes as needed.
@arcticio @SeregPie See #11638.
Hmm, in my case the onBeforeRender is not called. Did the issue raised up again?
My code is somewhat like this:
onCenterBeforeRender:function(renderer, scene, camera, geometry, material, group)
{
material.uniforms.viewVector.value = new THREE.Vector3().subVectors( camera.position, this.position);
},
setupSphere:function()
{
...
var sphere = new THREE.Mesh( geometry, material );
sphere.onBeforeRender=this.onCenterBeforeRender;
}
From the the debugger I can see, that the function onCenterBeforeRender is assigned correctly (is also defined).
Do I miss something?
Update: Just tested on this fiddle:
http://jsfiddle.net/0nsuhjgd/1/
@mojovski if this example works it means onBeforeRender()
works, so the issue is somewhere else.
I just ran into this myself. I wanted to contain a large FBX scene in a custom class which inherits from THREE.Group
where onBeforeRender()
is used to animate a material's opacity when a Boolean is true. What I discovered was that onBeforeRender()
is only executed for Mesh
instances of Object3D
. Which is why the example that @mrdoob linked above works correctly. The Reflector
is itself a Mesh
. So while I can certainly execute this method directly for the time being, it would be nice if it worked universally.
For the sake of context, this was my particular implementation:
set skeleton( bool ) {
if ( this._skeleton === !! bool ) return;
this._skeleton = !! bool;
this._skeletonClock.start();
}
get skeleton() {
return this._skeleton;
}
onBeforeRender() {
if ( this._skeletonClock.running ) {
let skeletonProgress = this._skeletonClock.getElapsedTime() / 1;
this._screenMaterial.opacity = this._skeleton ? 1 - skeletonProgress : skeletonProgress;
if ( skeletonProgress >= 1 ) this._skeletonClock.stop();
}
}
@fernandojsg I guess this would be a good use case for the component system with a tick()
...
Just for the record: Sprites support the callbacks in the meanwhile. Renaming the PR's title...
It seems that the thrust of this thread that onBeforeRender for groups is a useful feature, and I don't see any argument put forward against that point of view. The comment 'mrdoob added this to the rXX milestone on 9 Mar 2018' even appears to indicate that it accepted.
If it is still intended behaviour that the onBeforeRender for groups does not work it should be made much clearer in the documentation.
_An optional callback that is executed immediately before the Object3D is rendered. This function is called with the following parameters: renderer, scene, camera, geometry, material, group._
Most helpful comment
Say, I have an Object3D with some meshes as children sharing a common material and thus uniforms. The latter are updated each frame. Then it would make sense to have onAfterRender/onBeforeRender on the Object3d to avoid the logic needed to ensure only a single updates of the uniforms.
This approach allows to adapt to e.g. differently implemented maxVertexUniforms by creating meshes as needed.