<html>
	<head>
		<title>GLSL shaders</title>
	</head>
	<body>
		
	</body>
</html>
body { margin: 0; }
canvas { width: 100%; height: 100% }
const vshader = `
#include <noise>

uniform float uTime;

varying float vNoise;

void main() {	
  // add time to the noise parameters so it's animated
  vNoise = 10.0 *  -.10 * turbulence( .5 * normal + uTime );
  float b = 5.0 * pnoise( 0.05 * position + vec3( 2.0 * uTime ), vec3( 100.0 ) );
  float displacement = - 10. * vNoise + b;

  // move the position along the normal and transform it
  vec3 pos = position + normal * displacement;

  gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );
}
`
const fshader = `
uniform sampler2D uTex;

varying float vNoise;

//https://www.clicktorelease.com/blog/vertex-displacement-noise-3d-webgl-glsl-three-js/

float random( vec3 pt, float seed ){
  vec3 scale = vec3( 12.9898, 78.233, 151.7182 );
  return fract( sin( dot( pt + seed, scale ) ) * 43758.5453 + seed ) ;
}

void main() {

  // get a random offset
  float r = .01 * random( gl_FragCoord.xyz, 0.0 );
  // lookup vertically in the texture, using noise and offset
  // to get the right RGB colour
  vec2 uv = vec2( 0, 1.3 * vNoise + r );
  vec3 color = texture2D( uTex, uv ).rgb;

  gl_FragColor = vec4( color, 1.0 );
}
`






const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    10000
  );
camera.position.z = 100;

const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

const clock = new THREE.Clock();

const geometry = new THREE.IcosahedronGeometry( 20, 4 );
const uniforms = {
  uTime: { value: 0.0 },
  uTex: { value: new THREE.TextureLoader().load("https://s3-us-west-2.amazonaws.com/s.cdpn.io/2666677/explosion.png")}
}

const material = new THREE.ShaderMaterial( {
  uniforms: uniforms,
  vertexShader: vshader,
  fragmentShader: fshader
} );

const ball = new THREE.Mesh( geometry, material );
scene.add( ball );

const controls = new THREE.OrbitControls(camera, renderer.domElement);

onWindowResize();

window.addEventListener( 'resize', onWindowResize, false );

update();

function onWindowResize( event ) {
  camera.aspect = window.innerWidth/window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize( window.innerWidth, window.innerHeight );
}

function update() {
  requestAnimationFrame( update );
  uniforms.uTime.value += clock.getDelta();
  renderer.render( scene, camera );
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.min.js
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/2666677/OrbitControls.js
  3. https://s3-us-west-2.amazonaws.com/s.cdpn.io/2666677/MyShaderChunks.js