ThreeJS-3D Tutorial 1: Basic Scene Creation

Three.js is an open source JS 3D graphics library used to create and display high-performance, interactive 3D graphics scenes. It is built on WebGL technology and provides a rich set of features and tools that allow developers to easily build stunning 3D visualizations.

Three.js provides a complete set of tools and APIs for creating and managing 3D scenes, geometry, textures, lighting, materials, cameras, etc. It has a powerful rendering engine that can handle complex rendering tasks such as shadows, transparency, reflection and refraction effects. The library also supports animation, skeletal animation, particle systems and physics simulation, enabling smooth dynamic effects and interactive behaviors. It provides a rich set of controllers and user interaction tools, such as rotation, zooming, panning, and clicking.

Three.js also supports loading and importing various file formats such as OBJ, STL, FBX, glTF, etc. to create and edit 3D models using external tools. It can also be integrated with audio, video and other Web technologies to achieve richer application scenarios.

Next, we will introduce the three major components of three in sequence, Renderer, Scene, and Camera. Each of these three expansions can be written in a separate article. Here is a brief introduction to the concept. We will mainly start with Learn specific knowledge from the case. Interested friends can see this link Three.js Learning , which is introduced in more detail.

Renderer

When we search for WebGL in the official documentation, seven classes of renderers will be displayed:
WebGLMultipleRenderTargets
WebGLRenderer
WebGL1Renderer
WebGLRenderTarget
WebGL3DRenderTarget
WebGLArrayRenderTarget
WebGLCubeRenderTarget
For the time being, we only focus on WebGLRenderer. In fact, it is also the one that is often used.

WebGL1Renderer
three automatically uses the WebGL 2 rendering context after r118 (including this version). If you don't have time to upgrade your code but still want to use the latest version, you can use WebGL1Render. This version of the renderer will enforce a WebGL 1 rendering context.

WebGLRenderer
Below is a basic WebGLRenderer application

 var renderer;
 var width,height;
 function initThree() {
	 width = document.getElementById("box").clientWidth;
	 height = document.getElementById("box").clientHeight;
	  // 生成渲染器对象(属性antialias:抗锯齿效果为设置有效)
	 renderer = new THREE.WebGLRenderer({
	 	antialias: true
	 });
	 renderer.setSize(width,height);
	 document.getElementById("box").appendChild(renderer.domElement);
	 // 设置canvas背景色(clearColor)和背景色透明度(clearAlpha)
	 renderer.setClearColor(0xFFFFFF, 1.0);
 }

Scene

The models added by three.js are all added to the scene, and their initialization is very simple.

 var scene;
 function initScene(){
   scene = new THREE.Scene();
   // 场景的背景色
   scene.background = new THREE.Color( 0xf0f0f0 );
 }
 // 添加一个物体 mesh是什么后面会说明
 scene.add(mesh);

Camera

You can think of the camera as our eyes. It determines which angle of the scene will be displayed, which is what we see. People standing in different positions can see different scenery by raising or lowering their heads. The default camera Both the model and the loaded model are at the origin of the coordinates. In order to see the model, the camera position needs to be offset.
Commonly used cameras are divided into:
CubeCamera

This camera adapts to WebGLCubeRenderTarget

Orthographic Camera-OrthographicCamera

In this projection mode, the size of an object in the rendered image remains the same regardless of its distance from the camera. This is useful for rendering 2D scenes and UI elements etc.

Perspective Camera-PerspectiveCamera

This projection mode is designed to mimic the way the human eye sees. It is the most common projection mode used for rendering three-dimensional scenes.

The three version of all my cases is three-155.
Let’s take a look at the renderings first.
Insert image description here

Up code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    body {
      width: 100%;
      height: 100%;
    }
    * {
      margin: 0;
      padding: 0;
    }
    .label {
      font-size: 20px;
      color: #fff;
      font-weight: 700;
    }
  </style>
</head>
<body>
<div id="container"></div>
<script type="importmap">
  {
    "imports": {
      "three": "../three-155/build/three.module.js",
      "three/addons/": "../three-155/examples/jsm/"
    }
  }
</script>
<script type="module">
import * as THREE from 'three';
import Stats from 'three/addons/libs/stats.module.js';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { CSS2DRenderer, CSS2DObject } from 'three/addons/renderers/CSS2DRenderer.js';
let stats, labelRenderer;
let camera, scene, renderer, mesh, target, controls;
const group = new THREE.Group();

init();
initHelp();
initLight();
axesHelperWord();
animate();

function init() {
  camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 10, 2000 );
  camera.position.set(0, 500, 500);
  camera.up.set(0, 1, 0);
  camera.lookAt(0, 0, 0);

  scene = new THREE.Scene();
  scene.background = new THREE.Color( '#ccc' );
  
  renderer = new THREE.WebGLRenderer( { antialias: true } );
  renderer.setPixelRatio( window.devicePixelRatio );
  renderer.setSize( window.innerWidth, window.innerHeight );
  document.body.appendChild( renderer.domElement );

  labelRenderer = new CSS2DRenderer();
  labelRenderer.setSize( window.innerWidth, window.innerHeight );
  labelRenderer.domElement.style.position = 'absolute';
  labelRenderer.domElement.style.top = '0px';
  labelRenderer.domElement.style.pointerEvents = 'none';
  document.getElementById( 'container' ).appendChild( labelRenderer.domElement );

  window.addEventListener( 'resize', onWindowResize );

  controls = new OrbitControls( camera, renderer.domElement );
  controls.minDistance = 10;
  controls.maxDistance = 1000;
  // 设置为true可启用阻尼(惯性),可用于为控件提供重量感。默认值为false。
  // 请注意,如果启用了此选项,则必须在动画循环中调用.update()。
  controls.enableDamping = false;
  controls.screenSpacePanning = false; // 定义平移时如何平移相机的位置 控制不上下移动

  stats = new Stats();
  stats.setMode(1); // 0: fps, 1: ms
  document.body.appendChild( stats.dom );
  scene.add( group );
}

function initLight() {
  const light = new THREE.DirectionalLight(new THREE.Color('rgb(253,253,253)'));
  light.position.set(100, 100, -10);
  light.intensity = 3; // 光线强度
  const AmbientLight = new THREE.AmbientLight(new THREE.Color('rgb(255,255,255)'));
  scene.add( light );
  scene.add( AmbientLight );
}

function initHelp() {
  const size = 1000;
  const divisions = 20;
  const gridHelper = new THREE.GridHelper( size, divisions );
  scene.add( gridHelper );

  // The X axis is red. The Y axis is green. The Z axis is blue.
  const axesHelper = new THREE.AxesHelper( 500 );
  scene.add( axesHelper );
}

function axesHelperWord() {
  let xP = addWord('X轴');
  let yP = addWord('Y轴');
  let zP = addWord('Z轴');
  xP.position.set(200, 0, 0);
  yP.position.set(0, 200, 0);
  zP.position.set(0, 0, 200);
}

function addWord(word) {
  let name = `<span>${word}</span>`;
  let moonDiv = document.createElement( 'div' );
  moonDiv.className = 'label';
  // moonDiv.textContent = 'Moon';
  // moonDiv.style.marginTop = '-1em';
  moonDiv.innerHTML = name;
  const label = new CSS2DObject( moonDiv );
  group.add( label );
  return label;
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}

function animate() {
  requestAnimationFrame( animate );
  stats.update();
  controls.update();
  labelRenderer.render( scene, camera );
  renderer.render( scene, camera );
}
</script>
</body>
</html>

This is a simple 3D scene. In addition to the three major components introduced before, renderer, camera, and scene, the upper left corner
of stats.js
is an auxiliary library developed by Three.js, which is mainly used to detect the number of frames when the animation is running.
stats.setMode(1); // 0: fps, 1: ms.
Set to 0: it detects the number of frames per second (fps).
When it is set to 1: it detects the rendering time of the screen.

The OrbitControls.js
orbiting control allows the camera to orbit around a target.

GridHelper
is an object used to define a grid. A grid is a two-dimensional array of lines. This is also an auxiliary tool to help us see the 3D scene clearly.

AxesHelper
an axis object that displays the 3 axes in a simple way. The X-axis is red and the Y-axis is green. The Z-axis is blue. This is also an auxiliary tool that can clearly allow us to see the direction in the 3D scene, that is, where the X, Y, and Z axes are.

CSS2DRenderer
The copywriting in the picture uses CSS2DRenderer, and of course the corresponding CSS3DRenderer. The main difference between the two is that CSS2DRenderer will always face the camera, and the size will not change at will when the camera moves. Very suitable for assisting AxesHelper in specifying the X, Y, and Z axes

Of course, light
also has a very important light source. DirectionalLight and AmbientLight are used here. In fact, there are others such as: PointLight, SpotLight, and RectAreaLight, which we will introduce later.

AmbientLight
This light illuminates all objects in the scene equally and globally.
This light cannot be used to cast shadows because it has no direction.

DirectionalLight
emits light in a specific direction. This light behaves as if it is infinitely far away, and the rays produced from it are all parallel. A common use case for this is simulating daylight; the sun is far enough away that its position can be considered infinite and all rays coming from it are parallel.
This light can cast shadows.
You can check the three official website for specific usage parameters.

You will find that in the current 3D scene, except for some auxiliary methods, there is nothing else. In fact, this is the standard template that I often use. With it, when we need to test or learn certain effects, this can be used directly. Use it, and then we can add the required effects to it. I will introduce them one by one in the following cases.

Guess you like

Origin blog.csdn.net/weixin_44384273/article/details/133018998