@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
208 lines (170 loc) • 4.62 kB
JavaScript
import { RepeatWrapping, TextureLoader } from "three";
import Vector2 from '../../../core/geom/Vector2.js';
const texture_cache = new Map();
/**
*
* @param {string} url
* @returns {Texture}
*/
function loadCloudTexture(url) {
const existing = texture_cache.get(url);
if (existing !== undefined) {
return existing;
}
const textureLoader = new TextureLoader();
const t = textureLoader.load(url);
t.wrapS = RepeatWrapping;
t.wrapT = RepeatWrapping;
t.repeat.set(1, 1);
texture_cache.set(url, t);
return t;
}
class Clouds {
/**
*
* @type {boolean}
* @private
*/
__enabled = false;
/**
*
* @type {Array}
* @private
*/
materials = [];
time = 0;
__speed0 = new Vector2();
__speed1 = new Vector2();
__speed2 = new Vector2();
//how fast clouds reform
variability = 0.37;
constructor() {
this.setSpeed(0.5, -0.5);
}
/**
*
* @param {boolean} val
*/
set enabled(val) {
if (val === this.__enabled) {
return;
}
this.__enabled = val;
this.materials.forEach(this.writeOneEnabled.bind(this));
}
/**
*
* @returns {boolean}
*/
get enabled() {
return this.__enabled;
}
/**
*
* @param {number} x
* @param {number} y
*/
setSpeed(x, y) {
const variability = this.variability;
this.__speed0.set(x, y);
this.__speed1.set(x * (1 - variability), y * (1 + variability));
this.__speed2.set(x * (1 + variability), y * (1 - variability));
}
/**
*
* @param {THREE.Material} mat
*/
writeOneCloudSpeed(mat) {
const uniforms = mat.uniforms;
uniforms.v_CloudsSpeed_0.value.copy(this.__speed0);
uniforms.v_CloudsSpeed_1.value.copy(this.__speed1);
uniforms.v_CloudsSpeed_2.value.copy(this.__speed2);
}
/**
*
* @param {THREE.Material} mat
*/
writeOneEnabled(mat) {
mat.defines.SHADOWMAP_CLOUDS = this.__enabled;
mat.needsUpdate = true;
}
/**
*
* @param {THREE.Material} mat
*/
writeOneTime(mat) {
const uniforms = mat.uniforms;
uniforms.f_CloudsTime.value = this.time;
}
writeAllTime() {
const materials = this.materials;
const l = materials.length;
for (let i = 0; i < l; i++) {
const m = materials[i];
this.writeOneTime(m);
}
}
/**
*
* @param {number} timeDelta
*/
update(timeDelta) {
this.time += timeDelta;
this.writeAllTime();
}
/**
*
* @param {THREE.Material} mat
*/
writeOneCloudTextures(mat) {
const uniforms = mat.uniforms;
uniforms.t_Clouds_0.value = loadCloudTexture("data/textures/noise/tile_256.png");
uniforms.t_Clouds_1.value = loadCloudTexture("data/textures/noise/tile_256.png");
uniforms.t_Clouds_2.value = loadCloudTexture("data/textures/noise/tile_256.png");
}
/**
*
* @param {THREE.Material} mat
*/
writeOneCloudUniforms(mat) {
const uniforms = mat.uniforms;
uniforms.v_CloudsSize_0.value.set(161, 161);
uniforms.v_CloudsSize_1.value.set(83, 83);
uniforms.v_CloudsSize_2.value.set(23, 23);
uniforms.f_CloudsAmount.value = 0.8;
uniforms.f_CloudsIntensity.value = 0.2;
this.writeOneCloudSpeed(mat);
}
/**
*
* @param {THREE.Material} material
* @returns {boolean}
*/
removeMaterial(material) {
const i = this.materials.indexOf(material);
if (i === -1) {
return false;
}
this.materials.splice(i, 1);
return true;
}
/**
*
* @param {THREE.Material} material
*/
addMaterial(material) {
if (
typeof material.defines === "object"
&& material.defines.hasOwnProperty("SHADOWMAP_CLOUDS")
) {
this.writeOneTime(material);
this.writeOneEnabled(material);
this.writeOneCloudTextures(material);
this.writeOneCloudUniforms(material);
this.materials.push(material);
} else {
console.warn("material doesn't support clouds, ignoring");
}
}
}
export default Clouds;