three.js实现风的效果
时间: 2023-11-07 16:08:05 浏览: 53
要实现风的效果,可以使用three.js的ShaderMaterial和一个包含随机噪声的纹理。
首先,需要创建一个包含随机噪声的纹理。可以使用three.js提供的PerlinNoise库来生成噪声纹理。以下是一个创建噪声纹理的示例代码:
```javascript
var noiseSize = 256;
var noiseData = new Uint8Array(noiseSize * noiseSize * 4);
for (var i = 0; i < noiseSize * noiseSize; i++) {
var value = Math.random() * 255;
noiseData[i * 4] = value;
noiseData[i * 4 + 1] = value;
noiseData[i * 4 + 2] = value;
noiseData[i * 4 + 3] = 255;
}
var noiseTexture = new THREE.DataTexture(noiseData, noiseSize, noiseSize, THREE.RGBAFormat);
noiseTexture.needsUpdate = true;
noiseTexture.wrapS = THREE.RepeatWrapping;
noiseTexture.wrapT = THREE.RepeatWrapping;
```
接下来,需要创建一个ShaderMaterial,使用噪声纹理来模拟风的效果。以下是一个简单的ShaderMaterial示例代码:
```javascript
var windMaterial = new THREE.ShaderMaterial({
uniforms: {
time: { value: 0 },
noiseTexture: { value: noiseTexture },
},
vertexShader: `
uniform float time;
varying vec2 vUv;
void main() {
vUv = uv;
vec3 pos = position;
pos.z += sin(pos.x * 10.0 + time) * 0.1;
pos.z += sin(pos.y * 10.0 + time) * 0.1;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
uniform sampler2D noiseTexture;
varying vec2 vUv;
void main() {
vec2 noiseCoord = vUv * 10.0;
vec4 noiseColor = texture2D(noiseTexture, noiseCoord);
gl_FragColor = noiseColor;
}
`,
});
```
这个ShaderMaterial使用了一个时间变量和一个噪声纹理。在顶点着色器中,根据时间和顶点坐标的sin函数值来改变顶点位置,从而模拟风的效果。在片元着色器中,使用噪声纹理来确定片元的颜色。
最后,将这个ShaderMaterial应用到一个平面网格上,并在每个渲染帧更新时间变量。以下是一个完整的示例代码:
```javascript
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var noiseSize = 256;
var noiseData = new Uint8Array(noiseSize * noiseSize * 4);
for (var i = 0; i < noiseSize * noiseSize; i++) {
var value = Math.random() * 255;
noiseData[i * 4] = value;
noiseData[i * 4 + 1] = value;
noiseData[i * 4 + 2] = value;
noiseData[i * 4 + 3] = 255;
}
var noiseTexture = new THREE.DataTexture(noiseData, noiseSize, noiseSize, THREE.RGBAFormat);
noiseTexture.needsUpdate = true;
noiseTexture.wrapS = THREE.RepeatWrapping;
noiseTexture.wrapT = THREE.RepeatWrapping;
var windMaterial = new THREE.ShaderMaterial({
uniforms: {
time: { value: 0 },
noiseTexture: { value: noiseTexture },
},
vertexShader: `
uniform float time;
varying vec2 vUv;
void main() {
vUv = uv;
vec3 pos = position;
pos.z += sin(pos.x * 10.0 + time) * 0.1;
pos.z += sin(pos.y * 10.0 + time) * 0.1;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}
`,
fragmentShader: `
uniform sampler2D noiseTexture;
varying vec2 vUv;
void main() {
vec2 noiseCoord = vUv * 10.0;
vec4 noiseColor = texture2D(noiseTexture, noiseCoord);
gl_FragColor = noiseColor;
}
`,
});
var windGeometry = new THREE.PlaneGeometry(5, 5, 10, 10);
var windMesh = new THREE.Mesh(windGeometry, windMaterial);
scene.add(windMesh);
function animate() {
requestAnimationFrame(animate);
windMaterial.uniforms.time.value += 0.05;
renderer.render(scene, camera);
}
animate();
```
这个示例代码创建了一个平面网格,并将风的ShaderMaterial应用到上面。在渲染循环中更新时间变量,并调用渲染器的render方法来渲染场景。
你可以根据需要调整ShaderMaterial中的参数来改变风的效果。例如,可以使用更复杂的噪声纹理、更复杂的顶点变换等。