Three.js camera

This section will further introduce the camera function on the basis of the previous section.
The cameras of three.js mainly include two types: orthographic projection cameras and perspective projection cameras.

  1. Perspective projection camera: THREE.PerspectiveCamera, the most natural view, the farther away from the camera, the smaller they will be rendered.
  2. Orthographic projection camera: THREE.OrthographicCamera, all cubes are rendered with the same size.
  3. VR camera: THREE.StereoCamera renders the left and right eye images side by side, or through WebVR, etc.

renderings

insert image description here

source code

The plug-in js introduced [my csdn also has download resources, if you can’t open git, you can download it on csdn]:

Preparations (cloning several meshes of different colors first)

Add a gui method that can clone several grids with different colors and relative positions. Now we can click the clone method in the upper right corner of the page to add different cubes.

var gui = new dat.GUI();
var cloneIndex = 0
gui.add(new function () {
    
    
  this.clone = function () {
    
    
	  cloneIndex += 3
	  var clonedGeometry = mesh.children[0].geometry.clone();
	  var materials = [
		  new THREE.MeshLambertMaterial({
    
    opacity: 0.8, color: Math.random() * 0xffffff, transparent: true}),
		  new THREE.MeshBasicMaterial({
    
    color: 0x000000, wireframe: true})
	  ];

	  var mesh2 = THREE.SceneUtils.createMultiMaterialObject(clonedGeometry, materials);
	  mesh2.children.forEach(function (e) {
    
    
		  e.castShadow = true
	  });
	  mesh2.translateX(cloneIndex);
	  mesh2.translateZ(-cloneIndex);
	  mesh2.name = "clone" + cloneIndex;
	  scene.remove(scene.getChildByName("clone"));
	  scene.add(mesh2);
  }
}, 'clone');

important point:

  • You can change the position of the object using the translate() method, but this method does not set the absolute position of the object, but the translation distance of the object relative to the current position.
  • Math.random() * 0xffffff: The method is to realize the color random number.

perspective projection camera

The effect of this camera is closer to the real world, and the fov attribute of the camera determines the horizontal field of view. Based on the aspect property, the longitudinal field of view is determined accordingly. The near attribute determines the near distance, and the far attribute determines the far distance. The area between the near face distance and the far face distance will be rendered.
insert image description here
insert image description here

orthographic projection camera

Since the objects rendered by the orthographic projection camera are all the same size, it doesn't care what aspect ratio is used, or what perspective the scene is viewed from. When using an orthographic camera, what you define is a box area that needs to be rendered.
insert image description here
insert image description here

camera focus

  • In the past, we usually camera.lookAt(scene.position)focus the camera to the center of the scene through methods
  • Now we can use camera.lookAt(new THREE.Vector3(x, y, z));to support specifying a 3D coordinate point for the camera to focus on.
  • Of course, you can also specify a special grid and let the camera focus on this grid: camera.lookAt(mesh.position), so that when the grid position changes, the camera will follow the coordinate changes of the grid to track it.

source code

4.js

var stats = initStats();
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(new THREE.Color(0x000000));
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;

var planeGeometry = new THREE.PlaneGeometry(60, 40, 1, 1);
var planeMaterial = new THREE.MeshLambertMaterial({
    
    
	color: 0xffffff
});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.receiveShadow = true;
plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;
scene.add(plane);

camera.position.x = -80;
camera.position.y = 100;
camera.position.z = 240;
camera.lookAt(scene.position);

// 设置8个顶点
var vertices = [
	new THREE.Vector3(1,1,1),
	new THREE.Vector3(1,5,1),
	new THREE.Vector3(1,1,5),
	new THREE.Vector3(1,5,5),
	new THREE.Vector3(5,1,1),
	new THREE.Vector3(5,5,1),
	new THREE.Vector3(5,1,5),
	new THREE.Vector3(5,5,5)
]

// 构建立方体所需要的十二个三角形平面
var faces = [
	new THREE.Face3(0,2,1),
	new THREE.Face3(2,3,1),
	new THREE.Face3(7,3,2),
	new THREE.Face3(7,2,6),
	new THREE.Face3(5,7,6),
	new THREE.Face3(4,5,6),
	new THREE.Face3(1,5,0),
	new THREE.Face3(0,5,4),
	new THREE.Face3(5,1,3),
	new THREE.Face3(5,3,7),
	new THREE.Face3(2,0,4),
	new THREE.Face3(2,4,6)
]

var geom = new THREE.Geometry()
geom.vertices = vertices
geom.faces = faces
geom.computeFaceNormals()
// 设置两种材质,这样方便同时看颜色和骨架
var materials = [
	new THREE.MeshBasicMaterial({
    
    color: 0x000000, wireframe: true}),
	new THREE.MeshLambertMaterial({
    
    opacity: 0.6, color: 0x44ff44, transparent: true})
];
// materials这样做的原因是,除了显示绿色透明的立方体外,我还想显示一个线框。因为使用线框可以很容易地找出顶点和面的位置。
// SceneUtils是SceneUtils里的方法
var mesh = THREE.SceneUtils.createMultiMaterialObject(geom, materials);
mesh.castShadow = true;
mesh.children.forEach(function (e) {
    
    
  e.castShadow = true
});

scene.add(mesh);

var ambientLight = new THREE.AmbientLight(0x3c3c3c);
scene.add(ambientLight);

var spotLight = new THREE.SpotLight(0xffffff, 1.2, 150, 120);
spotLight.position.set(-40, 60, -10);
spotLight.castShadow = true;
scene.add(spotLight);

document.getElementById("webgl-output").appendChild(renderer.domElement);
var trackballControls = initTrackballControls(camera, renderer);
var clock = new THREE.Clock();

var gui = new dat.GUI();
var cloneIndex = 0
gui.add(new function () {
    
    
  this.clone = function () {
    
    
	  cloneIndex += 3
	  var clonedGeometry = mesh.children[0].geometry.clone();
	  var materials = [
		  new THREE.MeshLambertMaterial({
    
    opacity: 0.8, color: Math.random() * 0xffffff, transparent: true}),
		  new THREE.MeshBasicMaterial({
    
    color: 0x000000, wireframe: true})
	  ];

	  var mesh2 = THREE.SceneUtils.createMultiMaterialObject(clonedGeometry, materials);
	  mesh2.children.forEach(function (e) {
    
    
		  e.castShadow = true
	  });
	  mesh2.translateX(cloneIndex);
	  mesh2.translateZ(-cloneIndex);
	  mesh2.name = "clone" + cloneIndex;
	  scene.remove(scene.getChildByName("clone"));
	  scene.add(mesh2);
  }
}, 'clone');

var controls = new function () {
    
    
  this.perspective = "Perspective";
  this.switchCamera = function () {
    
    
	  if (camera instanceof THREE.PerspectiveCamera) {
    
    
		  camera = new THREE.OrthographicCamera(window.innerWidth / -16, window.innerWidth / 16, window.innerHeight / 16, window.innerHeight / -16, -200, 500);
		  camera.position.x = -80;
		  camera.position.y = 100;
		  camera.position.z = 240;
		  camera.lookAt(scene.position);
		  trackballControls = initTrackballControls(camera, renderer);
		  this.perspective = "Orthographic";
	  } else {
    
    
		  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
		  camera.position.x = -80;
		  camera.position.y = 100;
		  camera.position.z = 240;
		  camera.lookAt(scene.position);
		  trackballControls = initTrackballControls(camera, renderer);
		  this.perspective = "Perspective";
	  }
  };
};
gui.add(controls, 'switchCamera');
gui.add(controls, 'perspective').listen();

render();

var step = 0
function render() {
    
    
	trackballControls.update(clock.getDelta());
	stats.update();
	if (camera instanceof THREE.Camera) {
    
    
		step += 0.02;
		var x = 10 + ( 100 * (Math.sin(step)));
		camera.lookAt(new THREE.Vector3(x, 10, 0));
	}
	requestAnimationFrame(render);
	renderer.render(scene, camera);
}

Guess you like

Origin blog.csdn.net/qq_35517283/article/details/130247445