问题描述
我使用three.js和着色器为图像创建了一个简单的效果。这是link
现在我有一个疑问,我将如何在网站上使用它,例如,采用这种布局,其中蓝色块是应具有此效果的图像。
我在Google上四处搜寻,但真的找不到任何东西。
因为整个场景都是一个画布,并且我需要多个图像,所以我会想象该画布应该保持原样,但是如何将图像放置在正确的位置?
<script id="vertex" type="x-shader/x-vertex">
varying float wave;
varying vec2 vUv;
uniform float mouseIntersects;
void main() {
vUv = uv;
vec3 pos = position;
pos.z += -mouseIntersects / 20.0;
wave = pos.z;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0 );
}
</script>
<script id="fragment" type="x-shader/x-vertex">
uniform vec2 u_resolution;
uniform float u_time;
varying vec2 vUv;
varying float wave;
uniform sampler2D uTexture;
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
float r = texture2D(uTexture,vUv + wave).r;
float g = texture2D(uTexture,vUv).g;
float b = texture2D(uTexture,vUv).b;
vec4 image = vec4(r,g,b,1.0);
gl_FragColor = image;
}
</script>
<div id="container"></div>
</body>
和three.js部分:
import { OrbitControls } from "https://threejsfundamentals.org/threejs/resources/threejs/r110/examples/jsm/controls/OrbitControls.js";
let container,camera,scene,renderer,controls,material,uniforms,geometry,mesh,raycaster;
const setup = () => {
scene = new THREE.Scene();
renderer = new THREE.Webglrenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth,window.innerWidth);
renderer.setClearColor(0xffffff);
container = document.getElementById('container');
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70,window.innerWidth / window.innerHeight,0.001,100);
camera.position.set(0,0.5);
controls = new OrbitControls(camera,renderer.domElement);
uniforms = {
u_time: { type: 'f',value: 0 },u_mouse: { type: 'v2',value: new THREE.Vector2() },u_resolution: { type: 'v2',value: new THREE.Vector2(window.innerWidth,window.innerHeight) },uTexture: { type: 't',value: new THREE.TextureLoader().load('https://images.unsplash.com/photo-1512505965932-0dbfa7e7b8c8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=701&q=80') },mouseIntersects: { type: 'f',};
material = new THREE.ShaderMaterial({
side: THREE.DoubleSide,uniforms: uniforms,// wireframe: true,vertexShader: document.querySelector("#vertex").textContent,fragmentShader: document.querySelector("#fragment").textContent
});
geometry = new THREE.PlaneBufferGeometry(0.4,0.6,16,16);
mesh = new THREE.Mesh(geometry,material);
raycaster = new THREE.Raycaster();
scene.add(mesh);
onWindowResize();
window.addEventListener('resize',onWindowResize,false);
document.addEventListener('mousemove',(e) => updateMousePositions(e),false);
};
const updateMousePositions = (e) => {
uniforms.u_mouse.value.x = (event.clientX / window.innerWidth) * 2 - 1;
uniforms.u_mouse.value.y = -(event.clientY / window.innerHeight) * 2 + 1;
};
const onWindowResize = (event) => {
renderer.setSize(window.innerWidth,window.innerHeight);
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
};
const animate = () => {
requestAnimationFrame(animate);
render();
};
let targetValue = 0;
const render = () => {
uniforms.u_time.value += 0.05;
raycaster.setFromCamera(uniforms.u_mouse.value,camera);
const intersects = raycaster.intersectObject(mesh);
if (intersects.length === 1) {
targetValue = 1;
} else {
targetValue = 0;
}
uniforms.mouseIntersects.value = THREE.MathUtils.lerp(
uniforms.mouseIntersects.value,targetValue,0.1,);
renderer.render(scene,camera);
};
setup();
animate();
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)