threepipe
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import {
  2. _testFinish,
  3. IObject3D,
  4. LinearToneMapping,
  5. Mesh,
  6. PerspectiveCamera2,
  7. PlaneGeometry,
  8. PopmotionPlugin,
  9. ProgressivePlugin,
  10. Texture,
  11. ThreeViewer,
  12. ToneMapping,
  13. TonemapPlugin,
  14. UnlitMaterial,
  15. VirtualCamerasPlugin,
  16. } from 'threepipe'
  17. async function init() {
  18. const viewer = new ThreeViewer({
  19. canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
  20. debug: true,
  21. plugins: [new ProgressivePlugin(16)],
  22. })
  23. const virtualCameras = viewer.addPluginSync(VirtualCamerasPlugin)
  24. const popmotion = viewer.addPluginSync(PopmotionPlugin)
  25. await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')
  26. await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
  27. autoCenter: true,
  28. autoScale: true,
  29. })
  30. const aspect = 2
  31. const plane = new Mesh(
  32. new PlaneGeometry(5 * aspect, 5)
  33. .translate(0, 0, -3),
  34. new UnlitMaterial({
  35. color: '#ffffff',
  36. })
  37. )
  38. plane.castShadow = false
  39. plane.receiveShadow = true
  40. viewer.scene.addObject(plane)
  41. const camera = new PerspectiveCamera2('', viewer.canvas, false, 45, aspect)
  42. camera.position.set(0, 0, 5)
  43. camera.target.set(0, 0.25, 0)
  44. camera.userData.autoLookAtTarget = true
  45. camera.near = 1
  46. camera.far = 10
  47. camera.setDirty()
  48. const vCam = virtualCameras.addCamera(camera)
  49. plane.material.map = vCam.target.texture as Texture
  50. popmotion.animate({
  51. from: 0,
  52. to: 1,
  53. repeat: Infinity,
  54. duration: 6000,
  55. onUpdate: (v)=>{
  56. // Set camera position xz in a circle around the target
  57. const angle = v * Math.PI * 2 + Math.PI / 2
  58. const radius = 5
  59. camera.position.set(Math.cos(angle) * radius, 0, Math.sin(angle) * radius)
  60. camera.setDirty()
  61. viewer.setDirty() // since camera is not in the scene
  62. },
  63. })
  64. // We need to disable tonemapping when rendering the virtual camera, otherwise the tonemapping will be applied multiple times.
  65. let lastTonemapping: ToneMapping = LinearToneMapping
  66. const tonemap = viewer.getPlugin(TonemapPlugin)!
  67. virtualCameras.addEventListener('preRenderCamera', ()=>{
  68. lastTonemapping = tonemap.toneMapping
  69. // Comment this and see what happens to the color in the plane
  70. tonemap.toneMapping = LinearToneMapping
  71. })
  72. virtualCameras.addEventListener('postRenderCamera', ()=>{
  73. tonemap.toneMapping = lastTonemapping
  74. })
  75. }
  76. init().then(_testFinish)