Effect:

Full source code:

<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>The edges of the three.js model are highlighted</title>
  <style>
    body {
      margin: 0;
      overflow: hidden
    }
  </style>
  <script src="./js/three.js"></script>
  <script src="./js/OrbitControls.js"></script>
  <script src="./js/CSS2DRenderer.js"></script>
  <script src="./js/loaders/DDSLoader.js"></script>
  <script src="./js/loaders/MTLLoader.js"></script>
  <script src="./js/loaders/OBJLoader.js"></script>
  <! -- Activate the glow effect of an object -->
  <script src="./js/shaders/CopyShader.js"></script>
  <script src="./js/postprocessing/EffectComposer.js"></script>
  <script src="./js/postprocessing/RenderPass.js"></script>
  <script src="./js/shaders/FXAAShader.js"></script>
  <script src="./js/postprocessing/OutlinePass.js"></script>
  <script src="./js/postprocessing/ShaderPass.js"></script>

</head>

<body>
  <script>
    let camera, scene, renderer, controls
    let composer, effectFXAA, outlinePass, renderPass
    let selectedObjects = []

    const raycaster = new THREE.Raycaster()
    const mouse = new THREE.Vector2()

    Init()

    // Initialize method
    function Init() {
      // Initialize the renderer
      InitRenderer()
      // Initialize the scene
      InitScene()
      // Initialize the camera
      InitCamera()
      // Initialize the light source
      InitLights()
      // Initialize the helper
      InitHelper()
      // Set the controller
      setControl()
      // Initialize the data
      InitData()
      / / selector
      initSelection()
      // Perform rendering
      render()

      renderer.domElement.addEventListener('pointermove', onPointerMove.bind(this))}// Initialize data, load 3D objects, events, etc
    function InitData() {
      // Load OBJ model and MTL material
      const onProgress = function (xhr) {
        if (xhr.lengthComputable) {
          const percentComplete = xhr.loaded / xhr.total * 100
          console.log(Math.round(percentComplete, 2) + '% downloaded')}}const onError = function () {}

      const manager = new THREE.LoadingManager()
      manager.addHandler(/\.dds$/i.new THREE.DDSLoader())

      new THREE.MTLLoader(manager)
        .setPath('models/server_v2_console/')
        .load('ServerV2+console.mtl'.function (materials) {

          materials.preload()

          new THREE.OBJLoader(manager)
            .setMaterials(materials)
            .setPath('models/server_v2_console/')
            .load('ServerV2+console.obj'.function (object) {
              object.position.y = 0
              scene.add(object)
            }, onProgress, onError)
        })

    }

    / / the renderer
    function InitRenderer() {
      // Create renderer
      renderer = new THREE.WebGLRenderer()
      // Set the render area size
      renderer.setSize(window.innerWidth, window.innerHeight)
      // Set the background color
      // renderer.setClearColor(0xb9d3ff, 1)
      / / insert the canvas
      document.body.appendChild(renderer.domElement)
    }

    / / camera
    function InitCamera() {
      // Camera Settings
      camera = new THREE.PerspectiveCamera(70.window.innerWidth / window.innerHeight, 1.10000)
      camera.position.set(10.10.10)
      scene.add(camera)
      // scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000)
    }

    / / the scene
    function InitScene() {
      // Create Scene
      scene = new THREE.Scene()

      // Set the background color
      scene.background = new THREE.Color(0xf0f0f0)}/ / auxiliary device
    function InitHelper() {
      // Display the coordinate system
      let axes = new THREE.AxisHelper(300)
      scene.add(axes)

      // Secondary grid
      const helper = new THREE.GridHelper(2000.100)
      helper.position.y = -199
      helper.material.opacity = 0.25
      helper.material.transparent = true
      scene.add(helper)
    }

    / / light
    function InitLights() {
      // Light source Settings
      const ambientLight = new THREE.AmbientLight(0xcccccc.0.4)
      scene.add(ambientLight)

      const pointLight = new THREE.PointLight(0x333333)
      camera.add(pointLight)
    }

    / / controller
    function setControl() {
      controls = new THREE.OrbitControls(camera, renderer.domElement) // Create a control object
      // requestAnimationFrame(render) has been passed; The render function is executed periodically; there is no need to execute the render function by listening for mouse events
      // controls.addEventListener('change', render)
    }

    // Perform render operations, specifying the scene and camera as parameters
    function render() {
      Animate()
      
      if (composer) {
        composer.render()
      }
    }
    
    // call frame by frame
    function Animate() {
      renderer.render(scene, camera) // Perform render operations
      controls.update()
      requestAnimationFrame(render)
    }

    // Cursor move
    function onPointerMove(event) {
      if (event.isPrimary === false) return
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1
      mouse.y = -(event.clientY / window.innerHeight) * 2 + 1
      checkIntersection()
    }

    // Object selection
    function checkIntersection() {
      raycaster.setFromCamera(mouse, camera)
      const intersects = raycaster.intersectObject(scene, true)
      if (intersects.length > 0) {
        const selectedObject = intersects[0].object
        addSelectedObject(selectedObject)
        outlinePass.selectedObjects = selectedObjects
      } else {
        // outlinePass.selectedObjects = []}}// Highlight the stroke
    function initSelection() {
      // Select the effects
      composer = new THREE.EffectComposer(renderer)
      renderPass = new THREE.RenderPass(scene, camera)
      composer.addPass(renderPass)
      outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera)
      outlinePass.visibleEdgeColor.set('orange') // The surrounding line color
      composer.addPass(outlinePass)
      effectFXAA = new THREE.ShaderPass(THREE.FXAAShader)
      effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight)
      composer.addPass(effectFXAA)
    }

    / / selected
    function addSelectedObject(object) {
      selectedObjects = []
      selectedObjects.push(object)
    }
  </script>
</body>

</html>
Copy the code