UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

208 lines (170 loc) 4.62 kB
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;