let todoList = {
'audio/music.ogg': 1636930,
'fonts/cookie.json': 37866,
- 'textures/cloud1.png': 32020,
- 'textures/cloud2.png': 32020,
- 'textures/cloud3.png': 32020,
- 'textures/cloud4.png': 32020,
- 'textures/cloud5.png': 32020,
- 'textures/feather.png': 27729,
- 'textures/pinwheel.png': 49345,
+ 'textures/cloud0a.png': 568,
+ 'textures/cloud0b.png': 569,
+ 'textures/cloud0c.png': 568,
+ 'textures/cloud1a.png': 6932,
+ 'textures/cloud1b.png': 6932,
+ 'textures/cloud1c.png': 6933,
+ 'textures/cloud2a.png': 4365,
+ 'textures/cloud2b.png': 4364,
+ 'textures/cloud2c.png': 4365,
+ 'textures/cloud3a.png': 4000,
+ 'textures/cloud3b.png': 3999,
+ 'textures/cloud3c.png': 4001,
+ 'textures/cloud4a.png': 3183,
+ 'textures/cloud4b.png': 3182,
+ 'textures/cloud4c.png': 3184,
+ 'textures/cloud5a.png': 2066,
+ 'textures/cloud5b.png': 2065,
+ 'textures/cloud5c.png': 2066,
+ 'textures/feather.png': 9196,
+ 'textures/pinwheel.png': 904,
'textures/windowsill-texture.png': 483119,
};
let total = Object.keys(todoList).map(k => todoList[k]).reduce((a, b) => a + b, 0);
scene.add(game.view.directionalLight2);
const renderer = new THREE.WebGLRenderer({ canvas: canvas });
renderer.setSize(canvas.width, canvas.height);
- renderer.setClearColor(0xb7bff5, 1);
+ renderer.setClearColor(0x808080, 1);
game.view.clock = new THREE.Clock();
game.view.clock.previousTime = 0;
game.view.clock.getDeltaTime = () => {
}
game.objects.clouds = [];
- const cloudGeometry = new THREE.PlaneGeometry(1, 0.654);
- const cloudMaterials = [];
- for(let i = 1; i <= 5; i++) {
- cloudMaterials.push(
- new THREE.MeshPhongMaterial({
- map: game.assets.textures['cloud' + i],
- transparent: true,
- alphaTest: 0.5,
- })
- );
+ const cloudGeometry = new THREE.PlaneGeometry(1, 200 / 350);
+ const cloudShaders = {
+ vertexShader:
+ `
+ precision highp float;
+ precision highp int;
+ varying vec2 vUv;
+ void main() {
+ vUv = uv;
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+ }
+ `,
+ fragmentShader:
+ `
+ precision mediump float;
+ uniform sampler2D texture1;
+ uniform sampler2D texture2;
+ uniform sampler2D texture3;
+ uniform float lerp;
+ varying vec2 vUv;
+ void main() {
+ if(lerp > 1.0) {
+ vec4 col1 = texture2D(texture2, vUv);
+ vec4 col2 = texture2D(texture3, vUv);
+ gl_FragColor = mix(col1, col2, lerp - 1.0);
+ } else {
+ vec4 col1 = texture2D(texture1, vUv);
+ vec4 col2 = texture2D(texture2, vUv);
+ gl_FragColor = mix(col1, col2, lerp);
+ }
+ // I don't know how GLSL works: why do I need to do this to match the textures?
+ gl_FragColor = mix(gl_FragColor, vec4(1.0, 1.0, 1.0, gl_FragColor.a), 0.5);
+ }
+ `
+ };
+ game.view.materials = {};
+ for(let i = 0; i < 6; i++) {
+ game.view.materials['cloud' + i] = new THREE.ShaderMaterial({
+ uniforms: THREE.UniformsUtils.merge([{
+ texture1: null,
+ texture2: null,
+ texture3: null,
+ lerp: null,
+ }]),
+ ...cloudShaders,
+ });
+ game.view.materials['cloud' + i].uniforms.texture1.value = game.assets.textures['cloud' + i + 'a'];
+ game.view.materials['cloud' + i].uniforms.texture2.value = game.assets.textures['cloud' + i + 'b'];
+ game.view.materials['cloud' + i].uniforms.texture3.value = game.assets.textures['cloud' + i + 'c'];
+ game.view.materials['cloud' + i].uniforms.lerp.value = 0.0;
+ game.view.materials['cloud' + i].transparent = true;
}
+ game.objects.backdrop = new THREE.Mesh(new THREE.PlaneGeometry(350, 350), game.view.materials['cloud0']);
+ game.objects.backdrop.position.setZ(-100);
+ scene.add(game.objects.backdrop);
for(let i = 0; i < 300; i++) {
let randomAngle = Math.random() * 2 * Math.PI;
let randomCameraX = game.courseRadius * Math.sin(randomAngle);
let randomCameraY = game.courseRadius * Math.cos(randomAngle);
- let cloud = new THREE.Mesh(cloudGeometry, cloudMaterials[0 + i % 5]);
+ let cloud = new THREE.Mesh(cloudGeometry, game.view.materials['cloud' + (i % 5 + 1)]);
cloud.position.z = -10 - Math.round(Math.random() * 40);
const vFOV = THREE.MathUtils.degToRad(game.view.camera.fov);
cloud.maxCameraDistance = 2 * Math.tan(vFOV / 2) * Math.abs(cloud.position.z - game.view.camera.position.z);
game.view.camera.position.x = game.courseRadius * Math.sin(angle);
game.view.camera.position.y = - game.courseRadius * Math.cos(angle);
- game.view.ambientLight.color.lerpColors(lightStartColor, lightStartColor, game.timeProgress / game.timeTotal);
+ const sunsetValue = 2.0 * easeInOut(Math.min(1, Math.max(0, ((game.timeProgress / game.timeTotal) - 0.3) / 0.6)));
+ for(let i = 0; i < 6; i++) {
+ game.view.materials['cloud' + i].uniforms.lerp.value = sunsetValue;
+ }
featherLocalPos.subVectors(game.objects.feather.position, game.view.camera.position).setZ(0);
if(featherLocalPos.y > 3) {