main.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import * as THREE from 'three'
  2. import { GLTFLoader, EXRLoader, RGBELoader, OrbitControls, ShaderPass, GammaCorrectionShader } from 'three/examples/jsm/Addons.js'
  3. import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
  4. import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass';
  5. import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass';
  6. import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass';
  7. import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js';
  8. import { init, update, onClick, onKeyPress } from './game.js'
  9. import gsap from 'gsap'
  10. import { MotionPathPlugin } from 'gsap/MotionPathPlugin.js'
  11. import Howler from 'howler'
  12. gsap.registerPlugin(MotionPathPlugin)
  13. Howler.autoUnlock = true
  14. const game = {}
  15. game.entities = []
  16. game.loadingManager = new THREE.LoadingManager()
  17. game.gltfLoader = new GLTFLoader(game.loadingManager)
  18. game.textureLoader = new THREE.TextureLoader(game.loadingManager)
  19. game.exrLoader = new EXRLoader(game.loadingManager)
  20. game.rgbeLoader = new RGBELoader(game.loadingManager)
  21. game.clock = new THREE.Clock()
  22. game.camera = new THREE.PerspectiveCamera(60, 1, 0.1, 256)
  23. game.scene = new THREE.Scene()
  24. game.mousePosition = new THREE.Vector2(0, 0)
  25. game.keyboard = {}
  26. game.lookAtFocus = new THREE.Vector3(0, 0, 0)
  27. function loaded() {
  28. game.renderer = new THREE.WebGLRenderer({
  29. canvas: game.canvas,
  30. antialias: true,
  31. })
  32. game.renderer.outputColorSpace = THREE.SRGBColorSpace
  33. game.renderer.setSize(game.canvas.offsetWidth, game.canvas.offsetHeight)
  34. game.renderer.shadowMap.enabled = true
  35. game.renderer.shadowMap.type = THREE.PCFSoftShadowMap
  36. /******************
  37. * Postprocessing *
  38. ******************/
  39. const renderPass = new RenderPass(game.scene, game.camera)
  40. const bloomPass = new UnrealBloomPass(new THREE.Vector2(game.canvas.offsetWidth, game.canvas.offsetHeight));
  41. bloomPass.threshold = 0.5
  42. bloomPass.strength = 0.25
  43. bloomPass.radius = 0.0
  44. // Highlight
  45. game.outlinePass = new OutlinePass(new THREE.Vector2(game.canvas.offsetWidth, game.canvas.offsetHeight), game.scene, game.camera)
  46. // game.outlinePass.edgeThickness = 1
  47. // game.outlinePass.edgeGlow = 0
  48. game.outlinePass.edgeStrength = 4
  49. game.outlinePass.pulsePeriod = 4
  50. game.outlinePass.visibleEdgeColor = new THREE.Color(1, 1, 1)
  51. game.outlinePass.hiddenEdgeColor = new THREE.Color(1, 1, 1)
  52. const gammaCorrection = new ShaderPass( GammaCorrectionShader )
  53. const outputPass = new OutputPass()
  54. game.effectComposer = new EffectComposer(game.renderer)
  55. game.effectComposer.addPass(renderPass)
  56. game.effectComposer.addPass(game.outlinePass)
  57. game.effectComposer.addPass(bloomPass)
  58. // game.effectComposer.addPass( gammaCorrection )
  59. game.effectComposer.addPass(outputPass)
  60. game.orbitControls = new OrbitControls(game.camera, game.renderer.domElement)
  61. game.orbitControls.enabled = false
  62. onResize()
  63. init(game).then(() => {
  64. document.getElementById("loading").style.display = "none"
  65. game.clock.start()
  66. attachAnimationFrame()
  67. })
  68. }
  69. function onResize() {
  70. game.renderer.setSize(window.innerWidth, window.innerHeight, true)
  71. game.renderer.setPixelRatio(Math.min(2, window.devicePixelRatio))
  72. game.camera.aspect = game.canvas.offsetWidth / game.canvas.offsetHeight
  73. game.camera.updateProjectionMatrix()
  74. }
  75. function renderOneFrame() {
  76. update(game)
  77. game.orbitControls.update()
  78. if (!game.orbitControls.enabled) {
  79. game.camera.lookAt(game.lookAtFocus)
  80. }
  81. game.effectComposer.render()
  82. //game.renderer.render(game.scene, game.camera)
  83. }
  84. function attachAnimationFrame() {
  85. renderOneFrame()
  86. window.requestAnimationFrame(attachAnimationFrame)
  87. }
  88. export default async function main(canvasElement) {
  89. game.canvas = canvasElement
  90. document.addEventListener("DOMContentLoaded", loaded)
  91. window.addEventListener('resize', onResize)
  92. game.canvas.addEventListener('mousemove', event => {
  93. game.mousePosition.x = 2 * (event.clientX / game.canvas.offsetWidth - 0.5)
  94. game.mousePosition.y = -2 * (event.clientY / game.canvas.offsetHeight - 0.5)
  95. })
  96. game.canvas.addEventListener('touchmove', event => {
  97. if (event.touches.length == 1) {
  98. game.mousePosition.x = 2 * (event.touches[0].clientX / game.canvas.offsetWidth - 0.5)
  99. game.mousePosition.y = -2 * (event.touches[0].clientY / game.canvas.offsetHeight - 0.5)
  100. }
  101. })
  102. game.canvas.addEventListener('touchstart', event => {
  103. if (event.touches.length == 1) {
  104. game.mousePosition.x = 2 * (event.touches[0].clientX / game.canvas.offsetWidth - 0.5)
  105. game.mousePosition.y = -2 * (event.touches[0].clientY / game.canvas.offsetHeight - 0.5)
  106. }
  107. })
  108. game.canvas.addEventListener('mousedown', event => {
  109. game.mousePosition.x = 2 * (event.clientX / game.canvas.offsetWidth - 0.5)
  110. game.mousePosition.y = -2 * (event.clientY / game.canvas.offsetHeight - 0.5)
  111. })
  112. game.canvas.addEventListener('click', event => {
  113. onClick()
  114. })
  115. window.addEventListener('keydown', event => {
  116. const lastKeyState = game.keyboard[event.code]
  117. game.keyboard[event.code] = true
  118. if (!lastKeyState) {
  119. onKeyPress(event.code)
  120. }
  121. })
  122. window.addEventListener('keyup', event => {
  123. game.keyboard[event.code] = false
  124. })
  125. }