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">
<label for="pf-aa-level-select">Antialiasing</label>
<select id="pf-aa-level-select" class="form-control custom-select">
<option value="none" selected>None</option>
<option value="ssaa-2">2&times;SSAA (BROKEN)</option>
<option value="ssaa-4">4&times;SSAA (BROKEN)</option>
<option value="none">None</option>
<option value="ssaa-2">2&times;SSAA</option>
<option value="ssaa-4" selected>4&times;SSAA</option>
</select>
</div>
</form>

View File

@ -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<ThreeDView> {
});
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;

View File

@ -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) {

View File

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

View File

@ -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<void> {

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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)),

View File

@ -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);

View File

@ -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);