Three.js Journey - camera:鼠标控制摄像头左右旋转查看物体,求摄像头位置及理解

本文重点为:

  1. 摄像机旋转时X轴Z轴坐标与鼠标X坐标的关系
  2. 摄像机的旋转角度怎么根据鼠标X坐标计算,

本案例设定为: 左右旋转到画布边界时,看到物体背面即可
效果:
在这里插入图片描述

画布的大小单独设为一个对象

// Sizes
const sizes = {
    width: 800,
    height: 600
}

网格对象是一个0.5 X 0.5 X 0.5的正方体,每个面颜色不一致,代码:

const mesh = new THREE.Mesh(
    new THREE.BoxGeometry(0.5, 0.5, 0.5,),
    [
        new THREE.MeshBasicMaterial({ color: 0xff0000 }),
        new THREE.MeshBasicMaterial({ color: 0x00ff00 }),
        new THREE.MeshBasicMaterial({ color: 0x0000ff }),
        new THREE.MeshBasicMaterial({ color: 0xffff00 }),
        new THREE.MeshBasicMaterial({ color: 0x00ffff }),
        new THREE.MeshBasicMaterial({ color: 0xff00ff }),
    ]
)

透视摄像机代码:

const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.01, 1000)
// 摄像头的z轴位置默认先放在1
camera.position.z = 1
camera.lookAt(mesh.position)

鼠标移动时,在画布中的位置, 用cursor变量定义:

/**
 * cursor
 */
const cursor = {
    x: 0,
    y: 0
}
// 鼠标位置的计算不做过多解释,自行百度
window.addEventListener('mousemove', (event) => {
    cursor.x = event.clientX / sizes.width - 0.5
    cursor.y = - (event.clientY / sizes.height - 0.5)
})

在window.requestAnimationFrame()中设置照相机位置,画布重新渲染

const tick = () => {
   // 重点解释这两句
    camera.position.x = Math.sin(cursor.x * Math.PI * 2 )
    camera.position.z = Math.cos(cursor.x * Math.PI * 2 )
    camera.lookAt(mesh.position)
    // Render
    renderer.render(scene, camera)
    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

下面是对于计算摄像头位置以及如何根据鼠标位置计算出旋转角度的理解:

前提已知

1、Π = 180°
2、摄像机左右查看物体,且要看到背面的话,需要同时变化X轴以及Z轴坐标

理解1: 对照鼠标具体的5个坐标, 得到摄像机的位置与旋转角度

鼠标位置变化时,摄像机旋转位置如下:
在这里插入图片描述

由上面图片可以得出关于旋转角度、鼠标X轴位置、相机X轴位置、相机Z轴位置的对应关系表:

旋转角度鼠标X位置相机 x位置相机 z位置
001
90°0.2510
180°0.50-1
-90°-0.25-10
-180°-0.50-1

在这里插入图片描述

可以猜测以下结论:

  1. 相机X位置 = sin(旋转角度)
  2. 相机Z位置 = cos(旋转角度)
理解2: 根据相机距中心的位置为1、已知旋转角度a, 计算出相机x坐标 与 相机z的坐标,如下图:

在这里插入图片描述

由上图, 可以看出:

x = sin(a) * 1
z = cos(a) * 1

最终确定以下结论:

  1. 相机X位置 = sin(旋转角度) * 摄像机距离立方体中心点位置
  2. 相机Z位置 = cos(旋转角度) * 摄像机距离立方体中心点位置
理解3: 鼠标位置与旋转角度的关系

根据理解1中鼠标X轴移动位置与角度的变化:

鼠标X位置旋转角度a
0
0.2590°
0.5180°
-0.25-90°
-0.5-180°

可以得出结论:

旋转角度 = 360° * 鼠标X坐标

最终可以正式解释,为什么摄像机坐标是由那两行代码得出

最终代码如下:

import * as THREE from 'three'
/**
 * cursor
 */
const cursor = {
    x: 0,
    y: 0
}
window.addEventListener('mousemove', (event) => {
    cursor.x = event.clientX / sizes.width - 0.5
    cursor.y = - (event.clientY / sizes.height - 0.5)
})

/**
 * Base
 */
// Canvas
const canvas = document.querySelector('canvas.webgl')

// Sizes
const sizes = {
    width: 800,
    height: 600
}

// Scene
const scene = new THREE.Scene()

// Object
const mesh = new THREE.Mesh(
    new THREE.BoxGeometry(0.5, 0.5, 0.5,),
    [
        new THREE.MeshBasicMaterial({ color: 0xff0000 }),
        new THREE.MeshBasicMaterial({ color: 0x00ff00 }),
        new THREE.MeshBasicMaterial({ color: 0x0000ff }),
        new THREE.MeshBasicMaterial({ color: 0xffff00 }),
        new THREE.MeshBasicMaterial({ color: 0x00ffff }),
        new THREE.MeshBasicMaterial({ color: 0xff00ff }),
    ]
)
scene.add(mesh)

const axesHelper = new THREE.AxesHelper()
scene.add(axesHelper)

// Camera
// 角度 宽高比 near fear
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.01, 1000)
camera.position.z = 1
camera.lookAt(mesh.position)
scene.add(camera)

// Renderer
const renderer = new THREE.WebGLRenderer({
    canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)

const tick = () => {
    camera.position.x = Math.sin(cursor.x * Math.PI * 2 )
    camera.position.z = Math.cos(cursor.x * Math.PI * 2 )
    
    camera.lookAt(mesh.position)

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}
tick()
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值