React drei fix light direction with orbit control

122 Views Asked by At

I have a simple code, and I want to ensure that the light direction always comes from the positive z-axis. Even if I rotate the object, the well-lit side should be facing the front, and the light source should remain stationary.

Here is the codesandbox link. https://codesandbox.io/p/sandbox/three-light-cjmpwf

Here is my code.

import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";

import "./styles.css";

export default function App() {
  return (
    <div className="main">
      <Canvas>
        <directionalLight position={[0, 0, 2]} intensity={10} />
        <OrbitControls enableZoom={false} enablePan={false} />
        <mesh>
          <capsuleGeometry args={[1, 1, 32]} />
          <meshStandardMaterial color={"red"} />
        </mesh>
      </Canvas>
    </div>
  );
}

Currently, when I rotate the capsule, the directional light source also rotates with it. I would like to keep the light direction fixed, always coming from the top, regardless of the object's rotation.

Here's an example image illustrating the issue. How can I modify the code to achieve a fixed light direction while rotating the object?

enter image description here

1

There are 1 best solutions below

0
Łukasz D. Mastalerz On BEST ANSWER

"...Currently, when I rotate the capsule, the directional light source also rotates with it..."

You don't move the capsule or the light, OrbitControls "moves" the camera, or I should say updating position of it. And since the light is stationary, that's why you experience this problem.

import React, { useRef } from "react";
import { Canvas, useFrame, useThree } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import "./styles.css";

function FollowCameraLight() {
  const lightRef = useRef();
  const { camera } = useThree();

  useFrame(() => {
    lightRef.current.position.copy(camera.position);
  });

  return (
    <directionalLight ref={lightRef} intensity={10} />
  );
}

export default function App() {
  return (
    <div className="main">
      <Canvas>
        <FollowCameraLight />
        <OrbitControls enableZoom={false} enablePan={false} />
        <mesh>
          <capsuleGeometry args={[1, 1, 32]} />
          <meshStandardMaterial color={"red"} />
        </mesh>
      </Canvas>
    </div>
  );
}

https://codesandbox.io/p/sandbox/three-light-forked-5ths4p?file=%2Fsrc%2FApp.js%3A33%2C1