canvas{
  position: absolute;
  margin: auto;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
View Compiled
// シェーダーの作成

const vertexSrc = `
precision mediump float;

attribute vec4 position;
attribute vec2 uv;

varying vec2 vUv;

void main() {
	gl_Position = position;
	vUv = vec2( (position.x + 1.)/2., (-position.y + 1.)/2.);
}
`

const fragmentSrc = `
precision mediump float;

uniform float uTrans;
uniform sampler2D uTexture0;
uniform sampler2D uTexture1;
uniform sampler2D uDisp;

varying vec2 vUv;

float quarticInOut(float t) {
  return t < 0.5
    ? +8.0 * pow(t, 4.0)
    : -8.0 * pow(t - 1.0, 4.0) + 1.0;
}

void main() {
	// https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_FragCoord.xhtml
	
	vec4 disp = texture2D(uDisp, vec2(0., 0.5) + (vUv - vec2(0., 0.5)) * (0.2 + 0.8 * (1.0 - uTrans)) );
	float trans = clamp(1.6  * uTrans - disp.r * 0.4 - vUv.x * 0.2, 0.0, 1.0);
	trans = quarticInOut(trans);
	vec4 color0 = texture2D(uTexture0, vec2(0.5 - 0.3 * trans, 0.5) + (vUv - vec2(0.5)) * (1.0 - 0.2 * trans));
	vec4 color1 = texture2D(uTexture1, vec2(0.5 + sin( (1. - trans) * 0.1), 0.5 ) + (vUv - vec2(0.5)) * (0.9 + 0.1 * trans));


	gl_FragColor = mix(color0, color1 , trans);
}
`;

// デモに使用する画像URL
const assetUrls = [
	'https://s3-us-west-2.amazonaws.com/s.cdpn.io/13842/water.jpg',
	'https://s3-us-west-2.amazonaws.com/s.cdpn.io/13842/water2.jpg',
	'https://s3-us-west-2.amazonaws.com/s.cdpn.io/13842/disp.jpg'
];

/**
** 初期化開始
*/

// レンダラーの初期化
let renderer = new THREE.WebGLRenderer();
let canvas = renderer.domElement;
document.body.appendChild( canvas );

let scene = new THREE.Scene();

let obj = {trans: 0}
var cnt = 0;

let textureArr = [];

// カメラの初期化
let camera = new THREE.OrthographicCamera( -1, 1, 1, -1, 1, 1000  );
camera.position.z = 1;

// テクスチャの初期化
assetUrls.forEach( (url, index) =>{
	let img = new Image();
	
	let texture = new THREE.Texture();
	texture.flipY= false;
	textureArr.push(texture);
	
	img.onload = function(_index, _img){
		let texture = textureArr[_index];
		texture.image = _img;
		texture.needsUpdate = true;
		
		cnt++;
		if(cnt == 3) start();
	}.bind(this, index, img);
	
	img.crossOrigin = "Anonymous";
	img.src = url;
})

let mat = new THREE.RawShaderMaterial( {
	uniforms: {
		uTrans: { value: obj.trans },
		uTexture0: {value: textureArr[0]},
		uTexture1: {value: textureArr[1]},
		uDisp: {value: textureArr[2]},
	},
	vertexShader: vertexSrc,
	fragmentShader: fragmentSrc
} );

let geo = new THREE.PlaneGeometry(2, 2);
let mesh = new THREE.Mesh(geo, mat)
scene.add(mesh);

resize();

function start(){
	loop();
}

function loop(){
	mat.uniforms.uTrans.value = obj.trans;
	renderer.render(scene, camera);
	
	requestAnimationFrame(loop);
}

function resize(){
	let size = Math.min(window.innerWidth, window.innerHeight) * 0.8;
	if(size > 450)  size = 450;
	renderer.setSize(size, size);
}

window.addEventListener("resize", function() {
    resize();
});

canvas.addEventListener('mouseenter', function(){
	TweenMax.killTweensOf(obj);
	TweenMax.to(obj, 1.5, {trans: 1});
});

canvas.addEventListener('mouseleave', function(){
	TweenMax.killTweensOf(obj);
	TweenMax.to(obj, 1.5, {trans: 0});
});
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.1/TweenMax.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.min.js