With three and @react-three I have a component with sprite as follow:
export function Point({ position = [0, 0, 0] }: { position?: [number, number, number] }) {
const spriteRef = useRef<THREE.Sprite>(null)
const [hovered, setHovered] = useState(false)
useCursor(hovered)
useFrame(({ camera, clock }) => {
spriteRef.current?.lookAt(camera.position);
const scale = 0.1 + (1 + Math.sin(clock.getElapsedTime() * 5)) * 0.01;
spriteRef.current!.scale.set(scale, scale, scale)
})
const onClick = () => alert('You clicked me!')
return (
<sprite ref={spriteRef} onClick={onClick} onPointerOver={() => setHovered(true)} onPointerOut={() => setHovered(false)} position={position}>
<spriteMaterial attach="material" color={'hotpink'} />
</sprite>
)
}
Now here everything works perfectly, but the sprite is just pink square. I would like to add to it some shader to make it more attractive. So I changed it to:
export function Point({ position = [0, 0, 0] }: { position?: [number, number, number] }) {
const spriteRef = useRef<THREE.Sprite>(null)
const [hovered, setHovered] = useState(false)
useCursor(hovered)
useFrame(({ camera, clock }) => {
spriteRef.current?.lookAt(camera.position);
const scale = 0.1 + (1 + Math.sin(clock.getElapsedTime() * 5)) * 0.01;
spriteRef.current!.scale.set(scale, scale, scale)
})
const onClick = () => alert('You clicked me!')
return (
<sprite ref={spriteRef} onClick={onClick} onPointerOver={() => setHovered(true)} onPointerOut={() => setHovered(false)} position={position}>
{/* <spriteMaterial attach="material" color={'hotpink'} /> */}
<shaderMaterial
attach="material"
transparent={true}
depthWrite={false}
uniforms={{
color: { value: new THREE.Color("hotpink") },
}}
vertexShader={`
varying vec2 vUv;
void main() {
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * mvPosition;
gl_PointSize = 300.0 / -mvPosition.z;
}
`}
fragmentShader={`
uniform vec3 color;
varying vec2 vUv;
void main() {
float dist = length(vUv - vec2(0.5));
float alpha = 1.0 - smoothstep(0.3, 0.5, dist);
gl_FragColor = vec4(color, alpha);
}
`}
/>
</sprite>
)
}
But at this point ononClick, onPointerOver and onPointerOut do not work anymore. Would any one be able to advice me what should I change to have it working not only with sprite material but also with shader material?
drie, but I was always using their helper (the one called shaderMaterial) and that worked just fine for me in the past. I haven't tested it, but that may be an option!