Поворот камеры вокруг оси X с использованием React Three Fiber

Вопрос или проблема

Я просто хочу установить угол обзора своей камеры X, чтобы увидеть свою сцену сверху.

Вот мой исходный код:

          <PerspectiveCamera
            makeDefault
            rotation={[0, 4.7, 0]}
            position={[-20, 7, 0]}
            fov={60}
            near={1}
            far={100}
          />
          <PerspectiveCamera
            ref={cameraRef}
            rotation={[0, 4.7, 0]}
            position={[-20, 7, 0]}
            fov={50}
            near={1}
            far={100}
          />

вставьте описание изображения здесь

Я изменяю значение вращения по оси x, но, похоже, это влияет на вращение по оси y…

      <PerspectiveCamera
        makeDefault
        rotation={[0, 4.7, 0]}
        position={[-20, 7, 0]}
        fov={60}
        near={1}
        far={100}
      />
      <PerspectiveCamera
        ref={cameraRef}
        rotation={[1, 4.7, 0]}  // ЗДЕСЬ Я ИЗМЕНИЛ !
        position={[-20, 7, 0]}
        fov={50}
        near={1}
        far={100}
      />

Если я изменю вращение по оси x, вот результат… Странно?

вставьте описание изображения здесь

Я хотел бы установить камеру так, чтобы она смотрела сверху вниз, что-то вроде этого:

вставьте описание изображения здесь

Если я просто изменяю вращение по оси x, то результат – это то, что я ищу для этого вращения по x:

          <PerspectiveCamera
        makeDefault 
        rotation={[0, 4.7, 0]}
        position={[-20, 7, 0]} 
        fov={60} 
        near={1}
        far={100}
      />
      <PerspectiveCamera
        ref={cameraRef} 
        rotation={[-0.5, 0, 0]}
        position={[-20, 7, 0]} 
        fov={50} 
        near={1}
        far={100}
      />

вставьте описание изображения здесь

Спасибо за вашу помощь.

Вот полный код:

import { Canvas } from '@react-three/fiber';
import React, { Suspense, useRef } from 'react';
import SoccerField from '../models/SoccerField.jsx';
import SoccerBall from '../models/SoccerBall.jsx';
import {
CameraControls,
MeshReflectorMaterial,
PerspectiveCamera,
useHelper
} from '@react-three/drei';
import { degToRad } from 'maath/misc';
import Trophy from '../models/Trophy.jsx';
import SoccerStadium from '../models/SoccerStadium.jsx';
import { AxesHelper, CameraHelper } from 'three';

const SoccerScene = () => {
const controls = useRef();
const directionalLightRef = useRef();
console.log(directionalLightRef);

const cameraRef = useRef();
console.log(cameraRef);
return (
<section className="w-full h-screen relative bg-[#dfd6c6]">
  <Canvas
    className={`w-full h-screen bg-transparent`}
    shadows
  >
    {cameraRef.current && <primitive object={new 
CameraHelper(cameraRef.current)} />}

    <Suspense fallback={null}>
      <primitive object={new AxesHelper(5)} />

      <directionalLight
        ref={directionalLightRef}
        position={[60, 100, 100]}
        rotation={[0, 0, 0]}
        intensity={2}
        castShadow
        shadow-mapSize-width={4096 * 2} // Увеличивает разрешение тени
        shadow-mapSize-height={4096 * 2} // Увеличивает разрешение тени
        shadow-camera-left={-50} // Увеличивает ширину камеры shadows
        shadow-camera-right={50} // Увеличивает ширину камеры shadows
        shadow-camera-top={10} // Увеличивает высоту камеры shadows
        shadow-camera-bottom={-10}
      />
      {/*{directionalLightRef.current && (*/}
      {/*  <cameraHelper args={[directionalLightRef.current.shadow.camera]} />*/}
      {/*)}*/}
      <ambientLight intensity={0.5} />
      <pointLight
        position={[10, 5, 10]}
        intensity={2}
      />
      <spotLight
        position={[0, 50, 10]}
        angle={0.15}
        penumbra={1}
        intensity={2}
      />
      <hemisphereLight
        skyColor="#b1e1ff"
        groundColor="#000000"
        intensity={1}
      />

      {/* Основная камера с ref */}
      <PerspectiveCamera
        makeDefault // Это установит эту камеру как основную
        rotation={[0, 4.7, 0]}
        position={[-20, 7, 0]} // Позиция камеры для настройки угла
        fov={60} // Вы можете настроить поле зрения, чтобы изменить угол
        near={1}
        far={100}
      />
      <PerspectiveCamera
        ref={cameraRef} // Присоединение ref здесь
        rotation={[0, 4.7, 0]}
        position={[-20, 7, 0]} // Позиция камеры для настройки угла
        fov={50} // Вы можете настроить поле зрения, чтобы изменить угол
        near={1}
        far={100}
      />
      {/* Использование CameraHelper */}
      {cameraRef.current && <primitive object={new CameraHelper(cameraRef.current)} />}

      <CameraControls
        ref={controls}
        // minPolarAngle={degToRad(20)}
        // maxPolarAngle={degToRad(90)}
      />
      <SoccerStadium
        scale={0.1}
        position={[10, 0, 0]}
      />
      <group
        castShadow
        receiveShadow
        position={[-5, 4.3, -3]}
      >
        <Trophy
          scale={3}
          position={[10, 0, 2]}
        />
        <SoccerBall
          position={[5, -1, 2]}
          scale={0.5}
        />
      </group>
    </Suspense>
  </Canvas>
</section>
);
};

export default SoccerScene;

Ответ или решение

Чтобы настроить камеру в React Three Fiber так, чтобы видеть сцену сверху вниз, важно правильно управлять углом поворота камеры. Учитывая ваш код и то, что вы описали, давайте разберемся, как это сделать.

Проблема с поворотом камеры

Как вы заметили, когда вы изменяете значение вращения вдоль оси X, это может влиять на воспринимаемую ориентацию по оси Y. В Three.js (и, соответственно, в React Three Fiber) порядок вращения влияет на конечный результат. Часто рекомендуется устанавливать углы вращения по оси Y перед установкой вращения по оси X.

Шаги по решению

  1. Убедитесь, что вы использовали правильные значения для осей Y и X.
  2. Переместите камеру так, чтобы она была направлена вниз на вашу сцену.

Исправленный код

Согласно вашим требованиям, камеру можно настроить следующим образом:

<PerspectiveCamera
    makeDefault
    rotation={[-Math.PI / 4, 0, 0]} // Угол наклона вниз на 45 градусов
    position={[-20, 20, 0]} // Поднимите камеру выше, чтобы обеспечить более широкий обзор
    fov={60}
    near={1}
    far={100}
/>
<PerspectiveCamera
    ref={cameraRef}
    rotation={[-Math.PI / 4, 0, 0]} // То же самое для второй камеры
    position={[-20, 20, 0]} // Сохраните те же координаты
    fov={50}
    near={1}
    far={100}
/>

Пример полных изменений

Вот полная версия вашего компонента с учетом исправлений:

import { Canvas } from '@react-three/fiber';
import React, { Suspense, useRef } from 'react';
import SoccerField from '../models/SoccerField.jsx';
import SoccerBall from '../models/SoccerBall.jsx';
import {
    CameraControls,
    PerspectiveCamera,
    useHelper
} from '@react-three/drei';
import { AxesHelper, CameraHelper } from 'three';

const SoccerScene = () => {
    const controls = useRef();
    const cameraRef = useRef();

    return (
        <section className="w-full h-screen relative bg-[#dfd6c6]">
            <Canvas className={`w-full h-screen bg-transparent`} shadows>
                {cameraRef.current && <primitive object={new CameraHelper(cameraRef.current)} />}
                <Suspense fallback={null}>
                    <primitive object={new AxesHelper(5)} />

                    <ambientLight intensity={0.5} />
                    <pointLight position={[10, 5, 10]} intensity={2} />
                    <spotLight position={[0, 50, 10]} angle={0.15} penumbra={1} intensity={2} />
                    <hemisphereLight skyColor="#b1e1ff" groundColor="#000000" intensity={1} />

                    <PerspectiveCamera
                        makeDefault
                        rotation={[-Math.PI / 4, 0, 0]} // Поворот на 45 градусов вниз
                        position={[-20, 20, 0]} // Высокая позиция камеры
                        fov={60}
                        near={1}
                        far={100}
                    />
                    <PerspectiveCamera
                        ref={cameraRef}
                        rotation={[-Math.PI / 4, 0, 0]} // То же самое для рефери камеры
                        position={[-20, 20, 0]}
                        fov={50}
                        near={1}
                        far={100}
                    />

                    {cameraRef.current && <primitive object={new CameraHelper(cameraRef.current)} />}

                    <CameraControls ref={controls} />

                    {/* Ваши модели */}
                    <SoccerField />
                    <group castShadow receiveShadow position={[-5, 4.3, -3]}>
                        <SoccerBall position={[5, -1, 2]} scale={0.5} />
                    </group>
                </Suspense>
            </Canvas>
        </section>
    );
};

export default SoccerScene;

Заключение

Теперь у вас должно быть правильное направление камеры, позволяющее видеть сцену сверху вниз. Убедитесь, что параметры положения и вращения камеры корректны для желаемого результата. Попробуйте настроить значение Math.PI / 4, если требуется другой угол обзора.

Оцените материал
Добавить комментарий

Капча загружается...