Skip to content

ViewHelper: Customize the viewport size and fix renderer.autoClear settings #31355

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

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions examples/jsm/helpers/ViewHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ class ViewHelper extends Object3D {
* Constructs a new view helper.
*
* @param {Camera} camera - The camera whose transformation should be visualized.
* @param {HTMLDOMElement} [domElement] - The DOM element that is used to render the view.
* @param {WebGLRenderer|WebGPURenderer} renderer - The renderer that is used to render the view.
*/
constructor( camera, domElement ) {
constructor( camera, renderer ) {

super();

Expand Down Expand Up @@ -144,28 +144,24 @@ class ViewHelper extends Object3D {
/**
* Renders the helper in a separate view in the bottom-right corner
* of the viewport.
*
* @param {WebGLRenderer|WebGPURenderer} renderer - The renderer.
*/
this.render = function ( renderer ) {
this.render = function () {

this.quaternion.copy( camera.quaternion ).invert();
this.updateMatrixWorld();

point.set( 0, 0, 1 );
point.applyQuaternion( camera.quaternion );

//

const x = domElement.offsetWidth - dim;
const y = renderer.isWebGPURenderer ? domElement.offsetHeight - dim : 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's correct to drop this check. WebGPURenderer and WebGLRenderer have different viewport conventions.

Copy link
Author

@ylfq ylfq Jul 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's correct to drop this check. WebGPURenderer and WebGLRenderer have different viewport conventions.

It's really an oversight on my part here, and I think it's good to delegate viewport operations directly to the user

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's correct to drop this check. WebGPURenderer and WebGLRenderer have different viewport conventions.

However, the helper can only get the renderer instance inside the render function, and the cached variables are outside.I think it's better to leave the location settings of the helper to the user, the difference between GL and GPU is harmless

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the difference between GL and GPU is harmless

The view helper won't be proper positioned without this code. So it must be restored. This is not something the user should care about on app level.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the difference between GL and GPU is harmless

The view helper won't be proper positioned without this code. So it must be restored. This is not something the user should care about on app level.

The new commit already takes care of this, using the renderer as an argument to the constructor
The new demo is here https://jsfiddle.net/sdtL5bao/

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new commit already takes care of this, using the renderer as an argument to the constructor The new demo is here https://jsfiddle.net/sdtL5bao/

Please ignore this commit for now, some bugs are not fully fixed


renderer.clearDepth();

renderer.getViewport( viewport );
renderer.setViewport( x, y, dim, dim );
renderer.setViewport( helperViewport.x, helperViewport.y, helperViewport.z, helperViewport.w );

const autoClear = renderer.autoClear;
renderer.autoClear = false;
renderer.render( this, orthoCamera );
renderer.autoClear = autoClear;

renderer.setViewport( viewport.x, viewport.y, viewport.z, viewport.w );

Expand All @@ -177,8 +173,22 @@ class ViewHelper extends Object3D {
const q1 = new Quaternion();
const q2 = new Quaternion();
const viewport = new Vector4();
const helperViewport = new Vector4( renderer.domElement.offsetWidth - dim, renderer.isWebGPURenderer ? renderer.domElement.offsetHeight - dim : 0, dim, dim );
let radius = 0;

/**
* Sets the viewport for the helper.
* @param {number} x viewport x
* @param {number} y viewport y
* @param {number} width viewport width
* @param {number} height viewport height
*/
this.setViewport = function ( x, y, width, height ) {

helperViewport.set( x, y, width, height );

};

/**
* This method should be called when a click or pointer event
* has happened in the app.
Expand All @@ -190,9 +200,9 @@ class ViewHelper extends Object3D {

if ( this.animating === true ) return false;

const rect = domElement.getBoundingClientRect();
const offsetX = rect.left + ( domElement.offsetWidth - dim );
const offsetY = rect.top + ( domElement.offsetHeight - dim );
const rect = renderer.domElement.getBoundingClientRect();
const offsetX = rect.left + ( renderer.domElement.offsetWidth - dim );
const offsetY = rect.top + ( renderer.domElement.offsetHeight - dim );
mouse.x = ( ( event.clientX - offsetX ) / ( rect.right - offsetX ) ) * 2 - 1;
mouse.y = - ( ( event.clientY - offsetY ) / ( rect.bottom - offsetY ) ) * 2 + 1;

Expand Down