Implement SSAA for the 3D demo.

This commit additionally refactors transforms to be resolution-independent as much as possible throughout all the demos.
This commit is contained in:
Patrick Walton 2017-09-12 19:43:43 -07:00
parent 6fec73b2f7
commit f68da75c75
12 changed files with 75 additions and 33 deletions

View File

@ -27,9 +27,9 @@
<div class="form-group"> <div class="form-group">
<label for="pf-aa-level-select">Antialiasing</label> <label for="pf-aa-level-select">Antialiasing</label>
<select id="pf-aa-level-select" class="form-control custom-select"> <select id="pf-aa-level-select" class="form-control custom-select">
<option value="none" selected>None</option> <option value="none">None</option>
<option value="ssaa-2">2&times;SSAA (BROKEN)</option> <option value="ssaa-2">2&times;SSAA</option>
<option value="ssaa-4">4&times;SSAA (BROKEN)</option> <option value="ssaa-4" selected>4&times;SSAA</option>
</select> </select>
</div> </div>
</form> </form>

View File

@ -25,7 +25,7 @@ import SSAAStrategy from "./ssaa-strategy";
import * as _ from "lodash"; import * as _ from "lodash";
import PathfinderBufferTexture from "./buffer-texture"; import PathfinderBufferTexture from "./buffer-texture";
const WIDTH: number = 150000; const TEXT_AVAILABLE_WIDTH: number = 150000;
const PADDING: number = 2000; const PADDING: number = 2000;
const TEXT_DATA_URI: string = "/data/mozmonument.json"; 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 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 TEXT_DECAL_OFFSET: number = 5.0;
const MONUMENT_TRANSLATION: glmatrix.vec3 = glmatrix.vec3.fromValues(0.0, -690.0, 0.0); const MONUMENT_TRANSLATION: glmatrix.vec3 = glmatrix.vec3.fromValues(0.0, -690.0, 0.0);
const MONUMENT_SCALE: glmatrix.vec3 = 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, 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 TEXT_COLOR: Uint8Array = new Uint8Array([0xf2, 0xf8, 0xf8, 0xff]);
const MONUMENT_COLOR: number[] = [0x70 / 0xff, 0x80 / 0xff, 0x80 / 0xff]; const MONUMENT_COLOR: number[] = [0x70 / 0xff, 0x80 / 0xff, 0x80 / 0xff];
@ -147,7 +151,7 @@ class ThreeDController extends DemoAppController<ThreeDView> {
}); });
const usedSpace = _.sumBy(lineGlyphs, 'width'); 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); const spacing = emptySpace / Math.max(lineGlyphs.length - 1, 1);
let currentX = 0.0; let currentX = 0.0;

View File

@ -301,13 +301,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
view.gl.useProgram(coverProgram.program); view.gl.useProgram(coverProgram.program);
view.vertexArrayObjectExt.bindVertexArrayOES(this.coverVAO); view.vertexArrayObjectExt.bindVertexArrayOES(this.coverVAO);
const uniforms = coverProgram.uniforms; const uniforms = coverProgram.uniforms;
view.setTransformSTUniform(uniforms, 0);
view.setFramebufferSizeUniform(uniforms); view.setFramebufferSizeUniform(uniforms);
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0); this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1); this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2); view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2);
if (view.pathHintsBufferTexture !== null) if (view.pathHintsBufferTexture !== null)
view.pathHintsBufferTexture.bind(view.gl, uniforms, 3); view.pathHintsBufferTexture.bind(view.gl, uniforms, 3);
view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]);
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES, view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
6, 6,
view.gl.UNSIGNED_BYTE, view.gl.UNSIGNED_BYTE,
@ -334,13 +334,13 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
} }
private setAAUniforms(view: MonochromePathfinderView, uniforms: UniformMap) { private setAAUniforms(view: MonochromePathfinderView, uniforms: UniformMap) {
view.setTransformSTUniform(uniforms, 0);
view.setFramebufferSizeUniform(uniforms); view.setFramebufferSizeUniform(uniforms);
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0); this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1); this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2); view.pathTransformBufferTextures[0].bind(view.gl, uniforms, 2);
if (view.pathHintsBufferTexture !== null) if (view.pathHintsBufferTexture !== null)
view.pathHintsBufferTexture.bind(view.gl, uniforms, 3); view.pathHintsBufferTexture.bind(view.gl, uniforms, 3);
view.gl.uniform1f(uniforms.uScaleX, this.supersampleScale[0]);
} }
private antialiasLines(view: MonochromePathfinderView) { private antialiasLines(view: MonochromePathfinderView) {

View File

@ -275,15 +275,20 @@ class SVGDemoView extends PathfinderDemoView {
// TODO(pcwalton) // TODO(pcwalton)
} }
protected get usedSizeFactor(): glmatrix.vec2 { protected usedSizeFactor: glmatrix.vec2 = glmatrix.vec2.fromValues(1.0, 1.0);
return glmatrix.vec2.fromValues(1.0, 1.0);
}
protected get worldTransform() { protected get worldTransform() {
const transform = glmatrix.mat4.create(); const transform = glmatrix.mat4.create();
const translation = this.camera.translation; 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]); 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; return transform;
} }

View File

@ -568,8 +568,11 @@ class TextDemoView extends MonochromePathfinderView {
this.appController.updateTimings(timings); this.appController.updateTimings(timings);
} }
protected get worldTransform() { protected get worldTransform(): glmatrix.mat4 {
return glmatrix.mat4.create(); 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<void> { protected get directCurveProgramName(): keyof ShaderMap<void> {

View File

@ -295,10 +295,23 @@ export abstract class PathfinderDemoView extends PathfinderView {
protected renderingFinished(): void {} 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) { private setTransformUniform(uniforms: UniformMap, objectIndex: number) {
const transform = glmatrix.mat4.create(); const transform = glmatrix.mat4.clone(this.worldTransform);
if (this.antialiasingStrategy != null)
glmatrix.mat4.mul(transform, this.antialiasingStrategy.transform, this.worldTransform);
glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex)); glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex));
this.gl.uniformMatrix4fv(uniforms.uTransform, false, transform); this.gl.uniformMatrix4fv(uniforms.uTransform, false, transform);
} }

View File

@ -48,6 +48,10 @@ vec2 hintPosition(vec2 position, vec4 pathHints) {
return vec2(position.x, position.y / pathHints.x * pathHints.y); 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) { vec2 convertScreenToClipSpace(vec2 position, ivec2 framebufferSize) {
return position / vec2(framebufferSize) * 2.0 - 1.0; return position / vec2(framebufferSize) * 2.0 - 1.0;
} }
@ -65,13 +69,20 @@ bool computeQuadPosition(out vec2 outPosition,
inout vec2 rightPosition, inout vec2 rightPosition,
vec2 quadPosition, vec2 quadPosition,
ivec2 framebufferSize, ivec2 framebufferSize,
vec4 transform, vec4 localTransformST,
vec4 globalTransformST,
vec4 hints) { vec4 hints) {
leftPosition = hintPosition(leftPosition, hints); leftPosition = hintPosition(leftPosition, hints);
rightPosition = hintPosition(rightPosition, hints); rightPosition = hintPosition(rightPosition, hints);
leftPosition = transformVertexPositionST(leftPosition, transform); leftPosition = transformVertexPositionST(leftPosition, localTransformST);
rightPosition = transformVertexPositionST(rightPosition, transform); 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) { if (abs(leftPosition.x - rightPosition.x) <= EPSILON) {
outPosition = vec2(0.0); outPosition = vec2(0.0);

View File

@ -5,7 +5,6 @@
precision highp float; precision highp float;
uniform mat4 uTransform; uniform mat4 uTransform;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathColorsDimensions; uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions; uniform ivec2 uPathTransformDimensions;
uniform ivec2 uPathHintsDimensions; uniform ivec2 uPathHintsDimensions;
@ -32,7 +31,6 @@ void main() {
vec2 position = hintPosition(aPosition, pathHints); vec2 position = hintPosition(aPosition, pathHints);
position = transformVertexPositionST(position, pathTransform); position = transformVertexPositionST(position, pathTransform);
position = transformVertexPosition(position, uTransform); position = transformVertexPosition(position, uTransform);
position = convertScreenToClipSpace(position, uFramebufferSize);
float depth = convertPathIndexToViewportDepthValue(pathID); float depth = convertPathIndexToViewportDepthValue(pathID);
gl_Position = vec4(position, depth, 1.0); gl_Position = vec4(position, depth, 1.0);

View File

@ -5,7 +5,6 @@
precision highp float; precision highp float;
uniform mat4 uTransform; uniform mat4 uTransform;
uniform ivec2 uFramebufferSize;
uniform ivec2 uPathColorsDimensions; uniform ivec2 uPathColorsDimensions;
uniform ivec2 uPathTransformDimensions; uniform ivec2 uPathTransformDimensions;
uniform ivec2 uPathHintsDimensions; uniform ivec2 uPathHintsDimensions;
@ -28,7 +27,6 @@ void main() {
vec2 position = hintPosition(aPosition, pathHints); vec2 position = hintPosition(aPosition, pathHints);
position = transformVertexPositionST(position, pathTransform); position = transformVertexPositionST(position, pathTransform);
position = transformVertexPosition(position, uTransform); position = transformVertexPosition(position, uTransform);
position = convertScreenToClipSpace(position, uFramebufferSize);
float depth = convertPathIndexToViewportDepthValue(pathID); float depth = convertPathIndexToViewportDepthValue(pathID);
gl_Position = vec4(position, depth, 1.0); gl_Position = vec4(position, depth, 1.0);

View File

@ -4,8 +4,8 @@
precision highp float; precision highp float;
uniform vec4 uTransformST;
uniform ivec2 uFramebufferSize; uniform ivec2 uFramebufferSize;
uniform float uScaleX;
uniform ivec2 uBVertexPositionDimensions; uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexPathIDDimensions; uniform ivec2 uBVertexPathIDDimensions;
uniform ivec2 uPathTransformDimensions; uniform ivec2 uPathTransformDimensions;
@ -45,7 +45,6 @@ void main() {
vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions); vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions); vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
transform.xz *= uScaleX;
upperLeftPosition = hintPosition(upperLeftPosition, hints); upperLeftPosition = hintPosition(upperLeftPosition, hints);
upperRightPosition = hintPosition(upperRightPosition, hints); upperRightPosition = hintPosition(upperRightPosition, hints);
@ -57,6 +56,16 @@ void main() {
lowerLeftPosition = transformVertexPositionST(lowerLeftPosition, transform); lowerLeftPosition = transformVertexPositionST(lowerLeftPosition, transform);
lowerRightPosition = transformVertexPositionST(lowerRightPosition, 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), vec4 extents = vec4(min(upperLeftPosition.x, lowerLeftPosition.x),
min(min(upperLeftPosition.y, upperRightPosition.y), min(min(upperLeftPosition.y, upperRightPosition.y),
min(lowerLeftPosition.y, lowerRightPosition.y)), min(lowerLeftPosition.y, lowerRightPosition.y)),

View File

@ -4,8 +4,8 @@
precision highp float; precision highp float;
uniform vec4 uTransformST;
uniform ivec2 uFramebufferSize; uniform ivec2 uFramebufferSize;
uniform float uScaleX;
uniform ivec2 uBVertexPositionDimensions; uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexPathIDDimensions; uniform ivec2 uBVertexPathIDDimensions;
uniform ivec2 uPathTransformDimensions; uniform ivec2 uPathTransformDimensions;
@ -42,7 +42,6 @@ void main() {
vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions); vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions); vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
transform.xz *= uScaleX;
// Transform the points, and compute the position of this vertex. // Transform the points, and compute the position of this vertex.
vec2 position; vec2 position;
@ -52,9 +51,12 @@ void main() {
aQuadPosition, aQuadPosition,
uFramebufferSize, uFramebufferSize,
transform, transform,
uTransformST,
hints)) { hints)) {
controlPointPosition = hintPosition(controlPointPosition, hints); controlPointPosition = hintPosition(controlPointPosition, hints);
controlPointPosition = transformVertexPositionST(controlPointPosition, transform); controlPointPosition = transformVertexPositionST(controlPointPosition, transform);
controlPointPosition = transformVertexPositionST(controlPointPosition, uTransformST);
controlPointPosition = convertClipToScreenSpace(controlPointPosition, uFramebufferSize);
} }
float depth = convertPathIndexToViewportDepthValue(pathID); float depth = convertPathIndexToViewportDepthValue(pathID);

View File

@ -4,8 +4,7 @@
precision highp float; precision highp float;
uniform mat4 uTransform; uniform vec4 uTransformST;
uniform float uScaleX;
uniform ivec2 uFramebufferSize; uniform ivec2 uFramebufferSize;
uniform ivec2 uBVertexPositionDimensions; uniform ivec2 uBVertexPositionDimensions;
uniform ivec2 uBVertexPathIDDimensions; uniform ivec2 uBVertexPathIDDimensions;
@ -37,7 +36,6 @@ void main() {
vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions); vec4 hints = fetchFloat4Data(uPathHints, pathID, uPathHintsDimensions);
vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions); vec4 transform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
transform.xz *= uScaleX;
// Transform the points, and compute the position of this vertex. // Transform the points, and compute the position of this vertex.
vec2 position; vec2 position;
@ -47,6 +45,7 @@ void main() {
aQuadPosition, aQuadPosition,
uFramebufferSize, uFramebufferSize,
transform, transform,
uTransformST,
hints); hints);
float depth = convertPathIndexToViewportDepthValue(pathID); float depth = convertPathIndexToViewportDepthValue(pathID);