Animating ThreeJS ShaderMaterial Uniforms
by realhunts
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.js"></script>
<script id="fragmentShader" type="x-shader/x-fragment">
attribute vec3 barycentric;
uniform float frame;
uniform vec2 resolution;
varying vec3 vBarycentric;
varying vec2 vUv;
void main( void ) {
vec2 position = -1.0 + 2.0 * vUv;
float red = abs( sin( position.x * position.y + frame / 5.0 ) );
float green = abs( sin( position.x * position.y + frame / 4.0 ) );
float blue = abs( sin( position.x * position.y + frame / 3.0 ) );
gl_FragColor = vec4( red, green, blue, 1.0 );
}
</script>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv;
void main()
{
vUv = uv;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
}
</script>
<div id="container"></div>
JavaScript
var container, stats;
var camera, scene, renderer, mesh, mixer;
var uniforms1, uniforms2;
var clock = new THREE.Clock();
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 3000 );
camera.position.z = 4;
scene = new THREE.Scene();
var geometry = new THREE.BoxBufferGeometry( 0.75, 0.75, 0.75 );
uniforms1 = {
frame: { value: 1.0 },
resolution: { value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms1,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
const attrib = geometry.getIndex()// || bufferGeometry.getAttribute('position');
const count = attrib.count / 3;
const barycentric = [];
// for each triangle in the geometry, add the barycentric coordinates
var removeEdge = true
for (let i = 0; i < count; i++) {
const even = i % 2 === 0;
const Q = removeEdge ? 1 : 0;
if (even) {
barycentric.push(
0, 0, 1,
0, 1, 0,
1, 0, Q
);
} else {
barycentric.push(
0, 1, 0,
0, 0, 1,
1, 0, Q
);
}
}
// add the attribute to the geometry
const array = new Float32Array(barycentric);
const attribute = new THREE.BufferAttribute(array, 3);
geometry.addAttribute('barycentric', attribute);
mesh = new THREE.Mesh( geometry, material );
mesh.materialDotUniformsDotFrame = material.uniforms.frame;
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize( event ) {
uniforms1.resolution.value.x = window.innerWidth;
uniforms1.resolution.value.y =...