three.js艺术火焰shader
Three.js 是一个用于创建 3D 图形的 JavaScript 库。它是一款非常强大和灵活的库,可以用于创建各种各样的 3D 图形和动画效果。在这篇文章中,我们将介绍如何使用 Three.js 创建一个全屏平面,并在平面上应用一个着色器材质绘制艺术火焰的效果。让我们开始吧!
- 创建场景和相机
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 10;
我们首先创建了一个 Three.js 场景和一个透视相机。透视相机是一种常用的 3D 相机类型,它可以创建一个透视效果,使得远处的物体看起来比近处的物体小。我们将相机的位置设置为 z = 10,这样我们可以看到平面的正面。
- 创建平面几何体
let pre = 80;
let width = window.innerWidth/pre;
let height = window.innerHeight/pre;
const geometry = new THREE.PlaneGeometry(width, height)
我们使用 THREE.PlaneGeometry 创建了一个平面几何体,用于表示平面的形状。我们定义了一个比例因子 pre,用于将窗口大小缩小到更小的尺寸,以便于在屏幕上渲染。通过将窗口的宽度和高度除以 pre,我们可以计算出平面的宽度和高度。
- 创建着色器材质
const material = new THREE.ShaderMaterial({
uniforms: {
iTime: { value: 0 },
},
fragmentShader: fragmentShader,
vertexShader: vertexShader,
transparent: true,
});
我们使用 THREE.ShaderMaterial 创建了一个着色器材质,用于渲染平面。着色器材质是 Three.js 中非常强大的特性之一,它可以用于实现各种各样的效果,例如水面模拟、光线追踪、镜面反射等等。在这个例子中,我们使用了一个 fragment shader(片元着色器)来对平面进行渲染。
我们还定义了一些 uniform 变量,包括时间。这些 uniform 变量可以在 JavaScript 代码中进行设置和更新,以便在渲染时传递给着色器。在这个例子中,我们将时间值每帧都自动增加,用于控制动画。
- 编写着色器
全部代码见:码上掘金。
void main() {
vec2 uv = vUv;
uv.x *= 4.0;
float t = iTime * 3.0;
vec3 col = vec3(0);
float noise = getNoise(uv, t);
CUTOFF = uv.y;
CUTOFF += pow(abs(uv.x*0.5 - 1.),1.0);
if (noise < CUTOFF){
col = vec3(0.);
}else{
float d = pow(getDepth(noise),0.7);
vec3 hsv = vec3(d *0.17,0.8 - d/4., d + 0.8);
col = hsv2rgb(hsv);
}
gl_FragColor = vec4(col,col.r);
}
- 创建平面网格
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
我们使用 THREE.Mesh 将平面几何体和着色器材质组合成一个网格,并将其添加到场景中。网格是 Three.js 中用于表示 3D 对象的基本单位之一,它由一个几何体和一个材质组成。在这个例子中,我们将平面几何体和着色器材质传递给网格,得到一个可以渲染的平面对象。
- 创建渲染器并渲染场景
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
function animate() {
requestAnimationFrame(animate);
material && (material.uniforms.iTime.value += 0.01);
renderer.render(scene, camera);
}
animate();
我们创建了一个 THREE.WebGLRenderer 对象,并设置了渲染器的大小。我们还将渲染器的 domElement 添加到 HTML 文档中,以便将 Three.js 场景渲染到屏幕上。
我们创建了一个 animate 函数,它使用 requestAnimationFrame 方法来循环执行渲染,并在每个帧上更新着色器材质的 uniform 变量。我们还检查了着色器材质是否存在,以避免出现错误。
- 更新窗口大小
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize, false);
最后,我们创建了一个 onWindowResize 函数,该函数会在窗口大小改变时调用,更新相机和渲染器的参数。我们还将 onWindowResize 函数绑定到 resize 事件上,以便在窗口大小改变时自动调用。
这就是使用 Three.js 创建全屏平面的全部步骤。通过这个例子,我们可以看到 Three.js 的强大和灵活性,以及着色器材质的基本用法。