我有一个3D场景,有三个js,看起来像这样:
但我想把它改成这样:
的
颜色,星星和纹理并不重要,我想要的是地球的形状从底部显示为半球,我尝试改变地球的y位置,但它也改变了它的外观,因为透视相机
这是我的代码,它是一个NextJs组件,但我相信代码不会有什么不同:
'use client'
import { useEffect, useRef } from 'react'
import * as Three from 'three'
const Earth3D = () => {
const canvas = useRef<HTMLCanvasElement>(null)
useEffect(() => {
let mouse = { x: 0, y: 0 }
let target = { x: 0, y: 0 }
let requestAnimationFrame: number
/**
* Three js
*/
const scene = new Three.Scene()
const clock = new Three.Clock()
const textureLoader = new Three.TextureLoader()
/**
* earth
*/
const earthObject = new Three.SphereGeometry(0.65, 64, 64)
const earthTexture = textureLoader.load('/images/texture/earth-texture.jpg')
const earthMaterial = new Three.MeshStandardMaterial({ map: earthTexture })
const earth = new Three.Mesh(earthObject, earthMaterial)
scene.add(earth)
/**
* light
*/
const whiteLight = new Three.PointLight(0xffffff, 8)
whiteLight.position.set(-1, 0.5, 2)
scene.add(whiteLight)
/**
* camera
*/
const camera = new Three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
camera.position.set(0, 0, 10)
scene.add(camera)
/**
* renderer
*/
const renderer = new Three.WebGLRenderer({ canvas: canvas.current as HTMLCanvasElement, alpha: true })
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
/**
* window resize handler
*/
const resizeHandler = () => {
// Update camera
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
// Update renderer
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
}
window.addEventListener('resize', resizeHandler)
/**
* window mouse move handler
*/
const mousemoveHandler = (e: MouseEvent) => {
mouse.x = e.clientX - window.innerWidth / 2
mouse.y = e.clientY - window.innerHeight / 2
}
window.addEventListener('mousemove', mousemoveHandler)
/**
* animating
*/
const tick = () => {
// camera positioning
if (window.innerWidth < 500) camera.position.setZ(3)
else camera.position.setZ(2)
target.x = mouse.x * 0.001
target.y = mouse.y * 0.001
// Update objects
earth.rotation.y = 0.5 * clock.getElapsedTime()
// update object by mouse move
earth.rotation.x += 0.025 * (target.y - earth.rotation.x)
earth.rotation.y += 0.5 * (target.x - earth.rotation.y)
// Render
renderer.render(scene, camera)
requestAnimationFrame = window.requestAnimationFrame(tick)
}
tick()
// removing the window functions
return () => {
window.removeEventListener('resize', resizeHandler)
window.removeEventListener('mousemove', mousemoveHandler)
window.cancelAnimationFrame(requestAnimationFrame)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<div>
<canvas ref={canvas} className="relative w-screen h-screen outline-0" />
</div>
)
}
export default Earth3D
字符串
这是一个code sandbox
1条答案
按热度按时间guykilcj1#
尝试使用
y-axis
并调整FOV
。字符串
但如果出于某种原因你不想操纵相机,你可以玩的位置(如你所提到的),但要使地球看起来像在图片中的一个,没有变形,你还需要使用
scale
。当这两个参数相结合,你会达到预期的效果。型
https://codesandbox.io/p/devbox/three-forked-8qlrwc?file=%2Fcomponents%2FEarth3D.tsx%3A30%2C32