javascript Threejs定位3D对象

llew8vvj  于 2024-01-05  发布在  Java
关注(0)|答案(1)|浏览(145)

我有一个3D场景,有三个js,看起来像这样:

但我想把它改成这样:



颜色,星星和纹理并不重要,我想要的是地球的形状从底部显示为半球,我尝试改变地球的y位置,但它也改变了它的外观,因为透视相机
这是我的代码,它是一个NextJs组件,但我相信代码不会有什么不同:

  1. 'use client'
  2. import { useEffect, useRef } from 'react'
  3. import * as Three from 'three'
  4. const Earth3D = () => {
  5. const canvas = useRef<HTMLCanvasElement>(null)
  6. useEffect(() => {
  7. let mouse = { x: 0, y: 0 }
  8. let target = { x: 0, y: 0 }
  9. let requestAnimationFrame: number
  10. /**
  11. * Three js
  12. */
  13. const scene = new Three.Scene()
  14. const clock = new Three.Clock()
  15. const textureLoader = new Three.TextureLoader()
  16. /**
  17. * earth
  18. */
  19. const earthObject = new Three.SphereGeometry(0.65, 64, 64)
  20. const earthTexture = textureLoader.load('/images/texture/earth-texture.jpg')
  21. const earthMaterial = new Three.MeshStandardMaterial({ map: earthTexture })
  22. const earth = new Three.Mesh(earthObject, earthMaterial)
  23. scene.add(earth)
  24. /**
  25. * light
  26. */
  27. const whiteLight = new Three.PointLight(0xffffff, 8)
  28. whiteLight.position.set(-1, 0.5, 2)
  29. scene.add(whiteLight)
  30. /**
  31. * camera
  32. */
  33. const camera = new Three.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
  34. camera.position.set(0, 0, 10)
  35. scene.add(camera)
  36. /**
  37. * renderer
  38. */
  39. const renderer = new Three.WebGLRenderer({ canvas: canvas.current as HTMLCanvasElement, alpha: true })
  40. renderer.setSize(window.innerWidth, window.innerHeight)
  41. renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  42. /**
  43. * window resize handler
  44. */
  45. const resizeHandler = () => {
  46. // Update camera
  47. camera.aspect = window.innerWidth / window.innerHeight
  48. camera.updateProjectionMatrix()
  49. // Update renderer
  50. renderer.setSize(window.innerWidth, window.innerHeight)
  51. renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
  52. }
  53. window.addEventListener('resize', resizeHandler)
  54. /**
  55. * window mouse move handler
  56. */
  57. const mousemoveHandler = (e: MouseEvent) => {
  58. mouse.x = e.clientX - window.innerWidth / 2
  59. mouse.y = e.clientY - window.innerHeight / 2
  60. }
  61. window.addEventListener('mousemove', mousemoveHandler)
  62. /**
  63. * animating
  64. */
  65. const tick = () => {
  66. // camera positioning
  67. if (window.innerWidth < 500) camera.position.setZ(3)
  68. else camera.position.setZ(2)
  69. target.x = mouse.x * 0.001
  70. target.y = mouse.y * 0.001
  71. // Update objects
  72. earth.rotation.y = 0.5 * clock.getElapsedTime()
  73. // update object by mouse move
  74. earth.rotation.x += 0.025 * (target.y - earth.rotation.x)
  75. earth.rotation.y += 0.5 * (target.x - earth.rotation.y)
  76. // Render
  77. renderer.render(scene, camera)
  78. requestAnimationFrame = window.requestAnimationFrame(tick)
  79. }
  80. tick()
  81. // removing the window functions
  82. return () => {
  83. window.removeEventListener('resize', resizeHandler)
  84. window.removeEventListener('mousemove', mousemoveHandler)
  85. window.cancelAnimationFrame(requestAnimationFrame)
  86. }
  87. // eslint-disable-next-line react-hooks/exhaustive-deps
  88. }, [])
  89. return (
  90. <div>
  91. <canvas ref={canvas} className="relative w-screen h-screen outline-0" />
  92. </div>
  93. )
  94. }
  95. export default Earth3D

字符串
这是一个code sandbox

guykilcj

guykilcj1#

尝试使用y-axis并调整FOV

  1. const camera = new Three.PerspectiveCamera(
  2. 25,
  3. window.innerWidth / window.innerHeight,
  4. 0.1,
  5. 100,
  6. );
  7. camera.position.set(0, 0.6, 10);
  8. scene.add(camera);

字符串
但如果出于某种原因你不想操纵相机,你可以玩的位置(如你所提到的),但要使地球看起来像在图片中的一个,没有变形,你还需要使用scale。当这两个参数相结合,你会达到预期的效果。

  1. const earthObject = new Three.SphereGeometry(0.65, 64, 64);
  2. const earthTexture = textureLoader.load("/earth-texture.jpg");
  3. const earthMaterial = new Three.MeshStandardMaterial({ map: earthTexture });
  4. const earth = new Three.Mesh(earthObject, earthMaterial);
  5. scene.add(earth);
  6. earth.position.set(0, -1.2, 0);
  7. earth.scale.set(2, 1.6, 2);


https://codesandbox.io/p/devbox/three-forked-8qlrwc?file=%2Fcomponents%2FEarth3D.tsx%3A30%2C32

展开查看全部

相关问题