three.js - 对象在屏幕上保持相同大小,无论其与相机的距离如何
问题描述
在 Three.js 中,我有一个远离相机的矩形,如何计算 3D x 和 y 比例以应用于矩形,以便矩形在屏幕上保持相同大小(以像素为单位),无论距离多远从相机它是。
在这里,我制作了一个代码笔,显示矩形远离相机。我希望它在屏幕上保持相同的宽度和高度,无论它在 z 索引中有多远,这意味着矩形的 x 和 y 比例需要根据 z 轴上的距离改变一些比例,这需要根据 z 索引动态发生。
我不知道如何计算这个,我怀疑它的某些函数将以下某些内容作为输入,z 索引偏移,对象的高度或宽度,相机的视野,纵横比,屏幕宽度和高度。最终结果将是物体似乎不会远离相机,即使它正在远离相机。
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();
解决方案
要将立方体保持在您的 codepen 示例中,只需根据距离对其进行缩放。如果它z
不在,屏幕上立方体的大小是1/z
,所以缩放到它的倒数。
带有缩放的渲染函数(相机和立方体之间的初始距离为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);
}
或者通过计算相机和立方体之间的距离:
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);
}
在这里更新了 codepen:https ://codepen.io/mikael-l-nnroth/pen/LYRoaBB
推荐阅读
- c++ - 调用和重载模板函数
- c# - Noop for Fun
? - javascript - 将 Firebase 通知从 Web 应用扩展到移动应用
- css - 这是浏览器错误吗?继承具有背景颜色的变量
- php - 如何让 NGINX 通过 index.php 执行文件夹中的所有 URL
- amazon-web-services - 简单的 npm 站点显示无法访问此站点
- html - div 的内容未与中心对齐
- webpack - Webpack 不会将图像保存在我的“built”文件夹中
- azure-devops - 如何将某些工具预安装到托管代理上?
- ibm-watson - 如何使用 Telegram 应用程序使 Watson Discovery 在 Node-RED 上返回查询结果?