Skip to content

Instantly share code, notes, and snippets.

@shshaw
Last active December 8, 2016 19:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shshaw/c2bfbc9287b746248fc31ea1e02c40d5 to your computer and use it in GitHub Desktop.
Save shshaw/c2bfbc9287b746248fc31ea1e02c40d5 to your computer and use it in GitHub Desktop.
Warm up by the Fire (#3December - Day 8)
console.clear();
var scene, camera, renderer, orbit, light;
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x242426, 20, 400);
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 10, 400 );
camera.position.z = 100;
camera.position.y = 30;
camera.position.x = 10;
camera.updateProjectionMatrix();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x242426 );
renderer.toneMapping = THREE.LinearToneMapping;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
window.addEventListener( 'resize', function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false );
document.body.appendChild( renderer.domElement );
/*////////////////////////////////////////*/
orbit = new THREE.OrbitControls( camera, renderer.domElement );
orbit.enableZoom = true;
orbit.enablePan = false;
orbit.rotateSpeed = 0.3;
orbit.zoomSpeed = 0.3;
//orbit.autoRotate = true;
//orbit.autoRotateSpeed = 0.3;
orbit.minPolarAngle = Math.PI * 0.3;
orbit.maxPolarAngle = Math.PI * 0.42;
orbit.minAzimuthAngle = -Math.PI * 0.2; // radians
orbit.maxAzimuthAngle = Math.PI * 0.2; // radians
orbit.minDistance = 60;
orbit.maxDistance = 120;
/*////////////////////////////////////////*/
var ambientLight = new THREE.AmbientLight(0x222222);
scene.add(ambientLight);
let hemiLight = new THREE.HemisphereLight( 0xEBF7FD, 0xEBF7FD, 0.2 );
//hemiLight.color.setRGB(0.75,0.8,0.95);
hemiLight.position.set( 0, 100, 0 );
scene.add( hemiLight );
/*////////////////////////////////////////*/
function noiseMap(size,intensity){
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d'),
width = canvas.width = size || 512,
height = canvas.height = size || 512;
intensity = intensity || 120;
var imageData = ctx.getImageData(0, 0, width, height),
pixels = imageData.data,
n = pixels.length,
i = 0;
while (i < n) {
pixels[i++] = pixels[i++] = pixels[i++] = Math.sin( i * i * i + (i/n) * Math.PI) * intensity;
pixels[i++] = 255;
}
ctx.putImageData(imageData, 0, 0);
let sprite = new THREE.Texture(canvas);
sprite.needsUpdate = true;
return sprite;
}
let noise = noiseMap(512,60);
/*////////////////////////////////////////*/
let buildingMaterial = new THREE.MeshPhongMaterial({
color: 0x283739, //EBF7FD,
shininess: 10,
});
var loader = new THREE.ColladaLoader();
loader.options.convertUpAxis = true;
loader.load( 'http://codepen.io/shshaw/pen/mOKMzM.html', function ( collada ) {
dae = collada.scene.children[0];
dae.scale.x = dae.scale.y = dae.scale.z = 0.5;
dae.traverse(( child ) => {
if ( child.material ) {
child.material = buildingMaterial;
child.receiveShadow = true;
child.castShadow = true;
child.updateMatrix();
}
});
dae.updateMatrix();
scene.add(dae);
/*////////////////////////////////////////*/
let floorGeometry = new THREE.PlaneGeometry( 235, 235, 1, 1 );
let floorMaterial = buildingMaterial.clone();
floorMaterial.shininess = 100;
floorMaterial.bumpMap = noise;
floorMaterial.bumpScale = 0.025;
floorMaterial.metalness = 0.2;
floorMaterial.side = THREE.DoubleSide;
let floor = new THREE.Mesh( floorGeometry, floorMaterial );
floor.rotation.x = Math.PI / -2;
floor.position.z = -120;
floor.receiveShadow = true;
floor.castShadow = true;
dae.add( floor );
let ceiling = new THREE.Mesh( floorGeometry, floorMaterial );
ceiling.rotation.x = Math.PI / -2;
ceiling.position.z = -120;
ceiling.position.y = 120;
ceiling.receiveShadow = true;
dae.add( ceiling );
// let ceiling = floor.clone();
// ceiling.position.y = 119;
// dae.add( ceiling );
/*////////////////////////////////////////*/
fire = new Fire();
dae.add(fire);
fire.position.x = -106;
fire.position.y = 20;
fire.position.z = -122;
let tree = new Tree();
tree.position.x = 80;
tree.position.y = 2;
tree.position.z = -35;
tree.scale.set(3.5,3.5,3.5);
dae.add(tree);
});
/*////////////////////////////////////////*/
// Fire lighting
let fire;
//var gui = new dat.GUI();
//let l = 0;
function makeLight(color){
var light = new THREE.PointLight( color || 0xFFFFFF , 1, 0 );
light.castShadow = true;
light.shadow.mapSize.width = 1024;
light.shadow.mapSize.height = 1024;
light.shadow.camera.near = 0.1;
light.shadow.camera.far = 100;
light.shadow.bias = 0.9;
light.shadow.radius = 5;
light.power = 45;
// var sphereSize = 20;
// var pointLightHelper = new THREE.PointLightHelper( light, sphereSize );
// light.add( pointLightHelper );
return light;
}
function Fire(){
THREE.Group.apply(this,arguments);
this.add( makeLight(0xdb2902) );
this.add( makeLight(0xfb4402) );
let yellowLight = makeLight(0xff882d);
yellowLight.position.x = 68;
yellowLight.position.y = 60;
//yellowLight.position.z = 70;
//yellowLight.intensity = 0.8;
yellowLight.power = 13;
this.add( yellowLight );
}
Fire.prototype = Object.assign(THREE.Group.prototype, {
constructor: Fire,
flicker(count){
let i = 1;
this.traverse( (child) => {
child.position.y += Math[ i % 2 ? 'sin' : 'cos' ]( count + i + Math.random() ) * 0.01;
child.position.x += Math[ i % 2 ? 'sin' : 'cos' ]( count * 2 + i + Math.random() ) * 0.005;
child.position.z += Math[ i % 2 ? 'cos' : 'sin' ]( count + i + Math.random() ) * 0.005;
child._power = child._power || child.power;
let min = child._power * 0.1;
child.power = child._power + min * (Math.sin( i + count + (Math.random() > 0.9 ? 0.2 : 0) )+1/2 );
//child.intensity = 0.6 + 0.4 * Math.cos( i + count )+1/2;
i++;
})
}
});
/*////////////////////////////////////////*/
// TREE
let treeMaterial = new THREE.MeshPhongMaterial( {
color: 0x2C9E4B,
shininess: 20,
//bumpMap: noiseMap(256, 5),
//bumpScale: 0.5,
side: THREE.FrontSide,
shading: THREE.SmoothShading
});
function Cone(size, translate){
size = size || 10;
this.geometry = new THREE.CylinderGeometry( size / 2, size, size, 6 );
if ( translate ) {
this.geometry.applyMatrix( new THREE.Matrix4().makeTranslation(0, size, 0) );
}
THREE.Mesh.call(this, this.geometry, treeMaterial);
}
Cone.prototype = Object.assign(THREE.Mesh.prototype,{
constructor: Cone,
});
function Tree(size) {
size = size || 6 + Math.random();
THREE.Object3D.call(this);
let lastCone;
let cone;
for (let i = 0; i < size; i++) {
cone = new Cone( (size - i) + 1, i);
cone.position.y = 0;
if ( lastCone ) {
let box = new THREE.Box3().setFromObject( lastCone );
cone.position.y = (box.max.y + box.min.y) / 2;
} else {
cone.position.y += 2;
}
lastCone = cone;
cone.castShadow = true;
cone.receiveShadow = true;
this.add( cone );
}
};
Tree.prototype = Object.assign(THREE.Object3D.prototype,{
constructor: Tree,
});
/*////////////////////////////////////////*/
// OUTSIDE GROUND
function snowyGround(){
let geometry = new THREE.PlaneGeometry( 130, 100, 15, 10 );
for (let i = 0; i < geometry.vertices.length; i++) {
//if ( geometry.vertices[i].y < 0 ) {
geometry.vertices[i].z = (Math.sin(i * i)+1/2) * 2; //(Math.random() - 0.5) * 10;
//}
}
geometry.verticesNeedUpdate = true;
geometry.normalsNeedUpdate = true;
geometry.computeFaceNormals();
let material = new THREE.MeshPhongMaterial({
color: 0xFFFFFF,
shininess: 60,
//metalness: 1,
//specularMap: noiseMap(512,255),
bumpMap: noise,
bumpScale: 0.025,
//emissive: 0xEBF7FD,
//emissiveIntensity: 0.05,
shading: THREE.SmoothShading
});
let plane = new THREE.Mesh( geometry, material );
plane.rotation.x = Math.PI / -2;
plane.position.z = 50;
plane.position.y = 5;
//plane.castShadow = true;
plane.receiveShadow = true;
return plane;
}
scene.add( snowyGround() );
//scene.position.z = -40;
/*////////////////////////////////////////*/
// FALLING SNOW
const PI2 = Math.PI * 2;
function makeSprite(){
let canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
let spriteSize = 4;
canvas.width = canvas.height = spriteSize * 2;
ctx.fillStyle = '#FFF';
ctx.beginPath();
ctx.arc( spriteSize, spriteSize, spriteSize, 0, PI2, true );
ctx.fill();
let sprite = new THREE.Texture(canvas);
sprite.needsUpdate = true;
return sprite;
}
function pointsParticles(){
let pointGeometry = new THREE.Geometry();
for ( i = 0; i < 160; i ++ ) {
var vertex = new THREE.Vector3();
vertex.x = Math.random() * 120 - 60;
vertex.y = Math.random() * 100;
vertex.z = Math.random() * 100;
pointGeometry.vertices.push( vertex );
}
pointGeometry.verticesNeedUpdate = true;
pointGeometry.normalsNeedUpdate = true;
pointGeometry.computeFaceNormals();
let pointMaterial = new THREE.PointsMaterial( {
//size: 16,
map: makeSprite(),
blending: THREE.AdditiveBlending,
depthTest: true,
transparent : true,
opacity: 0.2,
});
let particles = new THREE.Points( pointGeometry, pointMaterial );
scene.add(particles);
console.log( particles.geometry );
let count = 0;
return function(){
count += 0.01;
particles.geometry.vertices.forEach( (vertex, i) => {
vertex.x += Math.sin(count + i) * 0.05;
vertex.y -= 0.2;
if ( vertex.y < 0 ) { vertex.y = 100; }
});
particles.geometry.verticesNeedUpdate = true;
}
}
let updateParticles = pointsParticles();
/*////////////////////////////////////////*/
// BLOOM
var params = {
projection: 'normal',
background: false,
exposure: 0.91,
bloomStrength: 0.6,
bloomThreshold: 0.6,
bloomRadius: 0.6
};
// renderScene.clear = true;
let effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight );
var copyShader = new THREE.ShaderPass(THREE.CopyShader);
copyShader.renderToScreen = true;
bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85);//1.0, 9, 0.5, 512);
composer = new THREE.EffectComposer(renderer);
composer.setSize(window.innerWidth, window.innerHeight);
composer.addPass(new THREE.RenderPass(scene, camera));
composer.addPass(effectFXAA);
composer.addPass(bloomPass);
composer.addPass(copyShader);
//renderer.toneMapping = THREE.ReinhardToneMapping;
renderer.gammaInput = true;
renderer.gammaOutput = true;
/*////////////////////////////////////////*/
let count = 3;
function render () {
requestAnimationFrame( render );
count += 0.03;
if ( updateParticles ) { updateParticles(count); }
if ( fire && fire.flicker ) { fire.flicker(count); }
// scene.traverse( (child) => {
// if ( child.material ) { child.material.needsUpdate = true; }
// });
renderer.toneMappingExposure = Math.pow( params.exposure, 5.0 );
if ( window.innerWidth > 500 ) {
composer.render();
} else {
renderer.render( scene, camera );
}
};
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="http://codepen.io/shshaw/pen/epmrgO"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/ColladaLoader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/EffectComposer.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/RenderPass.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/MaskPass.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/ShaderPass.js"></script>
<script src="https://threejs.org/examples/js/shaders/CopyShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/FXAAShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/ConvolutionShader.js"></script>
<script src="https://threejs.org/examples/js/shaders/LuminosityHighPassShader.js"></script>
<script src="https://threejs.org/examples/js/postprocessing/UnrealBloomPass.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.1/dat.gui.min.js"></script>
canvas { display: block; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment