From f68da75c753358b7cce2f8f7618b1db624d45932 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Tue, 12 Sep 2017 19:43:43 -0700 Subject: [PATCH] Implement SSAA for the 3D demo. This commit additionally refactors transforms to be resolution-independent as much as possible throughout all the demos. --- demo/client/html/3d-demo.html.hbs | 6 +++--- demo/client/src/3d-demo.ts | 14 +++++++++----- demo/client/src/ecaa-strategy.ts | 4 ++-- demo/client/src/svg-demo.ts | 13 +++++++++---- demo/client/src/text-demo.ts | 7 +++++-- demo/client/src/view.ts | 19 ++++++++++++++++--- shaders/gles2/common.inc.glsl | 17 ++++++++++++++--- shaders/gles2/direct-curve.vs.glsl | 2 -- shaders/gles2/direct-interior.vs.glsl | 2 -- shaders/gles2/ecaa-cover.vs.glsl | 13 +++++++++++-- shaders/gles2/ecaa-curve.vs.glsl | 6 ++++-- shaders/gles2/ecaa-line.vs.glsl | 5 ++--- 12 files changed, 75 insertions(+), 33 deletions(-) diff --git a/demo/client/html/3d-demo.html.hbs b/demo/client/html/3d-demo.html.hbs index 9d15d442..f0cda5fd 100644 --- a/demo/client/html/3d-demo.html.hbs +++ b/demo/client/html/3d-demo.html.hbs @@ -27,9 +27,9 @@
diff --git a/demo/client/src/3d-demo.ts b/demo/client/src/3d-demo.ts index 89b786fb..c8077d80 100644 --- a/demo/client/src/3d-demo.ts +++ b/demo/client/src/3d-demo.ts @@ -25,7 +25,7 @@ import SSAAStrategy from "./ssaa-strategy"; import * as _ from "lodash"; import PathfinderBufferTexture from "./buffer-texture"; -const WIDTH: number = 150000; +const TEXT_AVAILABLE_WIDTH: number = 150000; const PADDING: number = 2000; const TEXT_DATA_URI: string = "/data/mozmonument.json"; @@ -40,15 +40,19 @@ const FAR_CLIP_PLANE: number = 3000.0; const SCALE: glmatrix.vec3 = glmatrix.vec3.fromValues(1.0 / 200.0, 1.0 / 200.0, 1.0 / 200.0); -const TEXT_TRANSLATION: number[] = [-(WIDTH + PADDING) * 0.5, 0.0, (WIDTH + PADDING) * 0.5]; +const TEXT_TRANSLATION: number[] = [ + -(TEXT_AVAILABLE_WIDTH + PADDING) * 0.5, + 0.0, + (TEXT_AVAILABLE_WIDTH + PADDING) * 0.5 +]; const TEXT_DECAL_OFFSET: number = 5.0; const MONUMENT_TRANSLATION: glmatrix.vec3 = glmatrix.vec3.fromValues(0.0, -690.0, 0.0); const MONUMENT_SCALE: glmatrix.vec3 = - glmatrix.vec3.fromValues((WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET, + glmatrix.vec3.fromValues((TEXT_AVAILABLE_WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET, 700.0, - (WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET); + (TEXT_AVAILABLE_WIDTH + PADDING) / 400.0 - TEXT_DECAL_OFFSET); const TEXT_COLOR: Uint8Array = new Uint8Array([0xf2, 0xf8, 0xf8, 0xff]); const MONUMENT_COLOR: number[] = [0x70 / 0xff, 0x80 / 0xff, 0x80 / 0xff]; @@ -147,7 +151,7 @@ class ThreeDController extends DemoAppController { }); const usedSpace = _.sumBy(lineGlyphs, 'width'); - const emptySpace = Math.max(WIDTH - usedSpace, 0.0); + const emptySpace = Math.max(TEXT_AVAILABLE_WIDTH - usedSpace, 0.0); const spacing = emptySpace / Math.max(lineGlyphs.length - 1, 1); let currentX = 0.0; diff --git a/demo/client/src/ecaa-strategy.ts b/demo/client/src/ecaa-strategy.ts index 31b37643..60522bc5 100644 --- a/demo/client/src/ecaa-strategy.ts +++ b/demo/client/src/ecaa-strategy.ts @@ -301,13 +301,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy { view.gl.useProgram(coverProgram.program); view.vertexArrayObjectExt.bindVertexArrayOES(this.coverVAO); const uniforms = coverProgram.uniforms; + view.setTransformSTUniform(uniforms, 0); view.setFramebufferSizeUniform(uniforms); this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0); this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1); view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2); if (view.pathHintsBufferTexture !== null) view.pathHintsBufferTexture.bind(view.gl, uniforms, 3); - view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]); view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES, 6, view.gl.UNSIGNED_BYTE, @@ -334,13 +334,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy { } private setAAUniforms(view: MonochromePathfinderView, uniforms: UniformMap) { + view.setTransformSTUniform(uniforms, 0); view.setFramebufferSizeUniform(uniforms); this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0); this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1); view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2); if (view.pathHintsBufferTexture !== null) view.pathHintsBufferTexture.bind(view.gl, uniforms, 3); - view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]); } private antialiasLines(view: MonochromePathfinderView) { diff --git a/demo/client/src/svg-demo.ts b/demo/client/src/svg-demo.ts index cd55310c..e38b9fd4 100644 --- a/demo/client/src/svg-demo.ts +++ b/demo/client/src/svg-demo.ts @@ -275,15 +275,20 @@ class SVGDemoView extends PathfinderDemoView { // TODO(pcwalton) } - protected get usedSizeFactor(): glmatrix.vec2 { - return glmatrix.vec2.fromValues(1.0, 1.0); - } + protected usedSizeFactor: glmatrix.vec2 = glmatrix.vec2.fromValues(1.0, 1.0); protected get worldTransform() { const transform = glmatrix.mat4.create(); const translation = this.camera.translation; - glmatrix.mat4.fromTranslation(transform, [translation[0], translation[1], 0]); + glmatrix.mat4.translate(transform, transform, [-1.0, -1.0, 0.0]); + glmatrix.mat4.scale(transform, + transform, + [2.0 / this.canvas.width, 2.0 / this.canvas.height, 1.0]); + glmatrix.mat4.translate(transform, transform, [translation[0], translation[1], 0]); glmatrix.mat4.scale(transform, transform, [this.camera.scale, this.camera.scale, 1.0]); + if (this.antialiasingStrategy != null) + glmatrix.mat4.mul(transform, transform, this.antialiasingStrategy.transform); + console.log(transform); return transform; } diff --git a/demo/client/src/text-demo.ts b/demo/client/src/text-demo.ts index 427bd329..eff2e172 100644 --- a/demo/client/src/text-demo.ts +++ b/demo/client/src/text-demo.ts @@ -568,8 +568,11 @@ class TextDemoView extends MonochromePathfinderView { this.appController.updateTimings(timings); } - protected get worldTransform() { - return glmatrix.mat4.create(); + protected get worldTransform(): glmatrix.mat4 { + const transform = glmatrix.mat4.create(); + glmatrix.mat4.translate(transform, transform, [-1.0, -1.0, 0.0]); + glmatrix.mat4.scale(transform, transform, [2.0 / ATLAS_SIZE[0], 2.0 / ATLAS_SIZE[1], 1.0]); + return transform; } protected get directCurveProgramName(): keyof ShaderMap { diff --git a/demo/client/src/view.ts b/demo/client/src/view.ts index c553f6be..09ce8f65 100644 --- a/demo/client/src/view.ts +++ b/demo/client/src/view.ts @@ -295,10 +295,23 @@ export abstract class PathfinderDemoView extends PathfinderView { protected renderingFinished(): void {} + setTransformSTUniform(uniforms: UniformMap, objectIndex: number) { + // FIXME(pcwalton): Lossy conversion from a 4x4 matrix to an ST matrix is ugly and fragile. + // Refactor. + const transform = glmatrix.mat4.clone(this.worldTransform); + glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex)); + + const translation = glmatrix.vec4.clone([transform[12], transform[13], 0.0, 1.0]); + + this.gl.uniform4f(uniforms.uTransformST, + transform[0], + transform[5], + transform[12], + transform[13]); + } + private setTransformUniform(uniforms: UniformMap, objectIndex: number) { - const transform = glmatrix.mat4.create(); - if (this.antialiasingStrategy != null) - glmatrix.mat4.mul(transform, this.antialiasingStrategy.transform, this.worldTransform); + const transform = glmatrix.mat4.clone(this.worldTransform); glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex)); this.gl.uniformMatrix4fv(uniforms.uTransform, false, transform); } diff --git a/shaders/gles2/common.inc.glsl b/shaders/gles2/common.inc.glsl index 71ef2dd5..7186f206 100644 --- a/shaders/gles2/common.inc.glsl +++ b/shaders/gles2/common.inc.glsl @@ -48,6 +48,10 @@ vec2 hintPosition(vec2 position, vec4 pathHints) { return vec2(position.x, position.y / pathHints.x * pathHints.y); } +vec2 convertClipToScreenSpace(vec2 position, ivec2 framebufferSize) { + return (position + 1.0) * 0.5 * vec2(framebufferSize); +} + vec2 convertScreenToClipSpace(vec2 position, ivec2 framebufferSize) { return position / vec2(framebufferSize) * 2.0 - 1.0; } @@ -65,13 +69,20 @@ bool computeQuadPosition(out vec2 outPosition, inout vec2 rightPosition, vec2 quadPosition, ivec2 framebufferSize, - vec4 transform, + vec4 localTransformST, + vec4 globalTransformST, vec4 hints) { leftPosition = hintPosition(leftPosition, hints); rightPosition = hintPosition(rightPosition, hints); - leftPosition = transformVertexPositionST(leftPosition, transform); - rightPosition = transformVertexPositionST(rightPosition, transform); + leftPosition = transformVertexPositionST(leftPosition, localTransformST); + rightPosition = transformVertexPositionST(rightPosition, localTransformST); + + leftPosition = transformVertexPositionST(leftPosition, globalTransformST); + rightPosition = transformVertexPositionST(rightPosition, globalTransformST); + + leftPosition = convertClipToScreenSpace(leftPosition, framebufferSize); + rightPosition = convertClipToScreenSpace(rightPosition, framebufferSize); if (abs(leftPosition.x - rightPosition.x) <= EPSILON) { outPosition = vec2(0.0); diff --git a/shaders/gles2/direct-curve.vs.glsl b/shaders/gles2/direct-curve.vs.glsl index e61a626e..b70a1326 100644 --- a/shaders/gles2/direct-curve.vs.glsl +++ b/shaders/gles2/direct-curve.vs.glsl @@ -5,7 +5,6 @@ precision highp float; uniform mat4 uTransform; -uniform ivec2 uFramebufferSize; uniform ivec2 uPathColorsDimensions; uniform ivec2 uPathTransformDimensions; uniform ivec2 uPathHintsDimensions; @@ -32,7 +31,6 @@ void main() { vec2 position = hintPosition(aPosition, pathHints); position = transformVertexPositionST(position, pathTransform); position = transformVertexPosition(position, uTransform); - position = convertScreenToClipSpace(position, uFramebufferSize); float depth = convertPathIndexToViewportDepthValue(pathID); gl_Position = vec4(position, depth, 1.0); diff --git a/shaders/gles2/direct-interior.vs.glsl b/shaders/gles2/direct-interior.vs.glsl index e2e2466e..3b2d410d 100644 --- a/shaders/gles2/direct-interior.vs.glsl +++ b/shaders/gles2/direct-interior.vs.glsl @@ -5,7 +5,6 @@ precision highp float; uniform mat4 uTransform; -uniform ivec2 uFramebufferSize; uniform ivec2 uPathColorsDimensions; uniform ivec2 uPathTransformDimensions; uniform ivec2 uPathHintsDimensions; @@ -28,7 +27,6 @@ void main() { vec2 position = hintPosition(aPosition, pathHints); position = transformVertexPositionST(position, pathTransform); position = transformVertexPosition(position, uTransform); - position = convertScreenToClipSpace(position, uFramebufferSize); float depth = convertPathIndexToViewportDepthValue(pathID); gl_Position = vec4(position, depth, 1.0); diff --git a/shaders/gles2/ecaa-cover.vs.glsl b/shaders/gles2/ecaa-cover.vs.glsl index e1d2b49c..e229e3cc 100644 --- a/shaders/gles2/ecaa-cover.vs.glsl +++ b/shaders/gles2/ecaa-cover.vs.glsl @@ -4,8 +4,8 @@ precision highp float; +uniform vec4 uTransformST; uniform ivec2 uFramebufferSize; -uniform float uScaleX; uniform ivec2 uBVertexPositionDimensions; uniform ivec2 uBVertexPathIDDimensions; uniform ivec2 uPathTransformDimensions; @@ -45,7 +45,6 @@ void main() { vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions); vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions); - transform.xz *= uScaleX; upperLeftPosition = hintPosition(upperLeftPosition, hints); upperRightPosition = hintPosition(upperRightPosition, hints); @@ -57,6 +56,16 @@ void main() { lowerLeftPosition = transformVertexPositionST(lowerLeftPosition, transform); lowerRightPosition = transformVertexPositionST(lowerRightPosition, transform); + upperLeftPosition = transformVertexPositionST(upperLeftPosition, uTransformST); + upperRightPosition = transformVertexPositionST(upperRightPosition, uTransformST); + lowerLeftPosition = transformVertexPositionST(lowerLeftPosition, uTransformST); + lowerRightPosition = transformVertexPositionST(lowerRightPosition, uTransformST); + + upperLeftPosition = convertClipToScreenSpace(upperLeftPosition, uFramebufferSize); + upperRightPosition = convertClipToScreenSpace(upperRightPosition, uFramebufferSize); + lowerLeftPosition = convertClipToScreenSpace(lowerLeftPosition, uFramebufferSize); + lowerRightPosition = convertClipToScreenSpace(lowerRightPosition, uFramebufferSize); + vec4 extents = vec4(min(upperLeftPosition.x, lowerLeftPosition.x), min(min(upperLeftPosition.y, upperRightPosition.y), min(lowerLeftPosition.y, lowerRightPosition.y)), diff --git a/shaders/gles2/ecaa-curve.vs.glsl b/shaders/gles2/ecaa-curve.vs.glsl index bfa4ac83..a4d6938b 100644 --- a/shaders/gles2/ecaa-curve.vs.glsl +++ b/shaders/gles2/ecaa-curve.vs.glsl @@ -4,8 +4,8 @@ precision highp float; +uniform vec4 uTransformST; uniform ivec2 uFramebufferSize; -uniform float uScaleX; uniform ivec2 uBVertexPositionDimensions; uniform ivec2 uBVertexPathIDDimensions; uniform ivec2 uPathTransformDimensions; @@ -42,7 +42,6 @@ void main() { vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions); vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions); - transform.xz *= uScaleX; // Transform the points, and compute the position of this vertex. vec2 position; @@ -52,9 +51,12 @@ void main() { aQuadPosition, uFramebufferSize, transform, + uTransformST, hints)) { controlPointPosition = hintPosition(controlPointPosition, hints); controlPointPosition = transformVertexPositionST(controlPointPosition, transform); + controlPointPosition = transformVertexPositionST(controlPointPosition, uTransformST); + controlPointPosition = convertClipToScreenSpace(controlPointPosition, uFramebufferSize); } float depth = convertPathIndexToViewportDepthValue(pathID); diff --git a/shaders/gles2/ecaa-line.vs.glsl b/shaders/gles2/ecaa-line.vs.glsl index c751334e..8e49c81c 100644 --- a/shaders/gles2/ecaa-line.vs.glsl +++ b/shaders/gles2/ecaa-line.vs.glsl @@ -4,8 +4,7 @@ precision highp float; -uniform mat4 uTransform; -uniform float uScaleX; +uniform vec4 uTransformST; uniform ivec2 uFramebufferSize; uniform ivec2 uBVertexPositionDimensions; uniform ivec2 uBVertexPathIDDimensions; @@ -37,7 +36,6 @@ void main() { vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions); vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions); - transform.xz *= uScaleX; // Transform the points, and compute the position of this vertex. vec2 position; @@ -47,6 +45,7 @@ void main() { aQuadPosition, uFramebufferSize, transform, + uTransformST, hints); float depth = convertPathIndexToViewportDepthValue(pathID);