Enhance mysterious atmosphere

This commit is contained in:
adroitwhiz 2020-03-22 21:58:52 -04:00
parent d37c847389
commit ec40b654d4
4 changed files with 110 additions and 3 deletions

View file

@ -133,6 +133,13 @@ class RenderWebGL extends EventEmitter {
throw new Error('Could not get WebGL context: this browser or environment may not support WebGL.');
}
this._mystery = {
modeActive: false,
mouseMoveListener: null,
bufferInfo: null,
mouseCoords: [0, 0]
};
/** @type {RenderWebGL.UseGpuModes} */
this._useGpuMode = RenderWebGL.UseGpuModes.Automatic;
@ -223,6 +230,12 @@ class RenderWebGL extends EventEmitter {
const pixelRatio = window.devicePixelRatio || 1;
this._gl.canvas.width = pixelsWide * pixelRatio;
this._gl.canvas.height = pixelsTall * pixelRatio;
if (this._mystery.modeActive && this._mystery.bufferInfo) {
twgl.resizeFramebufferInfo(this._gl, this._mystery.bufferInfo, [
{format: this._gl.RGBA}
], pixelsWide * pixelRatio, pixelsTall * pixelRatio);
}
}
/**
@ -615,7 +628,43 @@ class RenderWebGL extends EventEmitter {
gl.clearColor.apply(gl, this._backgroundColor);
gl.clear(gl.COLOR_BUFFER_BIT);
this._drawThese(this._drawList, ShaderManager.DRAW_MODE.default, this._projection);
let drawList = this._drawList;
if (this._mystery.modeActive) {
drawList = drawList.slice(1);
twgl.bindFramebufferInfo(gl, this._mystery.bufferInfo);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
this._drawThese(drawList, ShaderManager.DRAW_MODE.default, this._projection);
if (this._mystery.modeActive) {
// draw all layers except for the bottom layer onto the mystery buffer
twgl.bindFramebufferInfo(gl, null);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
this._drawThese([this._drawList[0]], ShaderManager.DRAW_MODE.default, this._projection);
this._doExitDrawRegion();
const newShader = this._shaderManager.getShader(ShaderManager.DRAW_MODE.mystery, 0);
this._regionId = newShader;
// draw mystery buffer to main buffer
gl.useProgram(newShader.program);
twgl.setBuffersAndAttributes(gl, newShader, this._bufferInfo);
const uniforms = {
u_projectionMatrix: this._projection,
u_modelMatrix: twgl.m4.identity(),
u_skin: this._mystery.bufferInfo.attachments[0],
u_mousePosition: this._mystery.mouseCoords
};
twgl.setTextureParameters(
gl, uniforms.u_skin, {minMag: gl.LINEAR}
);
twgl.setUniforms(newShader, uniforms);
twgl.drawBufferInfo(gl, this._bufferInfo, gl.TRIANGLES);
}
if (this._snapshotCallbacks.length > 0) {
const snapshot = gl.canvas.toDataURL();
this._snapshotCallbacks.forEach(cb => cb(snapshot));
@ -1909,6 +1958,32 @@ class RenderWebGL extends EventEmitter {
return dst;
}
setMysteryMode (enableMysteryMode) {
this._mystery.modeActive = enableMysteryMode;
if (enableMysteryMode) {
this._mystery.bufferInfo = twgl.createFramebufferInfo(
this._gl,
[{format: this._gl.RGBA}],
this._gl.drawingBufferWidth,
this._gl.drawingBufferHeight
);
this._mystery.mouseMoveListener = event => {
const rect = this.canvas.getBoundingClientRect();
this._mystery.mouseCoords[0] = (event.clientX - rect.left) / rect.width;
this._mystery.mouseCoords[1] = (event.clientY - rect.top) / rect.height;
};
document.addEventListener('mousemove', this._mystery.mouseMoveListener);
} else {
if (this._mystery.bufferInfo) {
this._gl.deleteFramebuffer(this._mystery.bufferInfo.framebuffer);
}
document.removeEventListener('mousemove', this._mystery.mouseMoveListener);
}
}
/**
* @callback RenderWebGL#snapshotCallback
* @param {string} dataURI Data URI of the snapshot of the renderer

View file

@ -171,7 +171,9 @@ ShaderManager.DRAW_MODE = {
/**
* Sample a "texture" to draw a line with caps.
*/
lineSample: 'lineSample'
lineSample: 'lineSample',
mystery: 'mystery'
};
module.exports = ShaderManager;

View file

@ -39,6 +39,10 @@ uniform float u_capScale;
uniform float u_aliasAmount;
#endif // DRAW_MODE_lineSample
#ifdef DRAW_MODE_mystery
uniform vec2 u_mousePosition;
#endif
uniform sampler2D u_skin;
varying vec2 v_texCoord;
@ -112,6 +116,15 @@ void main()
#ifndef DRAW_MODE_lineSample
vec2 texcoord0 = v_texCoord;
#ifdef DRAW_MODE_mystery
vec2 mysteryCoord = texcoord0;
vec2 offset = vec2(u_mousePosition.x, 1.0 - u_mousePosition.y);
mysteryCoord -= offset;
const float SCALE_FACTOR = 0.85;
mysteryCoord *= vec2(SCALE_FACTOR, SCALE_FACTOR);
mysteryCoord += offset;
#endif
#ifdef ENABLE_mosaic
texcoord0 = fract(u_mosaic * texcoord0);
#endif // ENABLE_mosaic
@ -155,6 +168,21 @@ void main()
gl_FragColor = texture2D(u_skin, texcoord0);
#ifdef DRAW_MODE_mystery
const vec4 SHADOW_COLOR = vec4(0.0, 0.0, 0.0, 0.5);
const float SHADOW_BLUR = 0.0025;
float shadowSample1 = texture2D(u_skin, mysteryCoord + vec2(SHADOW_BLUR, SHADOW_BLUR)).a;
float shadowSample2 = texture2D(u_skin, mysteryCoord + vec2(-SHADOW_BLUR, SHADOW_BLUR)).a;
float shadowSample3 = texture2D(u_skin, mysteryCoord + vec2(SHADOW_BLUR, -SHADOW_BLUR)).a;
float shadowSample4 = texture2D(u_skin, mysteryCoord + vec2(-SHADOW_BLUR, -SHADOW_BLUR)).a;
float shadowAlpha = (shadowSample1 + shadowSample2 + shadowSample3 + shadowSample4) * 0.25;
vec4 shadow = SHADOW_COLOR * shadowAlpha;
gl_FragColor = gl_FragColor + (shadow * (1.0 - gl_FragColor.a));
#endif
#if defined(ENABLE_color) || defined(ENABLE_brightness)
// Divide premultiplied alpha values for proper color processing
// Add epsilon to avoid dividing by 0 for fully transparent pixels

View file

@ -15,7 +15,9 @@ void main() {
vec2 position = a_position;
position.y = clamp(position.y * u_positionScalar, -0.5, 0.5);
gl_Position = u_projectionMatrix * u_modelMatrix * vec4(position, 0, 1);
#else
#elif defined(DRAW_MODE_mystery)
gl_Position = vec4(a_position * vec2(-2.0, 2.0), 0.0, 1.0);
#else
gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1);
#endif
v_texCoord = a_texCoord;