Skip to content

Instantly share code, notes, and snippets.

@Ripley6811
Last active December 23, 2015 23:19
Show Gist options
  • Save Ripley6811/6709628 to your computer and use it in GitHub Desktop.
Save Ripley6811/6709628 to your computer and use it in GitHub Desktop.
Demo of using a animated canvas element as a texture on a webgl (Three.js) object surface.
"use strict";
// Create a class that draws to a canvas.
function BurningPlain(canvas) {
this.w = canvas.width;
this.h = canvas.height;
this.ctx = canvas.getContext("2d");
// Draw buffer
var buffer = this.buffer = document.createElement('canvas');
buffer.width = canvas.width;
buffer.height = canvas.height;
buffer.style.visibility='hidden';
this.bufferCtx = buffer.getContext('2d');
var N_TRACERS = this.N_TRACERS = 50;
var arrayBuffer = new ArrayBuffer(8*N_TRACERS); // bytes
this.bugCoords = new Float32Array(arrayBuffer);
function Tracer(x,y,index){
this.x = new Float32Array(arrayBuffer, index*8, 1);
this.y = new Float32Array(arrayBuffer, index*8+4, 1);
this.vx = Math.floor(Math.random() * 2)-0.5;
this.vy = 1;
this.color = "#5f5";
this.x[0] = x;
this.y[0] = y;
}
Tracer.prototype.onTick = function() {
this.wrap();
//this.color = "#5FA";
this.y[0] += this.vy*2;
this.x[0] += this.vx*2;
}
Tracer.prototype.wrap = function() {
if (this.y[0] > canvas.height & this.vy > 0) {
this.y[0] = 0;
}
else if (this.y[0] < 0 & this.vy < 0) {
this.y[0] = canvas.height;
}
if (this.x[0] > canvas.width & this.vx > 0) {
this.x[0] = 0;
}
else if (this.x[0] < 0 & this.vx < 0) {
this.x[0] = canvas.width;
}
}
this.tracers = [];
for (var i = 0; i < N_TRACERS; i++){
var reverse = true;
if (i % 2 === 0) reverse = false;
this.tracers.push(new Tracer(Math.random()*canvas.width,Math.random()*5,i));
}
};
// tick handler.
BurningPlain.prototype.tick = function (e) {
var ctx = this.ctx;
ctx.fillStyle = "rgba(0,0,0,0.03)";
ctx.rect(0,0,this.w,this.h);
ctx.fill();
//Clear buffer
this.bufferCtx.clearRect(0, 0, this.w, this.h);
ctx.fillStyle = '#FAB';
for (var i = 0; i < this.tracers.length; i++){
this.tracers[i].onTick();
}
for (var i = 0; i < this.N_TRACERS; i++){
ctx.beginPath();
ctx.fillStyle = this.tracers[i].color;
//fillRect and "flooring" force drawing to single pixel.
//Using fillRect instead of rect improves performance.
ctx.fillRect(~~this.bugCoords[i*2], ~~this.bugCoords[i*2+1], 2, 2);
ctx.fill();
}
};
<!DOCTYPE html>
<meta charset=utf-8>
<title>DEMO</title>
<!-- Load Three.js library. -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r58/three.min.js"></script>
<body>
<script src="burningPlain.js"></script>
<script src="webgl.js"></script>
"use strict";
var width = document.body.clientWidth;
var height = document.body.clientHeight || 700;
console.log(width, height);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width,height);
document.body.appendChild(renderer.domElement);
renderer.setClearColor("#001500", 1.0);
renderer.clear();
//CREATE A CAMERA
var camera = new THREE.PerspectiveCamera(45, width/height, 1, 2000);
camera.position.z = 300;
//MAKE A SCENE WITH A CUBE
var scene = new THREE.Scene();
var pMat = new THREE.ParticleBasicMaterial({
vertexColors: true,
size:5,
transparent: true
});
var particles = new THREE.Geometry();
for(var i = 0; i < 4; i++){
particles.vertices.push(new THREE.Vector3(0,0,0));
particles.colors.push(new THREE.Color(0x559955));
}
var particleSystem = new THREE.ParticleSystem(particles,pMat);
console.log(particles);
scene.add(particleSystem);
//var scene = new THREE.Scene();
var litcube = new THREE.Mesh(
new THREE.CubeGeometry(70,70,70),
new THREE.MeshLambertMaterial({color: "rgb(25,255,25)"})
);
//litcube.position.y = 25;
//litcube.position.x = 25;
litcube.position.z = 50;
scene.add(litcube);
var light = new THREE.SpotLight();
light.position.set(160,330,-160);
scene.add(light);
// enable shadows on the renderer
renderer.shadowMapEnabled = true;
// enable shadows for a light
light.castShadow = true;
// enable shadows for an object
litcube.castShadow = true;
litcube.receiveShadow = true;
var xx = 0;
//RENDER SCENE
renderer.render(scene, camera);
camera.position.x = 0;//Math.sin(t/1000)*300;
camera.position.y = 0;
camera.position.z = -400;//Math.cos(t/1000)*300;
//update lookAt on every frame
camera.lookAt(scene.position);
// create a canvas element
var canvas1 = document.createElement('canvas');
canvas1.width = 1210;
canvas1.height = 1277;
var burningPlain = new BurningPlain(canvas1)
// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;
var material1 = new THREE.MeshBasicMaterial( {map: texture1, side:THREE.DoubleSide } );
material1.transparent = true;
var mesh1 = new THREE.Mesh(
//new THREE.PlaneGeometry(canvas1.width, canvas1.height),
new THREE.CylinderGeometry(150,150,1000,100,100,true),
material1
);
mesh1.position.set(0,0,600);
mesh1.rotation.x = Math.PI/2;
mesh1.receiveShadow = true;
scene.add( mesh1 );
console.log(canvas1.width, canvas1.height);
var xx = 0;
console.log(particles.vertices[0]);
function animate(t){
burningPlain.tick();
mesh1.position.z -= .1;
mesh1.rotation.y += .001;
//spin the camera
particleSystem.rotation = litcube.rotation;
particleSystem.position = litcube.position;
var radAmp = 60;
var p = particles.vertices[0];
p.x = Math.cos(xx)*radAmp;
p.y = Math.sin(xx)*radAmp;
p.z = Math.cos(xx)*radAmp;
var p = particles.vertices[1];
p.x = Math.sin(xx)*radAmp;
p.y = Math.cos(xx)*radAmp;
p.z = Math.sin(xx)*radAmp;
var p = particles.vertices[2];
p.x = Math.sin(xx+1.3)*radAmp;
p.y = Math.sin(xx+1.4)*radAmp;
p.z = Math.cos(xx+1.5)*radAmp;
var p = particles.vertices[3];
p.x = Math.sin(xx+2)*radAmp;
p.y = Math.sin(xx-2)*radAmp;
p.z = Math.cos(xx+2)*radAmp;
xx += 0.1;
litcube.rotation.x = t/500;
litcube.rotation.y = t/700;
litcube.rotation.z = t/1700;
//These are set to false after executing render update
particleSystem.geometry.verticesNeedUpdate = true;
texture1.needsUpdate = true;
renderer.render(scene,camera);
window.requestAnimationFrame(animate,renderer.domElement);
}
animate(new Date().getTime());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment