」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在 � 學習 Three.js

在 � 學習 Three.js

發佈於2024-11-07
瀏覽:796

I had the chance to dive into some web development where I wanted to add interactive 3D elements that could move and react to certain triggers. Naturally, this led me to explore Three.js — a super popular library for rendering 3D graphics on the web.

While learning Three.js, I went through a ton of blogs, tutorials, and resources, and I thought, “Why not summarize my journey and share a really cool example?” So, if you’re someone who wants to get started with Three.js, I’ve put together this guide just for you.

As we step into 2024, the need for immersive and interactive 3D experiences is skyrocketing. Whether it’s for e-commerce sites showing 3D models of products, educational platforms using 3D simulations, or even games — 3D technology is transforming the way we engage with digital content. And the best part? With Three.js, creating these experiences is easier than ever!

In this guide, I’ll take you step-by-step through Three.js, and by the end, you’ll have built a 3D scene with a floating astronaut in space. ?‍??

Ready to dive in? Let’s get started!

Why Learn Three.js in 2024? ?

Three.js provides a simple yet powerful way to bring these 3D experiences to the web. Here’s why learning Three.js is a fantastic idea in 2024:

  1. WebXR and WebGL: Virtual reality (VR) and augmented reality (AR) on the web are growing, and Three.js is WebXR-ready.
  2. Cross-Browser Support: It works seamlessly across modern browsers, including mobile ones.
  3. Lightweight 3D Creation: No need to learn complex WebGL. Three.js makes 3D creation as easy as writing JavaScript.
  4. Growing Community: With more than a decade of active development, the library has an ever-growing collection of plugins and examples.

Setting Up: Your First Three.js Scene

Let’s start with the basics. The magic of Three.js starts with three core concepts: Scene, Camera, and Renderer. If you understand these, you’re already halfway there!

1. The Scene ?️

Think of the scene as your 3D canvas. It contains all the objects, lights, and cameras needed to create the final 3D rendering.

const scene = new THREE.Scene();

2. The Camera ?

The camera is your “viewpoint” into the 3D world. In 2024, most developers use PerspectiveCamera, which simulates how human eyes see the world.

const camera = new THREE.PerspectiveCamera(
  75, // Field of view
  window.innerWidth / window.innerHeight, // Aspect ratio
  0.1, // Near clipping plane
  1000 // Far clipping plane
);
camera.position.z = 5; // Move the camera back so we can see the objects

3. The Renderer ?

The renderer converts the 3D scene and camera into a 2D image for the browser to display. In 2024, we typically use WebGLRenderer, which is optimized for modern browsers.

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement); 
// Adds the canvas to the webpage

4. Creating a Simple 3D Object: A Cube ?

Let’s create our first 3D object: a cube. We define its geometry, give it a material, and combine them into a mesh.

const geometry = new THREE.BoxGeometry(); // Define the shape (cube)
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
 // Apply a green color to the cube
const cube = new THREE.Mesh(geometry, material); 
// Combine the geometry and material into a 3D mesh
scene.add(cube); // Add the cube to the scene

5. Animating the Cube ?

3D is all about movement! Let’s make our cube rotate. To do this, we create an animation loop using requestAnimationFrame, which ensures smooth 60fps rendering.

function animate() {
  requestAnimationFrame(animate); // Keep looping the function for continuous animation

  cube.rotation.x  = 0.01; // Rotate cube on the X axis
  cube.rotation.y  = 0.01; // Rotate cube on the Y axis
renderer.render(scene, camera); // Render the scene from the camera's perspective
}
animate(); // Start the animation loop

Putting It All Together:

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
function animate() {
  requestAnimationFrame(animate);
  cube.rotation.x  = 0.01;
  cube.rotation.y  = 0.01;
  renderer.render(scene, camera);
}
animate();

Congrats! ? You’ve now set up the basics of a 3D world ! ?

Adding Objects to the Scene ?️

Now that we have a scene, camera, and renderer, it’s time to add some 3D objects! We’ll start with something simple: a rotating cube.

const geometry = new THREE.BoxGeometry(); // Defines the shape
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
// Adds color to the shape
const cube = new THREE.Mesh(geometry, material); 
// Combines the shape and color
scene.add(cube); // Adds the cube to the scene

Adding Animation:

Now let’s animate the cube so it spins! Real-time graphics need smooth animations, and we can achieve that with requestAnimationFrame.

function animate() {
  requestAnimationFrame(animate); // Keep looping through this function

  cube.rotation.x  = 0.01; // Rotate the cube around the X axis
  cube.rotation.y  = 0.01; // Rotate the cube around the Y axis

renderer.render(scene, camera); // Render the scene from the perspective of the camera

}
animate(); // Start the animation loop

And boom ? — You’ve just created your first animated 3D object in Three.js!

Taking It Up a Notch

Lights, Materials, and Shadows ?

3D graphics are nothing without light. The more realistic the lighting, the more impressive your 3D world becomes. Let’s explore:

Adding Lights ?

Without light, even the best 3D models will look flat and lifeless. In Three.js, there are several types of lights:

  • AmbientLight: Provides soft global lighting that illuminates all objects equally.
  • DirectionalLight: Simulates sunlight, casting parallel light rays in a specific direction.
const ambientLight = new THREE.AmbientLight(0x404040, 2);
 // Soft light to brighten the scene
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1).normalize(); 
// Light from top-right corner
scene.add(directionalLight);

Better Materials for Realism ?

MeshStandardMaterial is the go-to material for creating objects that look realistic.

const material = new THREE.MeshStandardMaterial({ color: 0xff0051, metalness: 0.6, roughness: 0.4 });

Interactivity with OrbitControls ?️

What’s a 3D scene without interactivity? With OrbitControls, you can let users rotate, pan, and zoom in your 3D world.

const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.update(); // Make sure the controls stay in sync with the camera

Textures and Models: Bringing Realism to Life ?

loading 3D models and textures is key to building immersive experiences. Here’s how to load a 3D model of, say, a floating astronaut (because why not? ?):

Using the GLTFLoader:

const loader = new THREE.GLTFLoader();
loader.load('/path-to-your-model/astronaut.glb', function (gltf) {
  scene.add(gltf.scene); // Add the astronaut to the scene
});

Real-World Example: Floating Astronaut in Space ??‍?

Let’s bring everything together with a complete example — a floating astronaut in space! This example demonstrates everything we’ve covered so far: 3D models, textures, lights, animations, and interactivity.

Learning Three.js in �

Key Aspects of the Code:

Astronaut Model:

The astronaut model (astronaut.glb) is loaded using useGLTF().
The model uses several textures (color, roughness, metalness, normal, and ambient occlusion).

Textures:

  1. Color Texture: Adds base color to the astronaut model.
  2. Roughness Texture: Determines how rough or smooth the surface of the astronaut is.
  3. Metalness Texture: Controls how metallic the material looks.
  4. Normal Texture: Adds surface detail to make the astronaut’s surface look more realistic.
  5. Ambient Occlusion (AO): Adds shadows in crevices to give the astronaut model more depth.

Lighting:

  1. Ambient Light: Adds overall brightness to the scene.
  2. Directional Light: Illuminates the astronaut from one direction, simulating sunlight.
  3. Spot Light: Adds focused light on the astronaut to emphasize key areas.

Post-Processing:

Bloom: A bloom effect is used to create a subtle glow, enhancing the overall visual appeal.

Controls:

OrbitControls: Allows the user to interact with the scene by zooming and panning around the astronaut.

Final Code for Floating Astronaut:

The code you provided implements a 3D floating astronaut in space using Three.js, React Three Fiber, and various textures. Below is an explanation of the code along with some minor improvements:

import * as THREE from 'three';
import React, { useRef, useEffect } from 'react';
import { Canvas, useFrame, useLoader } from '@react-three/fiber';
import { OrbitControls, useGLTF } from '@react-three/drei';
import { TextureLoader, AnimationMixer, BackSide } from 'three';
import { EffectComposer, Bloom } from '@react-three/postprocessing';

const Astronaut = () => {
  const { scene, animations } = useGLTF('/astronaut.glb'); // Load the astronaut model
  const mixer = useRef(null);

  useEffect(() => {
    scene.scale.set(0.3, 0.3, 0.3); // Scale down the astronaut
  }, [scene]);

  useFrame((state, delta) => {
    if (!mixer.current && animations.length) {
      mixer.current = new AnimationMixer(scene);
      mixer.current.clipAction(animations[0]).play();
    }
    if (mixer.current) mixer.current.update(delta);
  });

  return ;
};

const SpaceBackground = () => {
  const texture = useLoader(TextureLoader, '/textures/space-background.jpg');
  return (
    
      
      
    
  );
};

const App = () => {
  return (
    
      
      
      
      
      
      
        
      
    
  );
};

export default App;
  • Astronaut Model: The astronaut model is loaded using GLTFLoader, animated with AnimationMixer.
  • Space Background: A large textured sphere acts as the space backdrop.
  • Lighting: Ambient and directional lights make the astronaut stand out, while bloom adds a glowing effect.
  • Interactivity: Users can pan, zoom, and rotate using OrbitControls. Heres how the result looks like:

Learning Three.js in �

Wrapping Up ?

With Three.js, creating stunning 3D experiences has never been easier. Whether you’re interested in building games, interactive websites, or visualizing data in 3D, the possibilities are endless. In 2024, the web is more immersive than ever, and with Three.js, you can be a part of this exciting future.

GitHub Repository ?

You can find the full source code for the floating astronaut in space project on GitHub. Feel free to explore, clone, and modify it to suit your needs.

GitHub Repository: 3D Floating Astronaut Project

Assets and Image Links ?

  • 3D Astronaut Model: The astronaut model used in this project can be found on Sketchfab.
    Animated Floating Astronaut in Space Suit (Sketchfab)

  • Background Image: The background space image is provided by Alex Myers from Pixabay.
    Image by Alex Myers from Pixabay.

Happy coding, future 3D creator! ?

版本聲明 本文轉載於:https://dev.to/ankitakanchan/learning-threejs-in-2024-40id?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • C++20 Consteval函數中模板參數能否依賴於函數參數?
    C++20 Consteval函數中模板參數能否依賴於函數參數?
    [ consteval函數和模板參數依賴於函數參數在C 17中,模板參數不能依賴一個函數參數,因為編譯器仍然需要對非contexexpr futcoriations contim at contexpr function進行評估。 compile time。 C 20引入恆定函數,必須在編譯時進...
    程式設計 發佈於2025-05-19
  • Python不會對超範圍子串切片報錯的原因
    Python不會對超範圍子串切片報錯的原因
    在python中用索引切片範圍:二重性和空序列索引單個元素不同,該元素會引起錯誤,切片在序列的邊界之外沒有。 這種行為源於索引和切片之間的基本差異。索引一個序列,例如“示例” [3],返回一個項目。但是,切片序列(例如“示例” [3:4])返回項目的子序列。 索引不存在的元素時,例如“示例” [9...
    程式設計 發佈於2025-05-19
  • 如何從PHP中的數組中提取隨機元素?
    如何從PHP中的數組中提取隨機元素?
    從陣列中的隨機選擇,可以輕鬆從數組中獲取隨機項目。考慮以下數組:; 從此數組中檢索一個隨機項目,利用array_rand( array_rand()函數從數組返回一個隨機鍵。通過將$項目數組索引使用此鍵,我們可以從數組中訪問一個隨機元素。這種方法為選擇隨機項目提供了一種直接且可靠的方法。
    程式設計 發佈於2025-05-19
  • 如何使用Regex在PHP中有效地提取括號內的文本
    如何使用Regex在PHP中有效地提取括號內的文本
    php:在括號內提取文本在處理括號內的文本時,找到最有效的解決方案是必不可少的。一種方法是利用PHP的字符串操作函數,如下所示: 作為替代 $ text ='忽略除此之外的一切(text)'; preg_match('#((。 &&& [Regex使用模式來搜索特...
    程式設計 發佈於2025-05-19
  • CSS可以根據任何屬性值來定位HTML元素嗎?
    CSS可以根據任何屬性值來定位HTML元素嗎?
    靶向html元素,在CSS 中使用任何屬性值,在CSS中,可以基於特定屬性(如下所示)基於特定屬性的基於特定屬性的emants目標元素: 字體家庭:康斯拉斯(Consolas); } 但是,出現一個常見的問題:元素可以根據任何屬性值而定位嗎?本文探討了此主題。 的目標元素有任何任何屬性值,...
    程式設計 發佈於2025-05-19
  • 為什麼PYTZ最初顯示出意外的時區偏移?
    為什麼PYTZ最初顯示出意外的時區偏移?
    與pytz 最初從pytz獲得特定的偏移。例如,亞洲/hong_kong最初顯示一個七個小時37分鐘的偏移: 差異源利用本地化將時區分配給日期,使用了適當的時區名稱和偏移量。但是,直接使用DateTime構造器分配時區不允許進行正確的調整。 example pytz.timezone(&#...
    程式設計 發佈於2025-05-19
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-05-19
  • 如何避免Go語言切片時的內存洩漏?
    如何避免Go語言切片時的內存洩漏?
    ,a [j:] ...雖然通常有效,但如果使用指針,可能會導致內存洩漏。這是因為原始的備份陣列保持完整,這意味著新切片外部指針引用的任何對象仍然可能佔據內存。 copy(a [i:] 對於k,n:= len(a)-j i,len(a); k
    程式設計 發佈於2025-05-19
  • C++成員函數指針正確傳遞方法
    C++成員函數指針正確傳遞方法
    如何將成員函數置於c 的函數時,接受成員函數指針的函數時,必須同時提供對象的指針,並提供指針和指針到函數。需要具有一定簽名的功能指針。要通過成員函數,您需要同時提供對象指針(此)和成員函數指針。這可以通過修改Menubutton :: SetButton()(如下所示:[&& && && &&華)...
    程式設計 發佈於2025-05-19
  • 用戶本地時間格式及時區偏移顯示指南
    用戶本地時間格式及時區偏移顯示指南
    在用戶的語言環境格式中顯示日期/時間,並使用時間偏移在向最終用戶展示日期和時間時,以其localzone and格式顯示它們至關重要。這確保了不同地理位置的清晰度和無縫用戶體驗。以下是使用JavaScript實現此目的的方法。 方法:推薦方法是處理客戶端的Javascript中的日期/時間格式化和...
    程式設計 發佈於2025-05-19
  • 在Python中如何創建動態變量?
    在Python中如何創建動態變量?
    在Python 中,動態創建變量的功能可以是一種強大的工具,尤其是在使用複雜的數據結構或算法時,Dynamic Variable Creation的動態變量創建。 Python提供了幾種創造性的方法來實現這一目標。 利用dictionaries 一種有效的方法是利用字典。字典允許您動態創建密鑰並...
    程式設計 發佈於2025-05-19
  • 如何使用不同數量列的聯合數據庫表?
    如何使用不同數量列的聯合數據庫表?
    合併列數不同的表 當嘗試合併列數不同的數據庫表時,可能會遇到挑戰。一種直接的方法是在列數較少的表中,為缺失的列追加空值。 例如,考慮兩個表,表 A 和表 B,其中表 A 的列數多於表 B。為了合併這些表,同時處理表 B 中缺失的列,請按照以下步驟操作: 確定表 B 中缺失的列,並將它們添加到表的...
    程式設計 發佈於2025-05-19
  • 您如何在Laravel Blade模板中定義變量?
    您如何在Laravel Blade模板中定義變量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配變量對於存儲以後使用的數據至關重要。在使用“ {{}}”分配變量的同時,它可能並不總是最優雅的解決方案。 幸運的是,Blade通過@php Directive提供了更優雅的方法: $ old_section =...
    程式設計 發佈於2025-05-19
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-05-19
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,將常數列添加到Spark DataFrame,該列具有適用於所有行的任意值的Spark DataFrame,可以通過多種方式實現。使用文字值(SPARK 1.3)在嘗試提供直接值時,用於此問題時,旨在為此目的的column方法可能會導致錯誤。 df.withCo...
    程式設計 發佈於2025-05-19

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3