46. Three.js案例-创建颜色不断变化的立方体模型

46. Three.js案例-创建颜色不断变化的立方体模型

实现效果

知识点

Three.js基础组件

WebGLRenderer

THREE.WebGLRenderer是Three.js提供的用于渲染场景的WebGL渲染器。它支持抗锯齿处理,可以设置渲染器的大小和背景颜色。

  • 构造器
    • antialias: 是否开启抗锯齿,默认为false。
    • setSize(width, height): 设置渲染器的宽度和高度。
    • setClearColor(color, alpha): 设置渲染器的背景颜色和透明度。
Scene

THREE.Scene是Three.js中的场景对象,所有的物体都需要添加到场景中才能被渲染。

  • 方法
    • add(object): 向场景中添加物体。
PerspectiveCamera

THREE.PerspectiveCamera是透视相机,模拟人眼的视角效果。

  • 构造器
    • fov: 视野角度(Field of View),通常设置为45度。
    • aspect: 宽高比,通常是窗口宽度除以高度。
    • near: 近裁剪面距离。
    • far: 远裁剪面距离。
  • 属性
    • position: 相机的位置。
    • lookAt(vector): 设置相机看向的目标位置。

ShaderMaterial

ShaderMaterial

THREE.ShaderMaterial允许用户自定义着色器,通过编写GLSL代码来控制物体的外观。

  • 构造器
    • uniforms: 传递给着色器的统一变量。
      • time: 时间变量,类型为浮点数。
      • resolution: 分辨率变量,类型为二维向量。
    • vertexShader: 顶点着色器代码。
    • fragmentShader: 片元着色器代码。
顶点着色器

顶点着色器负责计算每个顶点的位置,并将一些数据传递给片元着色器。

glsl 复制代码
varying vec2 vUv;
void main() {
  vUv = uv;
  vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
  gl_Position = projectionMatrix * mvPosition;
}
片元着色器

片元着色器负责计算每个像素的颜色。

glsl 复制代码
uniform float time;
uniform vec2 resolution;
varying vec2 vUv;
void main( void ) {
  vec2 position = -1.0 + 2.0 * vUv;
  float red = abs(sin(position.x * position.y + time / 5.0));
  float green = abs(sin(position.x * position.y + time / 4.0));
  float blue = abs(sin(position.x * position.y + time / 3.0));
  gl_FragColor = vec4(red, green, blue, 1.0);
}

Mesh

THREE.Mesh是网格对象,由几何体和材质组成。

  • 构造器
    • geometry: 几何体,如BoxGeometry
    • material: 材质,如ShaderMaterial

动画

使用requestAnimationFrame函数实现动画效果,不断更新物体的旋转角度和时间变量。

javascript 复制代码
function animate() {
  myMesh.rotation.y = myStep += 0.01;
  myMesh.rotation.x = myStep;
  myMesh.rotation.z = myStep;
  myMesh.material.uniforms.time.value += 0.1;
  requestAnimationFrame(animate);
  myRenderer.render(myScene, myCamera);
}

代码

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="ThreeJS/three.js"></script>
    <script src="ThreeJS/jquery.js"></script>
</head>
<body>
<div id="myContainer"></div>
<script id="myVertexShader" type="x-shader/x-vertex">
    varying vec2 vUv;
    void main() {
      vUv = uv;
      vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
      gl_Position = projectionMatrix * mvPosition;
    }
</script>
<script id="myFragmentShader" type="x-shader/x-fragment">
    uniform float time;
    uniform vec2 resolution;
    varying vec2 vUv;
    void main( void ) {
      vec2 position = -1.0 + 2.0 * vUv;
      float red = abs(sin(position.x * position.y + time / 5.0));
      float green = abs(sin(position.x * position.y + time / 4.0));
      float blue = abs(sin(position.x * position.y + time / 3.0));
      gl_FragColor = vec4(red, green, blue, 1.0);
    }
</script>
<script type="text/javascript">
    var myRenderer = new THREE.WebGLRenderer({antialias: true});
    myRenderer.setSize(window.innerWidth, window.innerHeight);
    myRenderer.setClearColor('white', 1.0);
    $('#myContainer')[0].appendChild(myRenderer.domElement);
    var myScene = new THREE.Scene();
    var myCamera = new THREE.PerspectiveCamera(45,
        window.innerWidth / window.innerHeight, 10, 130);
    myCamera.position.x = 30;
    myCamera.position.y = 30;
    myCamera.position.z = 30;
    myCamera.lookAt(new THREE.Vector3(0, 0, 0));
    var myShaderMaterial = new THREE.ShaderMaterial({
        uniforms: {
            time: {type: "f", value: 1.0},
            resolution: {type: "v2", value: new THREE.Vector2()},
        },
        vertexShader: $('#myVertexShader')[0].textContent,
        fragmentShader: $('#myFragmentShader')[0].textContent
    });
    var myBoxGeometry = new THREE.BoxGeometry(16, 16, 16);
    var myMesh = new THREE.Mesh(myBoxGeometry, myShaderMaterial);
    myScene.add(myMesh);
    var myStep = 0;
    function animate() {
        myMesh.rotation.y = myStep += 0.01;
        myMesh.rotation.x = myStep;
        myMesh.rotation.z = myStep;
        myMesh.material.uniforms.time.value += 0.1;
        requestAnimationFrame(animate);
        myRenderer.render(myScene, myCamera);
    }
    animate();
</script>
</body>
</html>

演示链接

示例链接

相关推荐
xhload3d14 小时前
热力图可视化为何被广泛应用?| 图扑数字孪生
3d·html5·webgl·数字孪生·可视化·热力图·三维建模·轻量化·电力能源·空间热力图
十年_H19 小时前
Cesium 顶点着色器的数据来源
javascript·webgl·cesium
秋田君2 天前
3D热力图封装组件:Vue + Three.js 实现3D图表详解
javascript·vue.js·3d·three.js·热力图
Mintopia5 天前
🌌 Three.js 几何变化动画配合噪声粒子教程:让你的代码也会“呼吸”
前端·javascript·three.js
xhload3d7 天前
WebGL/Canvas 内存泄露分析
低代码·3d·html5·webgl·数字孪生·可视化·软件开发·工业互联网·内存泄漏·轻量化·技术应用·hightopo
爱看书的小沐9 天前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine
Dragonir9 天前
React+Three.js 实现 Apple 2025 热成像 logo
前端·javascript·html·three.js·页面特效
郝学胜-神的一滴10 天前
Three.js光照技术详解:为3D场景注入灵魂
开发语言·前端·javascript·3d·web3·webgl
linweidong11 天前
让低端机也能飞:Canvas/WebGL/Viz 分层、降级渲染与数据抽样策略
前端框架·webgl·canvas·前端动画·前端面经·css渲染·动画优化