130 lines
3.2 KiB
JavaScript
130 lines
3.2 KiB
JavaScript
/**
|
|
* Fog shader effect.
|
|
*/
|
|
class FogShader extends AbstractWeatherShader {
|
|
|
|
/** @inheritdoc */
|
|
static defaultUniforms = {
|
|
intensity: 1,
|
|
rotation: 0,
|
|
slope: 0.25
|
|
};
|
|
|
|
/* ---------------------------------------- */
|
|
|
|
/**
|
|
* Configure the number of octaves into the shaders.
|
|
* @param {number} mode
|
|
* @returns {string}
|
|
*/
|
|
static OCTAVES(mode) {
|
|
return `${mode + 2}`;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/**
|
|
* Configure the fog complexity according to mode (performance).
|
|
* @param {number} mode
|
|
* @returns {string}
|
|
*/
|
|
static FOG(mode) {
|
|
if ( mode === 0 ) {
|
|
return `vec2 mv = vec2(fbm(uv * 4.5 + time * 0.115)) * (1.0 + r * 0.25);
|
|
mist += fbm(uv * 4.5 + mv - time * 0.0275) * (1.0 + r * 0.25);`;
|
|
}
|
|
return `for ( int i=0; i<2; i++ ) {
|
|
vec2 mv = vec2(fbm(uv * 4.5 + time * 0.115 + vec2(float(i) * 250.0))) * (0.50 + r * 0.25);
|
|
mist += fbm(uv * 4.5 + mv - time * 0.0275) * (0.50 + r * 0.25);
|
|
}`;
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/** @override */
|
|
static createProgram() {
|
|
const mode = canvas?.performance.mode ?? 2;
|
|
return PIXI.Program.from(this.vertexShader, this.fragmentShader(mode));
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/** @inheritdoc */
|
|
static fragmentShader(mode) {
|
|
return `
|
|
${this.FRAGMENT_HEADER}
|
|
uniform float intensity;
|
|
uniform float slope;
|
|
uniform float rotation;
|
|
|
|
${this.CONSTANTS}
|
|
${this.PERCEIVED_BRIGHTNESS}
|
|
${this.PRNG}
|
|
${this.ROTATION}
|
|
|
|
// ********************************************************* //
|
|
|
|
float fnoise(in vec2 coords) {
|
|
vec2 i = floor(coords);
|
|
vec2 f = fract(coords);
|
|
|
|
float a = random(i);
|
|
float b = random(i + vec2(1.0, 0.0));
|
|
float c = random(i + vec2(0.0, 1.0));
|
|
float d = random(i + vec2(1.0, 1.0));
|
|
vec2 cb = f * f * (3.0 - 2.0 * f);
|
|
|
|
return mix(a, b, cb.x) + (c - a) * cb.y * (1.0 - cb.x) + (d - b) * cb.x * cb.y;
|
|
}
|
|
|
|
// ********************************************************* //
|
|
|
|
float fbm(in vec2 uv) {
|
|
float r = 0.0;
|
|
float scale = 1.0;
|
|
uv += time * 0.03;
|
|
uv *= 2.0;
|
|
|
|
for (int i = 0; i < ${this.OCTAVES(mode)}; i++) {
|
|
r += fnoise(uv + time * 0.03) * scale;
|
|
uv *= 3.0;
|
|
scale *= 0.3;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
// ********************************************************* //
|
|
|
|
vec3 mist(in vec2 uv, in float r) {
|
|
float mist = 0.0;
|
|
${this.FOG(mode)}
|
|
return vec3(0.9, 0.85, 1.0) * mist;
|
|
}
|
|
|
|
// ********************************************************* //
|
|
|
|
void main() {
|
|
${this.COMPUTE_MASK}
|
|
|
|
vec2 ruv;
|
|
if ( rotation != 0.0 ) {
|
|
ruv = vUvs - 0.5;
|
|
ruv *= rot(rotation);
|
|
ruv += 0.5;
|
|
}
|
|
else {
|
|
ruv = vUvs;
|
|
}
|
|
|
|
vec3 col = mist(ruv * 2.0 - 1.0, 0.0) * 1.33;
|
|
float pb = perceivedBrightness(col);
|
|
pb = smoothstep(slope * 0.5, slope + 0.001, pb);
|
|
|
|
gl_FragColor = vec4( mix(vec3(0.05, 0.05, 0.08), col * clamp(slope, 1.0, 2.0), pb), 1.0)
|
|
* vec4(tint, 1.0) * intensity * mask * alpha;
|
|
}
|
|
`;
|
|
}
|
|
}
|
|
|