Files
english/.opencode/skills/threejs/references/04-cameras.md
2026-04-12 01:06:31 +07:00

196 lines
4.8 KiB
Markdown

# Cameras
Define viewpoint and projection for rendering.
## Perspective Camera
Realistic camera with field of view (most common):
```javascript
const camera = new THREE.PerspectiveCamera(
fov, // field of view in degrees (typically 45-75)
aspect, // width / height
near, // near clipping plane (typically 0.1)
far // far clipping plane (typically 1000)
);
camera.position.set(0, 5, 10);
camera.lookAt(0, 0, 0);
// Update after changing parameters
camera.fov = 60;
camera.updateProjectionMatrix();
```
## Orthographic Camera
No perspective distortion (parallel projection):
```javascript
const frustumSize = 10;
const aspect = window.innerWidth / window.innerHeight;
const camera = new THREE.OrthographicCamera(
frustumSize * aspect / -2, // left
frustumSize * aspect / 2, // right
frustumSize / 2, // top
frustumSize / -2, // bottom
0.1, // near
1000 // far
);
// Useful for: 2D games, CAD, isometric views
```
## Camera Controls (Addons)
### OrbitControls (Most Common)
```javascript
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0, 0);
controls.enableDamping = true; // smooth motion
controls.dampingFactor = 0.05;
controls.minDistance = 5;
controls.maxDistance = 50;
controls.maxPolarAngle = Math.PI / 2; // prevent going below ground
// In animation loop
function animate() {
controls.update(); // required if enableDamping = true
renderer.render(scene, camera);
}
```
### FirstPersonControls
```javascript
import { FirstPersonControls } from 'three/addons/controls/FirstPersonControls.js';
const controls = new FirstPersonControls(camera, renderer.domElement);
controls.movementSpeed = 10;
controls.lookSpeed = 0.1;
const clock = new THREE.Clock();
function animate() {
const delta = clock.getDelta();
controls.update(delta);
renderer.render(scene, camera);
}
```
### FlyControls
```javascript
import { FlyControls } from 'three/addons/controls/FlyControls.js';
const controls = new FlyControls(camera, renderer.domElement);
controls.movementSpeed = 10;
controls.rollSpeed = Math.PI / 24;
controls.dragToLook = true;
```
### TransformControls
```javascript
import { TransformControls } from 'three/addons/controls/TransformControls.js';
const controls = new TransformControls(camera, renderer.domElement);
controls.attach(mesh);
scene.add(controls);
// Switch modes
controls.setMode('translate'); // or 'rotate', 'scale'
// Events
controls.addEventListener('change', () => renderer.render(scene, camera));
controls.addEventListener('dragging-changed', (event) => {
orbitControls.enabled = !event.value;
});
```
## Camera Methods
```javascript
// Position and orientation
camera.position.set(x, y, z);
camera.lookAt(x, y, z); // or lookAt(vector3) or lookAt(object.position)
camera.up.set(0, 1, 0); // define "up" direction
// Get world direction
const direction = new THREE.Vector3();
camera.getWorldDirection(direction);
// Screen to world conversion
const mouse = new THREE.Vector2(x, y); // normalized device coords (-1 to 1)
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
// World to screen
const vector = new THREE.Vector3(x, y, z);
vector.project(camera); // now in normalized device coords
```
## Layers
Selective rendering with layers:
```javascript
// Set object layers
mesh.layers.set(1);
// Set camera layers
camera.layers.enable(0); // render layer 0
camera.layers.enable(1); // render layer 1
camera.layers.disable(2); // don't render layer 2
// Objects on disabled layers won't be rendered
```
## Frustum Culling
Automatic optimization (objects outside view are not rendered):
```javascript
// Manually check if object is in view
const frustum = new THREE.Frustum();
const matrix = new THREE.Matrix4().multiplyMatrices(
camera.projectionMatrix,
camera.matrixWorldInverse
);
frustum.setFromProjectionMatrix(matrix);
if (frustum.containsPoint(object.position)) {
// Object is visible
}
```
## Multiple Cameras
```javascript
const mainCamera = new THREE.PerspectiveCamera(...);
const minimapCamera = new THREE.OrthographicCamera(...);
// Render with different viewports
renderer.setViewport(0, 0, width, height);
renderer.render(scene, mainCamera);
renderer.setViewport(width - 200, height - 200, 200, 200);
renderer.render(scene, minimapCamera);
```
## Resize Handling
```javascript
window.addEventListener('resize', () => {
// Perspective camera
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
// Orthographic camera
const aspect = window.innerWidth / window.innerHeight;
camera.left = -frustumSize * aspect / 2;
camera.right = frustumSize * aspect / 2;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
```