Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

In Three.js I have an rectangle which is moving away from the camera, how can I compute a 3D x and y scale to apply to the rectangle such that the rectangle retains its same size on the screen in pixels, no matter how far away from the camera it is.

Here I made a codepen which shows the rectangle moving away from the camera. I would like it to retain its same width and height on the screen no matter how far away it is in the z index, that means the x and y scale of the rectangle needs to vary by some scale dependent on the distance in the z axis, this needs to occur dynamically dependent on the z index.

I don't know how to compute this, I suspect its some function taking as input some of the following, the z index offset, the height or width of the object, the field of view of the camera, the aspect ratio, the screen width and height. The end result would be that the object would not appear to be moving away from the camera, even though it is moving away.

https://codepen.io/philip368320/pen/bGwJPvE

var width = window.innerWidth;
var height = window.innerHeight;

var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);

var scene = new THREE.Scene();

var cubeGeometry = new THREE.CubeGeometry(100, 100, 0.000001);
var cubeMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff });
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
//cube.rotation.y = Math.PI * 45 / 180;
scene.add(cube);


var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 10000);
camera.position.y = 0;
camera.position.z = 400;
camera.lookAt(cube.position);

scene.add(camera);

var skyboxGeometry = new THREE.CubeGeometry(10000, 10000, 10000);
var skyboxMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.BackSide });
var skybox = new THREE.Mesh(skyboxGeometry, skyboxMaterial);

scene.add(skybox);

var pointLight = new THREE.PointLight(0xffffff);
pointLight.position.set(0, 300, 200);

scene.add(pointLight);

var clock = new THREE.Clock();

var n = 0;

function render() {
  requestAnimationFrame(render);
  n = n + clock.getDelta() * 30;
  cube.position.z = -n;
  renderer.render(scene, camera);
}

render();
question from:https://stackoverflow.com/questions/65858400/object-to-retain-same-size-on-screen-regardless-of-its-distance-from-the-camera

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
889 views
Welcome To Ask or Share your Answers For Others

1 Answer

To keep the cube in place in your codepen example, just scale it according to the distance. If it's z away, the size of the cube on the screen is 1/z, so scale to the inverse of that.

The render function with the scaling (initial distance between the camera and the cube is 400):


    function render() {
      requestAnimationFrame(render);
      n = n + clock.getDelta() * 30;
      cube.position.z = -n;
      cube.scale.set((400+n)/400, (400+n)/400, 1);
      renderer.render(scene, camera);
    }

Or by calculating the distance between the camera and the cube:


    function render() {
      requestAnimationFrame(render);
      n = n + clock.getDelta() * 30;
      cube.position.z = -n;
      let distance = camera.position.distanceTo(cube.position);
      cube.scale.set(distance/400, distance/400, 1);
      renderer.render(scene, camera);
    }

Updated codepen here: https://codepen.io/mikael-l-nnroth/pen/LYRoaBB


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...