Jump to content

Engine resizing - choose between width or height to take in account


Recommended Posts

Hello boys and girls,

When window (or canvas) is resized, BJS engine responds by resizing itself. that's great !

For now the height value is taken in account to define the scene size (if canvas width is changed, the scene size stay the same, but if canvas height is changed, scene will be resized, you can try on any scene on the playground, simply by resizing the browser window).

In HTML / CSS responsive pages, defining elements width is frequent, but it's often pretty tough to know or define elements height.

Would it be possible to add something in BJS to define if the engine resizing should take width or height in account to resize the scene ?

EDIT: wow ! what happened to my title ??!! :wacko: Do you know if forum moderators can change a post title ? (we can't at edit time)

Link to comment
Share on other sites

Thank for the piece of info gryff.


DK, in fact I've had a look to the BJS.engine class before posting this thread.

I saw that on resizing everything is updated (canvas bounding width AND height, etc), so I conclued that thoses values are specificaly taken in account in the rendering process.

In scene.render the viewport is calculated from both width and height canvas values, it certainly happens somewhere else, maybe in updateTransfromMatrix but I don't understand this part (I'm not a math guy, at all :P)

I'm trying to understand the whole rendering process, but it's not an easy task, this is the core and most complex part of BJS.

I didn't manage to figure out by myself where this ratio stuff is calculated, that's why I posted this...


Looking at your code is a great learning process for me, but this part is tough... Maybe you could point me somewhere.

Link to comment
Share on other sites

That's what I tought (for "PR") :)


Ok... Matrix.PerspectiveFovLHToRef is really a matter of maths science...


For what I can see, engine.aspectRatio take width and height in account to get the ratio (seems obvious...), but after that, what happened in Babylon.math Matrix.PerspectiveFovLHToRef is pure magic far away from my knowledge...

I remember what a matrix looks like... and that 's all folks... :D

Link to comment
Share on other sites



I think that what you want is to be able to chose whether the fixed field of view (FOV) angle is the horizontal one or the vertical one.

If the vertical FOV is fixed (default setting), then when you resize the canvas height, the camera will appear to "zoom" in and out.

On the contrary, if the horizontal FOV is fixed, then this "zooming" effect will appear when the canvas width is modified.


To switch between the two, I hacked a bit the PerspectiveFovLHToRef function (dear developer, please forgive me, for I have sinned) :

public static PerspectiveFovLHToRef(fov: number, aspect: number, znear: number, zfar: number, result: Matrix, horizontal_fov_fixed?: boolean): void {  var tan = 1.0 / (Math.tan(fov * 0.5));  if(!horizontal_fov_fixed) { result.m[0] = tan / aspect; }   // V FOV fixed (default)  else { result.m[0] = tan; }                                 // H FOV fixed   result.m[1] = result.m[2] = result.m[3] = 0.0;   if(!horizontal_fov_fixed) { result.m[5] = tan; }            // V FOV fixed (default)  else { result.m[5] = tan * aspect; }                        // H FOV fixed  result.m[4] = result.m[6] = result.m[7] = 0.0;  result.m[8] = result.m[9] = 0.0;  result.m[10] = -zfar / (znear - zfar);  result.m[11] = 1.0;  result.m[12] = result.m[13] = result.m[15] = 0.0;  result.m[14] = (znear * zfar) / (znear - zfar);}
I didn't really manage to make an example out of it in the playground, but it works if you add this hack in your (debug version) babylon.js file.


Also I wouldn't really know how to make a PR out of this... I guess it would be necessary to add a parameter in the camera creation, since the project matrix handling is all done behind the scenes.

Link to comment
Share on other sites

The most difficult part will be to find the right property name :)

Maybe something like "FOVFixing" (well... I don't know if in english that really means what it should...) and the two values we can apply to this property could be constant _HORIZONTAL_FOV and _VERTICAL_FOV (with proper getters).

And is it also be possible to not fix any of horizontal or vertical FOV, resulting in resizing the scene on width AND height ? What would be the result of that ?

Link to comment
Share on other sites

Done! https://github.com/BabylonJS/Babylon.js/pull/392


Hope this will do.


As to not fixing any FOV angle, this would be called 'anamorphic' and result in black bars appearing on the sides: http://en.wikipedia.org/wiki/Field_of_view_in_video_games#Field_of_view_scaling_methods

Edit: it would also be possible to not have black bars, but then the projection would be stretched


If the PR is accepted, I'll look into adding this as well, but no promise, as it might be much more complicated.

Link to comment
Share on other sites

Great, thank you !

And also for the valuable piece of info about changing FOV, that's interesting.

You're right, anamorphic resizing seems more complicated. And if bars are added on sides, they should be identical to scene.clearColor (that means they also should take alpha in account...). Certainly not an easy task indeed that anamorphic stuff...

Link to comment
Share on other sites

  • 1 year later...

Necroing this because it seems to be the best source of info for a problem I've had,

I actually want the view to be cut off when the html canvas is scaled in either direction. Like what it does by default when the width is scaled.

You can see the current effect with my demo http://chad-autry.github.io/hex-grid-map-3D/#/demo   If you put your browser into windowed mode and decrease the width, the shapes on screen stay the same size (desired), but decrease the height and their size shrinks (weird).


In particular, I actually wonder why the canvas height/width is impacting this at all. I'd expect the screen resolution aspect ratio (which doesn't change) to be the key part about sizing/scaling the view. My mental model (which doesn't seem to match how babylon.js works) of the role of the canvas size, is that it should be a window behind which the camera sits. 

Link to comment
Share on other sites

The way the canvas resize totally depends on your own HTML/CSS rules. Babylon engine doesn't change the canvas at all (except when you activate the brand new debugLayer).

You can choose how the 3D scene will rescale when the canvas is resized with the engine.fovMode set to FOVMODE_VERTICAL_FIXED (default value) and FOVMODE_HORIZONTAL_FIXED. If you change this value, the engine wil rescale 3D when you change canvas width or height respectively.

Link to comment
Share on other sites

Probably first thing get exactly in mind what I think the best way for it to behave would be.

I think first of all make the size of the scene unrelated to the size of the screen.

One option is to fit the image in the larger direct, crop on the smaller. As a user shrunk the canvas in the larger dimension, more and more of the picture would show in the smaller until the inflection point was hit, and the image began cropping.

The other way things could work is the 'pixel rendering' mentioned on the wikipedia link. Static size independent of screen size, changing width/height crops/uncrops the image.

I have the suspicion such a feature is going to be more like the the Orthographic camera, than it is like the simple change made earlier in the thread.

I'm going to have to look into things more later, when it is higher up on my priority list. It is usable for me right now, just a bit weird. Particularly on mobile. Dropping for now

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...