How to reproduce given viewport maintaining aspect ratio?
I have 3D scene rendered in a viewport that fits to the window size. So the viewport (camera) aspect ratio depends on window size. On top of the viewport I draw a frame that has aspect ratio 16:9 and it also fits the viewport and it's centered vertically and horizontally inside the viewport. The purpose of the frame is to show which part of the viewport will be rendered in 16:9 aspect ratio. See screen below:
Now I want to render same 3D scene in the viewport 16:9 that will contain exactly same "pixels" that are contained in orange frame on the screen above. So inside another window I create a viewport that has 16:9 aspect ratio, set the object and camera positions to exactlty same position/orientation as on the previous scene. This time both viewport and camera aspect ratios are 16:9. However pixels rendered inside viewport differ from pixels from orange frame on the first screen (the sticks should be "cut" in half):
I guess I missed some calculations that have to be done to reproduce exact viewport from orange frame but I can't figure out which. The data I have from first viewport:
- viewport width/height/aspectRatio
- orange frame width/height and position
- scene object position
- camera position/orientation/aspectRatio
The data I have from second viewport:
- viewport width/height (aspect ratio = 16:9)
- scene object position (same as in first viewport)
- camera position (same as in first viewport)
What I need is to reproduce exact amount of first viewport (inside orange frame) in the second viewport.
math three.js 3d
add a comment |
I have 3D scene rendered in a viewport that fits to the window size. So the viewport (camera) aspect ratio depends on window size. On top of the viewport I draw a frame that has aspect ratio 16:9 and it also fits the viewport and it's centered vertically and horizontally inside the viewport. The purpose of the frame is to show which part of the viewport will be rendered in 16:9 aspect ratio. See screen below:
Now I want to render same 3D scene in the viewport 16:9 that will contain exactly same "pixels" that are contained in orange frame on the screen above. So inside another window I create a viewport that has 16:9 aspect ratio, set the object and camera positions to exactlty same position/orientation as on the previous scene. This time both viewport and camera aspect ratios are 16:9. However pixels rendered inside viewport differ from pixels from orange frame on the first screen (the sticks should be "cut" in half):
I guess I missed some calculations that have to be done to reproduce exact viewport from orange frame but I can't figure out which. The data I have from first viewport:
- viewport width/height/aspectRatio
- orange frame width/height and position
- scene object position
- camera position/orientation/aspectRatio
The data I have from second viewport:
- viewport width/height (aspect ratio = 16:9)
- scene object position (same as in first viewport)
- camera position (same as in first viewport)
What I need is to reproduce exact amount of first viewport (inside orange frame) in the second viewport.
math three.js 3d
add a comment |
I have 3D scene rendered in a viewport that fits to the window size. So the viewport (camera) aspect ratio depends on window size. On top of the viewport I draw a frame that has aspect ratio 16:9 and it also fits the viewport and it's centered vertically and horizontally inside the viewport. The purpose of the frame is to show which part of the viewport will be rendered in 16:9 aspect ratio. See screen below:
Now I want to render same 3D scene in the viewport 16:9 that will contain exactly same "pixels" that are contained in orange frame on the screen above. So inside another window I create a viewport that has 16:9 aspect ratio, set the object and camera positions to exactlty same position/orientation as on the previous scene. This time both viewport and camera aspect ratios are 16:9. However pixels rendered inside viewport differ from pixels from orange frame on the first screen (the sticks should be "cut" in half):
I guess I missed some calculations that have to be done to reproduce exact viewport from orange frame but I can't figure out which. The data I have from first viewport:
- viewport width/height/aspectRatio
- orange frame width/height and position
- scene object position
- camera position/orientation/aspectRatio
The data I have from second viewport:
- viewport width/height (aspect ratio = 16:9)
- scene object position (same as in first viewport)
- camera position (same as in first viewport)
What I need is to reproduce exact amount of first viewport (inside orange frame) in the second viewport.
math three.js 3d
I have 3D scene rendered in a viewport that fits to the window size. So the viewport (camera) aspect ratio depends on window size. On top of the viewport I draw a frame that has aspect ratio 16:9 and it also fits the viewport and it's centered vertically and horizontally inside the viewport. The purpose of the frame is to show which part of the viewport will be rendered in 16:9 aspect ratio. See screen below:
Now I want to render same 3D scene in the viewport 16:9 that will contain exactly same "pixels" that are contained in orange frame on the screen above. So inside another window I create a viewport that has 16:9 aspect ratio, set the object and camera positions to exactlty same position/orientation as on the previous scene. This time both viewport and camera aspect ratios are 16:9. However pixels rendered inside viewport differ from pixels from orange frame on the first screen (the sticks should be "cut" in half):
I guess I missed some calculations that have to be done to reproduce exact viewport from orange frame but I can't figure out which. The data I have from first viewport:
- viewport width/height/aspectRatio
- orange frame width/height and position
- scene object position
- camera position/orientation/aspectRatio
The data I have from second viewport:
- viewport width/height (aspect ratio = 16:9)
- scene object position (same as in first viewport)
- camera position (same as in first viewport)
What I need is to reproduce exact amount of first viewport (inside orange frame) in the second viewport.
math three.js 3d
math three.js 3d
edited Nov 20 '18 at 14:50
user606521
asked Nov 20 '18 at 14:23
user606521user606521
4,521960137
4,521960137
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Code in PerspectiveCamera.js suggests that the fov
(field of view) in Three.js gives the angle in the vertical direction.
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom
Say you go with the default of 50°. Then that tan there will be tan(25°) except for JavaScript you actually need to compute that in radians. If you want the width to be 50° instead, you want fov = 2 * atan(tan(50°/2) * 9/16)
except you need to convert between degrees and radians. The idea is that you take the tangens, apply the aspect ratio to map it from width (where you want to measure it) to height (where the class expects it), then reverse the tangens computation.
But perhaps you don't want to specify the angle for the width. Perhaps you want the original scene at a vertical fov of 50°, but still want the adjusted cene to be the 16:9 clipped version of that. In this case you can multiply with the ratio of ratios. So if your original image was 4:3 and the new image is 16:9, multiply by (9/16)/(3/4) also known as (9*4)/(16*3) also known as 3/4 and you convert from original height to width to new height angle in one go.
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395092%2fhow-to-reproduce-given-viewport-maintaining-aspect-ratio%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Code in PerspectiveCamera.js suggests that the fov
(field of view) in Three.js gives the angle in the vertical direction.
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom
Say you go with the default of 50°. Then that tan there will be tan(25°) except for JavaScript you actually need to compute that in radians. If you want the width to be 50° instead, you want fov = 2 * atan(tan(50°/2) * 9/16)
except you need to convert between degrees and radians. The idea is that you take the tangens, apply the aspect ratio to map it from width (where you want to measure it) to height (where the class expects it), then reverse the tangens computation.
But perhaps you don't want to specify the angle for the width. Perhaps you want the original scene at a vertical fov of 50°, but still want the adjusted cene to be the 16:9 clipped version of that. In this case you can multiply with the ratio of ratios. So if your original image was 4:3 and the new image is 16:9, multiply by (9/16)/(3/4) also known as (9*4)/(16*3) also known as 3/4 and you convert from original height to width to new height angle in one go.
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
add a comment |
Code in PerspectiveCamera.js suggests that the fov
(field of view) in Three.js gives the angle in the vertical direction.
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom
Say you go with the default of 50°. Then that tan there will be tan(25°) except for JavaScript you actually need to compute that in radians. If you want the width to be 50° instead, you want fov = 2 * atan(tan(50°/2) * 9/16)
except you need to convert between degrees and radians. The idea is that you take the tangens, apply the aspect ratio to map it from width (where you want to measure it) to height (where the class expects it), then reverse the tangens computation.
But perhaps you don't want to specify the angle for the width. Perhaps you want the original scene at a vertical fov of 50°, but still want the adjusted cene to be the 16:9 clipped version of that. In this case you can multiply with the ratio of ratios. So if your original image was 4:3 and the new image is 16:9, multiply by (9/16)/(3/4) also known as (9*4)/(16*3) also known as 3/4 and you convert from original height to width to new height angle in one go.
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
add a comment |
Code in PerspectiveCamera.js suggests that the fov
(field of view) in Three.js gives the angle in the vertical direction.
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom
Say you go with the default of 50°. Then that tan there will be tan(25°) except for JavaScript you actually need to compute that in radians. If you want the width to be 50° instead, you want fov = 2 * atan(tan(50°/2) * 9/16)
except you need to convert between degrees and radians. The idea is that you take the tangens, apply the aspect ratio to map it from width (where you want to measure it) to height (where the class expects it), then reverse the tangens computation.
But perhaps you don't want to specify the angle for the width. Perhaps you want the original scene at a vertical fov of 50°, but still want the adjusted cene to be the 16:9 clipped version of that. In this case you can multiply with the ratio of ratios. So if your original image was 4:3 and the new image is 16:9, multiply by (9/16)/(3/4) also known as (9*4)/(16*3) also known as 3/4 and you convert from original height to width to new height angle in one go.
Code in PerspectiveCamera.js suggests that the fov
(field of view) in Three.js gives the angle in the vertical direction.
top = near * Math.tan( _Math.DEG2RAD * 0.5 * this.fov ) / this.zoom
Say you go with the default of 50°. Then that tan there will be tan(25°) except for JavaScript you actually need to compute that in radians. If you want the width to be 50° instead, you want fov = 2 * atan(tan(50°/2) * 9/16)
except you need to convert between degrees and radians. The idea is that you take the tangens, apply the aspect ratio to map it from width (where you want to measure it) to height (where the class expects it), then reverse the tangens computation.
But perhaps you don't want to specify the angle for the width. Perhaps you want the original scene at a vertical fov of 50°, but still want the adjusted cene to be the 16:9 clipped version of that. In this case you can multiply with the ratio of ratios. So if your original image was 4:3 and the new image is 16:9, multiply by (9/16)/(3/4) also known as (9*4)/(16*3) also known as 3/4 and you convert from original height to width to new height angle in one go.
answered Nov 20 '18 at 21:10
MvGMvG
39.3k994197
39.3k994197
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
add a comment |
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hey, thanks, I ended up with slightly different solution that seems to work. In the first viewport I calculate something I call "zScale": blueFrameHeight / orangeFrameHeight. Then in the second viewport after positioning camera I set camera.scale.z = zScale and it just works :). zScale is basically ratio between blue and orange viewport heights. Can you confirm that this works same as you described? I don't know why I need only ratio between heights but it seems to just work for all my cases...
– user606521
Nov 21 '18 at 12:43
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
Hmm, my code does not work in some scenarios... So I want to try what you wrote (ratio of ratios). You said I have to multiply by 3/4. But what I need to multiply exactly?
– user606521
Nov 22 '18 at 9:28
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53395092%2fhow-to-reproduce-given-viewport-maintaining-aspect-ratio%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown