安装THREE
- 需要安装好node (个人目前使用 node 版本为 22.14.0)
- npm init -y
- npm install three vite
- 新建 index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>First Three.js</title> <style> *{ margin: 0; } body{ background-color: black; } </style> </head> <body> <!-- <h1>Soon the be Three.js website</h1> --> <script type="module" src="./index.js"></script> </body> </html> - 新建index.js 并引入 three.js
import * as THREE from "three/webgpu"; import { color, convertColorSpace, Fn, If, positionLocal, texture, abs, rotateUV, time, vec2, } from "three/tsl"; import { OrbitControls } from "three/addons/controls/OrbitControls.js"; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10 ); camera.position.z = 1; const renderer = new THREE.WebGPURenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); renderer.setAnimationLoop(animate); window.addEventListener("resize", function () { camera.aspect = window.innerHeight / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(this.window.innerWidth, this.window.innerHeight); }); const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; const material = new THREE.NodeMaterial(); material.fragmentNode = positionLocal; const mesh = new THREE.Mesh(new THREE.PlaneGeometry(), material); scene.add(mesh); function animate() { controls.update(); renderer.render(scene, camera); } - 新建 vite.config.js 并修改 package.json 输入npm run dev
package.jsonimport { defineConfig } from 'vite'; export default defineConfig({ server: { port: 3000, open: true, }, build: { outDir: 'dist', }, plugins: [], });javascript "scripts": { "dev": "vite", "build": "vite build" }, - 浏览器输入http://localhost:3000/ 查看效果
- 添加的是一个 PlaneGeometry 平面几何体 材质 material.fragmentNode 为 positionLocal
- 其中 positionLocal 是通过 three/tsl 暴露出来的
- 在三维空间中, positionLocal 是一个三维向量(x,y,z),表示物体在布局坐标系中的位置,即几何体 xy -0.5 ~ 0.5 将 坐标分量直接赋值给材质的颜色(rgb)通道 颜色会根据坐标值自动映射
9. 现在我们 新建一个Fn方法
const main = Fn(()=>{
// 假如 p点 x的绝对值 小于 0.1 则将p点 z轴值变成1 通过rgb映射变成蓝色
If(abs(p.x).lessThan(0.1), () => {
p.z = 1;
});
return p
})
// 同时将 material的fragment 进行替换
material.fragmentNode = main();
//会得到
- 同理 添加对 y 轴的判断
const main = Fn(() => { const p = positionLocal.toVar(); If(abs(p.x).lessThan(0.1), () => { p.z = 1; }); If(abs(p.y).lessThan(0.1), () => { p.z = 1; }); return p; }); // 我们会得到一个十字架
11. 添加 time 让 十字架动起来
const main = Fn(() => {
const p = positionLocal.toVar();
p.assign(rotateUV(p.xy, time, vec2()));
console.log('time',time)
If(abs(p.x).lessThan(0.1), () => {
p.z = 1;
});
If(abs(p.y).lessThan(0.1), () => {
p.z = 1;
});
return p;
});
- 可以将 planegeometry 替换成别的几何体