将三个.js WebGL粒子和着色器与鼠标运动相结合
我非常感谢有关如何实现这一目标的任何建议。
因此,我一直在尝试取得您可以在PIC.5上看到的结果。如何将底部着色器倒置并更改背景,以使粒子向内弯曲(凹形立方体形状可能是我需要的)?
我还将链接附加到所需的结果。
我非常努力地研究如何实现这一目标,但没有成功。
任何帮助将不胜感激!谢谢大家,请随时提出任何其他问题。
>
/*
Most of the stuff in here is just bootstrapping. Essentially it's just
setting ThreeJS up so that it renders a flat surface upon which to draw
the shader. The only thing to see here really is the uniforms sent to
the shader. Apart from that all of the magic happens in the HTML view
under the fragment shader.
*/
let container;
let camera, scene, renderer;
let uniforms;
let loader=new THREE.TextureLoader();
let texture;
loader.setCrossOrigin("anonymous");
loader.load(
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/982762/noise.png',
function do_something_with_texture(tex) {
texture = tex;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.minFilter = THREE.LinearFilter;
init();
animate();
}
);
function init() {
container = document.getElementById( 'container' );
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_noise: { type: "t", value: texture },
u_mouse: { type: "v2", value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
material.extensions.derivatives = true;
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
// renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener('pointermove', (e)=> {
let ratio = window.innerHeight / window.innerWidth;
uniforms.u_mouse.value.x = (e.pageX - window.innerWidth / 2) / window.innerWidth / ratio;
uniforms.u_mouse.value.y = (e.pageY - window.innerHeight / 2) / window.innerHeight * -1;
e.preventDefault();
});
}
function onWindowResize( event ) {
// renderer.setSize( 1000, 1000 );
renderer.setSize( window.innerWidth, window.innerHeight );
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
function animate(delta) {
requestAnimationFrame( animate );
render(delta);
}
let capturer = new CCapture( {
verbose: true,
framerate: 30,
// motionBlurFrames: 4,
quality: 90,
format: 'webm',
workersPath: 'js/'
} );
let capturing = false;
isCapturing = function(val) {
if(val === false && window.capturing === true) {
capturer.stop();
capturer.save();
} else if(val === true && window.capturing === false) {
capturer.start();
}
capturing = val;
}
toggleCapture = function() {
isCapturing(!capturing);
}
window.addEventListener('keyup', function(e) { console.log(e.keyCode); if(e.keyCode == 68) toggleCapture(); });
let then = 0;
function render(delta) {
uniforms.u_time.value = -11200 + delta * 0.0015;
renderer.render( scene, camera );
if(capturing) {
capturer.capture( renderer.domElement );
}
}
const nearDist = 0.1;
const farDist = 70000;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
100,
window.innerWidth / window.innerHeight,
nearDist,
farDist);
camera.position.x = farDist * -200;
camera.position.z = 5000;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor("BLACK"); // Backgrond Color - Blue
renderer.setPixelRatio(window.devicePixelRatio); // For HiDPI devices to prevent bluring output canvas
renderer.setSize(window.innerWidth, window.innerHeight);
document.querySelector("#canvas-wrapper").appendChild(renderer.domElement);
// CREATE CUBES
const cubeSize = 30;
const geometry = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize); // BufferAttribute allows for more efficient passing of data to the GPU
const material = new THREE.MeshNormalMaterial(); // Maps the normal vectors to RGB colors
const group = new THREE.Group();
for (let i = 0; i < 500; i++) {
const mesh = new THREE.Mesh(geometry, material);
const dist = farDist / 3;
const distDouble = dist * 2;
const tau = 6 * Math.PI; // One turn
mesh.position.x = Math.random() * distDouble - dist;
mesh.position.y = Math.random() * distDouble - dist;
mesh.position.z = Math.random() * distDouble - dist;
mesh.rotation.x = Math.random() * tau;
mesh.rotation.y = Math.random() * tau;
mesh.rotation.z = Math.random() * tau;
// Manually control when 3D transformations recalculation occurs for better performance
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
group.add(mesh);
}
scene.add(group);
// CREATE TYPOGRAPHY
const loader = new THREE.FontLoader();
const textMesh = new THREE.Mesh();
const createTypo = font => {
const word = "";
const typoProperties = {
font: font,
size: cubeSize,
height: cubeSize / 2,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 6,
bevelOffset: 1,
bevelSegments: 8 };
const text = new THREE.TextGeometry(word, typoProperties);
textMesh.geometry = text;
textMesh.material = material;
textMesh.position.x = cubeSize * -2;
textMesh.position.z = cubeSize * -1;
scene.add(textMesh);
};
loader.load(
"https://threejs.org/examples/fonts/helvetiker_regular.typeface.json",
createTypo);
// CREATE PART OF THE MOUSE/TOUCH OVER EFFECT
let mouseX = 0;
let mouseY = 0;
const mouseFX = {
windowHalfX: window.innerWidth / 2,
windowHalfY: window.innerHeight / 2,
coordinates: function (coordX, coordY) {
mouseX = (coordX - mouseFX.windowHalfX) * 100;
mouseY = (coordY - mouseFX.windowHalfY) * 100;
},
onMouseMove: function (e) {
mouseFX.coordinates(e.clientX, e.clientY);
},
onTouchMove: function (e) {
mouseFX.coordinates(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
} };
document.addEventListener("mousemove", mouseFX.onMouseMove, false);
document.addEventListener("touchmove", mouseFX.onTouchMove, false);
// RENDER 3D GRAPHIC
const render = () => {
requestAnimationFrame(render);
// Camera animation
// Works with onMouseMove and onTouchMove functions
camera.position.x += (mouseX - camera.position.x) * 0.5;
camera.position.y += (mouseY * -1 - camera.position.y) * 0.5;
camera.lookAt(scene.position); // Rotates the object to face a point in world space
const t = Date.now() * 0.001;
const rx = Math.sin(t * 0.5) * 0.5;
const ry = Math.sin(t * 0.5) * 0.5;
const rz = Math.sin(t * 0.5) * 0.5;
group.rotation.x = rx;
group.rotation.y = ry;
group.rotation.z = rz;
textMesh.rotation.x = rx;
textMesh.rotation.y = ry;
textMesh.rotation.z = rx; // Happy accident :)
renderer.render(scene, camera);
};
render();
// RESIZE CANVAS
// This is buggy in some iOS...
// const resizeCanvas = () => {
// camera.aspect = window.innerWidth / window.innerHeight;
// camera.updateProjectionMatrix();
// renderer.setSize(window.innerWidth, window.innerHeight);
// };
// window.addEventListener("resize", resizeCanvas, false);
I'd really appreciate any sort of advice on how can I accomplish this.
So I've been trying to achieve the result that you can see on the pic.5 . How can flip the bottom shader upside down and change the background so that the particles would be bent inwards (concave cube shape is probably what I need)?
I also attach a link to a desired result.
I tried really hard to research how I can achieve that but to no success sadly.
Any help would be much appreciated! Thank you guys in advance and please feel free to ask any additional questions.
/*
Most of the stuff in here is just bootstrapping. Essentially it's just
setting ThreeJS up so that it renders a flat surface upon which to draw
the shader. The only thing to see here really is the uniforms sent to
the shader. Apart from that all of the magic happens in the HTML view
under the fragment shader.
*/
let container;
let camera, scene, renderer;
let uniforms;
let loader=new THREE.TextureLoader();
let texture;
loader.setCrossOrigin("anonymous");
loader.load(
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/982762/noise.png',
function do_something_with_texture(tex) {
texture = tex;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.minFilter = THREE.LinearFilter;
init();
animate();
}
);
function init() {
container = document.getElementById( 'container' );
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_noise: { type: "t", value: texture },
u_mouse: { type: "v2", value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
material.extensions.derivatives = true;
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
// renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener('pointermove', (e)=> {
let ratio = window.innerHeight / window.innerWidth;
uniforms.u_mouse.value.x = (e.pageX - window.innerWidth / 2) / window.innerWidth / ratio;
uniforms.u_mouse.value.y = (e.pageY - window.innerHeight / 2) / window.innerHeight * -1;
e.preventDefault();
});
}
function onWindowResize( event ) {
// renderer.setSize( 1000, 1000 );
renderer.setSize( window.innerWidth, window.innerHeight );
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
function animate(delta) {
requestAnimationFrame( animate );
render(delta);
}
let capturer = new CCapture( {
verbose: true,
framerate: 30,
// motionBlurFrames: 4,
quality: 90,
format: 'webm',
workersPath: 'js/'
} );
let capturing = false;
isCapturing = function(val) {
if(val === false && window.capturing === true) {
capturer.stop();
capturer.save();
} else if(val === true && window.capturing === false) {
capturer.start();
}
capturing = val;
}
toggleCapture = function() {
isCapturing(!capturing);
}
window.addEventListener('keyup', function(e) { console.log(e.keyCode); if(e.keyCode == 68) toggleCapture(); });
let then = 0;
function render(delta) {
uniforms.u_time.value = -11200 + delta * 0.0015;
renderer.render( scene, camera );
if(capturing) {
capturer.capture( renderer.domElement );
}
}
const nearDist = 0.1;
const farDist = 70000;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
100,
window.innerWidth / window.innerHeight,
nearDist,
farDist);
camera.position.x = farDist * -200;
camera.position.z = 5000;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor("BLACK"); // Backgrond Color - Blue
renderer.setPixelRatio(window.devicePixelRatio); // For HiDPI devices to prevent bluring output canvas
renderer.setSize(window.innerWidth, window.innerHeight);
document.querySelector("#canvas-wrapper").appendChild(renderer.domElement);
// CREATE CUBES
const cubeSize = 30;
const geometry = new THREE.BoxBufferGeometry(cubeSize, cubeSize, cubeSize); // BufferAttribute allows for more efficient passing of data to the GPU
const material = new THREE.MeshNormalMaterial(); // Maps the normal vectors to RGB colors
const group = new THREE.Group();
for (let i = 0; i < 500; i++) {
const mesh = new THREE.Mesh(geometry, material);
const dist = farDist / 3;
const distDouble = dist * 2;
const tau = 6 * Math.PI; // One turn
mesh.position.x = Math.random() * distDouble - dist;
mesh.position.y = Math.random() * distDouble - dist;
mesh.position.z = Math.random() * distDouble - dist;
mesh.rotation.x = Math.random() * tau;
mesh.rotation.y = Math.random() * tau;
mesh.rotation.z = Math.random() * tau;
// Manually control when 3D transformations recalculation occurs for better performance
mesh.matrixAutoUpdate = false;
mesh.updateMatrix();
group.add(mesh);
}
scene.add(group);
// CREATE TYPOGRAPHY
const loader = new THREE.FontLoader();
const textMesh = new THREE.Mesh();
const createTypo = font => {
const word = "";
const typoProperties = {
font: font,
size: cubeSize,
height: cubeSize / 2,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 6,
bevelOffset: 1,
bevelSegments: 8 };
const text = new THREE.TextGeometry(word, typoProperties);
textMesh.geometry = text;
textMesh.material = material;
textMesh.position.x = cubeSize * -2;
textMesh.position.z = cubeSize * -1;
scene.add(textMesh);
};
loader.load(
"https://threejs.org/examples/fonts/helvetiker_regular.typeface.json",
createTypo);
// CREATE PART OF THE MOUSE/TOUCH OVER EFFECT
let mouseX = 0;
let mouseY = 0;
const mouseFX = {
windowHalfX: window.innerWidth / 2,
windowHalfY: window.innerHeight / 2,
coordinates: function (coordX, coordY) {
mouseX = (coordX - mouseFX.windowHalfX) * 100;
mouseY = (coordY - mouseFX.windowHalfY) * 100;
},
onMouseMove: function (e) {
mouseFX.coordinates(e.clientX, e.clientY);
},
onTouchMove: function (e) {
mouseFX.coordinates(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
} };
document.addEventListener("mousemove", mouseFX.onMouseMove, false);
document.addEventListener("touchmove", mouseFX.onTouchMove, false);
// RENDER 3D GRAPHIC
const render = () => {
requestAnimationFrame(render);
// Camera animation
// Works with onMouseMove and onTouchMove functions
camera.position.x += (mouseX - camera.position.x) * 0.5;
camera.position.y += (mouseY * -1 - camera.position.y) * 0.5;
camera.lookAt(scene.position); // Rotates the object to face a point in world space
const t = Date.now() * 0.001;
const rx = Math.sin(t * 0.5) * 0.5;
const ry = Math.sin(t * 0.5) * 0.5;
const rz = Math.sin(t * 0.5) * 0.5;
group.rotation.x = rx;
group.rotation.y = ry;
group.rotation.z = rz;
textMesh.rotation.x = rx;
textMesh.rotation.y = ry;
textMesh.rotation.z = rx; // Happy accident :)
renderer.render(scene, camera);
};
render();
// RESIZE CANVAS
// This is buggy in some iOS...
// const resizeCanvas = () => {
// camera.aspect = window.innerWidth / window.innerHeight;
// camera.updateProjectionMatrix();
// renderer.setSize(window.innerWidth, window.innerHeight);
// };
// window.addEventListener("resize", resizeCanvas, false);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论