Last active
December 23, 2015 23:19
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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(); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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