Вопрос или проблема
Я просто хочу установить угол обзора своей камеры 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.
Шаги по решению
- Убедитесь, что вы использовали правильные значения для осей Y и X.
- Переместите камеру так, чтобы она была направлена вниз на вашу сцену.
Исправленный код
Согласно вашим требованиям, камеру можно настроить следующим образом:
<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
, если требуется другой угол обзора.