Files
Foundry-VTT-Docker/resources/app/client/pixi/webgl/shaders/weather/fog.js
2025-01-04 00:34:03 +01:00

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;
}
`;
}
}