Compare commits

...

2 Commits

Author SHA1 Message Date
adroitwhiz
08e2abced2 Set v_texCoord in mystery mode 2021-03-29 11:08:02 -04:00
adroitwhiz
88d31483a2 Enhance mysterious atmosphere 2021-03-29 11:04:53 -04:00
4 changed files with 112 additions and 3 deletions

View File

@@ -139,6 +139,13 @@ class RenderWebGL extends EventEmitter {
throw new Error('Could not get WebGL context: this browser or environment may not support WebGL.'); 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} */ /** @type {RenderWebGL.UseGpuModes} */
this._useGpuMode = RenderWebGL.UseGpuModes.Automatic; this._useGpuMode = RenderWebGL.UseGpuModes.Automatic;
@@ -242,6 +249,7 @@ class RenderWebGL extends EventEmitter {
resize (pixelsWide, pixelsTall) { resize (pixelsWide, pixelsTall) {
const {canvas} = this._gl; const {canvas} = this._gl;
const pixelRatio = window.devicePixelRatio || 1; const pixelRatio = window.devicePixelRatio || 1;
const newWidth = pixelsWide * pixelRatio; const newWidth = pixelsWide * pixelRatio;
const newHeight = pixelsTall * pixelRatio; const newHeight = pixelsTall * pixelRatio;
@@ -250,10 +258,16 @@ class RenderWebGL extends EventEmitter {
if (canvas.width !== newWidth || canvas.height !== newHeight) { if (canvas.width !== newWidth || canvas.height !== newHeight) {
canvas.width = newWidth; canvas.width = newWidth;
canvas.height = newHeight; canvas.height = newHeight;
if (this._mystery.modeActive && this._mystery.bufferInfo) {
twgl.resizeFramebufferInfo(this._gl, this._mystery.bufferInfo, [
{format: this._gl.RGBA}
], pixelsWide * pixelRatio, pixelsTall * pixelRatio);
}
// Resizing the canvas causes it to be cleared, so redraw it. // Resizing the canvas causes it to be cleared, so redraw it.
this.draw(); this.draw();
} }
} }
/** /**
@@ -653,7 +667,43 @@ class RenderWebGL extends EventEmitter {
gl.clearColor(...this._backgroundColor4f); gl.clearColor(...this._backgroundColor4f);
gl.clear(gl.COLOR_BUFFER_BIT); 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) { if (this._snapshotCallbacks.length > 0) {
const snapshot = gl.canvas.toDataURL(); const snapshot = gl.canvas.toDataURL();
this._snapshotCallbacks.forEach(cb => cb(snapshot)); this._snapshotCallbacks.forEach(cb => cb(snapshot));
@@ -2083,6 +2133,32 @@ class RenderWebGL extends EventEmitter {
return dst; 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 * @callback RenderWebGL#snapshotCallback
* @param {string} dataURI Data URI of the snapshot of the renderer * @param {string} dataURI Data URI of the snapshot of the renderer

View File

@@ -181,7 +181,9 @@ ShaderManager.DRAW_MODE = {
/** /**
* Draw the background in a certain color. Must sometimes be used instead of gl.clear. * Draw the background in a certain color. Must sometimes be used instead of gl.clear.
*/ */
background: 'background' background: 'background',
mystery: 'mystery'
}; };
module.exports = ShaderManager; module.exports = ShaderManager;

View File

@@ -43,6 +43,10 @@ uniform float u_lineLength;
uniform vec4 u_backgroundColor; uniform vec4 u_backgroundColor;
#endif // DRAW_MODE_background #endif // DRAW_MODE_background
#ifdef DRAW_MODE_mystery
uniform vec2 u_mousePosition;
#endif
uniform sampler2D u_skin; uniform sampler2D u_skin;
#ifndef DRAW_MODE_background #ifndef DRAW_MODE_background
@@ -118,6 +122,15 @@ void main()
#if !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) #if !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background))
vec2 texcoord0 = v_texCoord; 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 #ifdef ENABLE_mosaic
texcoord0 = fract(u_mosaic * texcoord0); texcoord0 = fract(u_mosaic * texcoord0);
#endif // ENABLE_mosaic #endif // ENABLE_mosaic
@@ -161,6 +174,21 @@ void main()
gl_FragColor = texture2D(u_skin, texcoord0); 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) #if defined(ENABLE_color) || defined(ENABLE_brightness)
// Divide premultiplied alpha values for proper color processing // Divide premultiplied alpha values for proper color processing
// Add epsilon to avoid dividing by 0 for fully transparent pixels // Add epsilon to avoid dividing by 0 for fully transparent pixels

View File

@@ -68,6 +68,9 @@ void main() {
gl_Position = vec4(position, 0, 1); gl_Position = vec4(position, 0, 1);
#elif defined(DRAW_MODE_background) #elif defined(DRAW_MODE_background)
gl_Position = vec4(a_position * 2.0, 0, 1); gl_Position = vec4(a_position * 2.0, 0, 1);
#elif defined(DRAW_MODE_mystery)
gl_Position = vec4(a_position * vec2(-2.0, 2.0), 0.0, 1.0);
v_texCoord = a_texCoord;
#else #else
gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1); gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1);
v_texCoord = a_texCoord; v_texCoord = a_texCoord;