ThreeJS code from https://codepen.io/HunorMarton/pen/JwWLJo
original code
const distance = 500;
const camera = new THREE.OrthographicCamera( window.innerWidth/-2, window.innerWidth/2, window.innerHeight / 2, window.innerHeight / -2, 0.1, 10000 );
camera.rotation.x = 50*Math.PI/180;
camera.rotation.y = 20*Math.PI/180;
camera.rotation.z = 10*Math.PI/180;
const initialCameraPositionY = -Math.tan(camera.rotation.x)*distance;
const initialCameraPositionX = Math.tan(camera.rotation.y)*Math.sqrt(distance**2 + initialCameraPositionY**2);
camera.position.y = initialCameraPositionY;
camera.position.x = initialCameraPositionX;
camera.position.z = distance;
My Codesandbox boring-panini-6s85vw - CodeSandbox
my convert code to
const distance = 500
const newCamera = new OrthographicCamera(size.width / -2, size.width / 2, size.height / 2, size.height / -2, 0.1, 10000)
camera.near = newCamera.near
camera.far = newCamera.far
camera.rotation.x = (50 * Math.PI) / 180
camera.rotation.y = (20 * Math.PI) / 180
camera.rotation.z = (10 * Math.PI) / 180
const initialCameraPositionY = -Math.tan(camera.rotation.x) * distance
const initialCameraPositionX = Math.tan(camera.rotation.y) * Math.sqrt(distance ** 2 + initialCameraPositionY ** 2)
camera.position.y = initialCameraPositionY
camera.position.x = initialCameraPositionX
camera.position.z = distance
this is my first tutorial by can anyone help me about camera angle
drcmda
October 15, 2023, 6:25pm
2
setting the camera has no effect if you also have orbitcontrols, whose only purpose is to set the camera. you have to places of code that pull on the camera.
another thing is that the camera you create isn’t actually used anywhere, you don’t render out with it.
imo it should be relatively easy, use drei/orthocam for instance which can makeDefault so that it’s being used to render. or alternatively render yourself, but why if it’s just this:
const distance = 500
const rotX = (50 * Math.PI) / 180
const rotY = (20 * Math.PI) / 180
const initialCameraPositionY = -Math.tan(rotX) * distance
const initialCameraPositionX = Math.tan(rotY) * Math.sqrt(distance ** 2 + initialCameraPositionY ** 2)
return (
<>
<OrthographicCamera
makeDefault
rotation={[rotX, rotY, (10 * Math.PI) / 180]}
position={[initialCameraPositionX, initialCameraPositionY, distance]}
/>
you don’t need recoil either, you can access that camera now from anywhere, it’s the new default
const cam = useThree(state => state.camera)
useEffect(() => {
camera.doSomething()
}, [camera])
boring-panini-6s85vw by danya0365 using @react-three/drei, @react-three/fiber, @types/three, react, react-dom, react-scripts, recoil, three
1 Like
drcmda
October 15, 2023, 6:37pm
3
you also don’t need to sync the light to the cam, you can just mount it directly into it
<OrthographicCamera
makeDefault
rotation={[rotX, rotY, (10 * Math.PI) / 180]}
position={[initialCameraPositionX, initialCameraPositionY, distance]}>
<directionalLight
intensity={0.6}
color={new Color('#ffffff')}
castShadow
position={[-100, -100, 200]}
shadow-mapSize={[2048, 2048]}>
<orthographicCamera attach="shadow-camera" args={[-distance, distance, distance, -distance]} />
</directionalLight>
</OrthographicCamera>
1 Like
Ok its work as my expect
next question how to set target of directionalLight to ChickenView
i try to set with following code but its does not work
<ChickenView ref={chickenRef} />
<OrthographicCamera
makeDefault
rotation={[rotX, rotY, (10 * Math.PI) / 180]}
position={[initialCameraPositionX, initialCameraPositionY, distance]}
>
<directionalLight
intensity={0.6}
color={new Color('#ffffff')}
castShadow
position={[-150, 100, -700]}
shadow-mapSize={[2048, 2048]}
target={chickenRef.current}
>
<orthographicCamera
attach="shadow-camera"
args={[-distance, distance, distance, -distance]}
/>
</directionalLight>
</OrthographicCamera>
it null pointer at this line
target={chickenRef.current}
Uncaught TypeError: Cannot read properties of null (reading 'matrixWorld')
at DirectionalLightShadow.updateMatrices
drcmda
October 16, 2023, 10:14pm
5
well in any way you want. right now you’re just putting null into it, a ref is filled after render not before. just set it straight up + updateMatrixWorld Volumetric spotlight - CodeSandbox or you can use refs + effects,
const ref = useRef()
const light = useRef()
...
useLayoutEffect(() => {
light.current.target = ref.current
}, [])
...
<Chicken ref={ref} />
<directionalLight ref={light} />
or a setstate
const [chicken, set] = useState()
...
<Chicken ref={set} />
{chicken && <directionalLight target={chicken} />}
i’d prefer uLE because there’s no FOUC. chicken will be unlit for a single frame with the last one.
1 Like
All enought, thank for your help