On hover of a 3d model | highlight

Hi guys, I’m curious to know how can I make my 3d models shine whenever I hover over them. what I want to do is whenever I hover over them models they need to shine so that I can select them and perform operations on them like deleting dragging etc. but as of now I don’t even know how can I make my models shine on hover forget about the other part. But I’m figuring everything out one by one so please let me know how can I achieve my goals.

Based on the other post I’m assuming you’re using R3F - which makes this part actually quite a bit way easier than vanilla threejs.

In R3F you can add pointer / mouse events the same you’d add it in normal React, ex.:

const Box = () => {
  const [shiny, setShiny] = useState(false);
  
  return (
    <mesh
      onPointerEnter={() => setShiny(true)}
      onPointerLeave={() => setShiny(false)}
    >
      <boxGeometry args={[ 1.0, 1.0, 1.0 ]} />
      <meshPhongMaterial color={shiny ? 0xff00ff : 0x880088} />
    </mesh>
  );
};

@mjurczyk, I appreciate your help so much.

Hi @mjurczyk , Is there anyway I can just highlight it’s borders with some light colour? I mean is there any property for doing this with R3F?

I tried it for a simple boxGeometry like this :

import { useRef, useState } from 'react'
import { EdgesGeometry, LineSegments, Color } from 'three'
import { useFrame } from '@react-three/fiber'
import * as THREE from "three"
function Box() {
  const meshRef = useRef()
  const [hovered, setHover] = useState(false)
  const handlePointerOver = (event) => {
    setHover(true)
    const edges = new EdgesGeometry(meshRef.current.geometry)
    const material = new THREE.LineBasicMaterial({ color: new Color('white') })
    const lineSegments = new LineSegments(edges, material)
    meshRef.current.add(lineSegments)
  }

  const handlePointerOut = (event) => {
    setHover(false)
    meshRef.current.remove(meshRef.current.children[meshRef.current.children.length - 1])
  }

  return (
    <mesh
      ref={meshRef}
      onPointerOver={handlePointerOver}
      onPointerOut={handlePointerOut}
    >
      <boxGeometry args={[1, 1, 1]} />
      <meshBasicMaterial color={'hotpink'} />
    </mesh>
  )
}

export default Box

Is this ideal way for glb/gltf files too?

you shouldn’t ever add/remove stuff imperatively, it’s anti react and will only invite trouble. referring to meshRef.current.add, meshRef.current.remove. when you want things to mount/unmount you render them in jsx, or not. edges geometry will also not be the same as a silhouette.

outlines are usually handled by a postprocessing pass.

1 Like