Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGLRenderer: onAfterRender() and onBeforeRender() are not called for Object3D and Group. #11306

Closed
SeregPie opened this issue May 9, 2017 · 11 comments · Fixed by #21124
Closed

Comments

@SeregPie
Copy link

SeregPie commented May 9, 2017

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.

@SeregPie SeregPie changed the title [r85] onAfterRender and onBeforeRender are not called on Object3D/Group and Sprite [r85] onAfterRender and onBeforeRender are not called for Object3D/Group and Sprite May 9, 2017
@Mugen87
Copy link
Collaborator

Mugen87 commented May 10, 2017

Just for reference: There is already an existing issue forSprites: #10579.

@mrdoob
Copy link
Owner

mrdoob commented May 11, 2017

Yeah, Sprite is lacking but objects and groups are not really being "rendered" so I guess it makes sense this way.

@mrdoob mrdoob closed this as completed May 11, 2017
@WestLangley
Copy link
Collaborator

#11559

@arcticio
Copy link

arcticio commented Jul 3, 2017

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.

@WestLangley
Copy link
Collaborator

@arcticio @SeregPie See #11638.

@ghost
Copy link

ghost commented Nov 17, 2017

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/

@mrdoob
Copy link
Owner

mrdoob commented Nov 17, 2017

@mojovski if this example works it means onBeforeRender() works, so the issue is somewhere else.

@msimpson
Copy link
Contributor

msimpson commented Mar 5, 2018

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();
    }
  }

@mrdoob mrdoob added this to the rXX milestone Mar 9, 2018
@mrdoob mrdoob reopened this Mar 9, 2018
@mrdoob
Copy link
Owner

mrdoob commented Mar 9, 2018

@fernandojsg I guess this would be a good use case for the component system with a tick()...

@Mugen87 Mugen87 changed the title [r85] onAfterRender and onBeforeRender are not called for Object3D/Group and Sprite WebGLRenderer: onAfterRender() and onBeforeRender() are not called for Object3D and Group. Apr 13, 2020
@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 13, 2020

Just for the record: Sprites support the callbacks in the meanwhile. Renaming the PR's title...

@sjpt
Copy link

sjpt commented May 28, 2020

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants