Stop using multiple render targets.

We don't need them anymore, so let's lower our hardware requirements!
This commit is contained in:
Patrick Walton 2017-10-20 22:04:53 -07:00
parent 048c261f6c
commit 9d93cebca6
18 changed files with 266 additions and 200 deletions

View File

@ -15,13 +15,15 @@ import {DemoView} from './view';
export type AntialiasingStrategyName = 'none' | 'ssaa' | 'xcaa';
export type DirectRenderingMode = 'none' | 'color' | 'pathID';
export type SubpixelAAType = 'none' | 'medium';
export type StemDarkeningMode = 'none' | 'dark';
export abstract class AntialiasingStrategy {
// True if direct rendering should occur.
shouldRenderDirect: boolean;
// The type of direct rendering that should occur, if any.
abstract readonly directRenderingMode: DirectRenderingMode;
// Prepares any OpenGL data. This is only called on startup and canvas resize.
init(renderer: Renderer): void {
@ -82,7 +84,7 @@ export class NoAAStrategy extends AntialiasingStrategy {
resolve(renderer: Renderer) {}
get shouldRenderDirect() {
return true;
get directRenderingMode(): DirectRenderingMode {
return 'color';
}
}

View File

@ -95,21 +95,17 @@ export function setTextureParameters(gl: WebGLRenderingContext, filter: number)
}
export function createFramebuffer(gl: WebGLRenderingContext,
drawBuffersExt: WebGLDrawBuffers,
colorAttachments: WebGLTexture[],
colorAttachment: WebGLTexture,
depthAttachment: WebGLTexture | null):
WebGLFramebuffer {
const framebuffer = unwrapNull(gl.createFramebuffer());
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
const colorAttachmentCount = colorAttachments.length;
for (let colorAttachmentIndex = 0;
colorAttachmentIndex < colorAttachmentCount;
colorAttachmentIndex++) {
const glEnum = (drawBuffersExt as any)[`COLOR_ATTACHMENT${colorAttachmentIndex}_WEBGL`];
const attachment = colorAttachments[colorAttachmentIndex];
gl.framebufferTexture2D(gl.FRAMEBUFFER, glEnum, gl.TEXTURE_2D, attachment, 0);
}
gl.framebufferTexture2D(gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
colorAttachment,
0);
if (depthAttachment != null) {
gl.framebufferTexture2D(gl.FRAMEBUFFER,

View File

@ -119,7 +119,7 @@ export abstract class Renderer {
this.drawSceneryIfNecessary();
// Perform direct rendering (Loop-Blinn).
if (antialiasingStrategy.shouldRenderDirect)
if (antialiasingStrategy.directRenderingMode !== 'none')
this.renderDirect();
// Antialias.
@ -263,29 +263,26 @@ export abstract class Renderer {
protected drawSceneryIfNecessary(): void {}
protected clearForDirectRendering(): void {
const renderingMode = unwrapNull(this.antialiasingStrategy).directRenderingMode;
const renderContext = this.renderContext;
const gl = renderContext.gl;
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
]);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clearDepth(0.0);
gl.depthMask(true);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Clear out the path ID buffer.
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.gl.NONE,
renderContext.drawBuffersExt.COLOR_ATTACHMENT1_WEBGL,
]);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT);
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
renderContext.drawBuffersExt.COLOR_ATTACHMENT1_WEBGL,
]);
switch (renderingMode) {
case 'color':
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clearDepth(0.0);
gl.depthMask(true);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
break;
case 'pathID':
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clearDepth(0.0);
gl.depthMask(true);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
break;
case 'none':
// Nothing to do.
}
}
protected getModelviewTransform(pathIndex: number): glmatrix.mat4 {
@ -301,7 +298,10 @@ export abstract class Renderer {
protected newTimingsReceived() {}
private renderDirect() {
const renderingMode = unwrapNull(this.antialiasingStrategy).directRenderingMode;
const renderContext = this.renderContext;
const gl = renderContext.gl;
for (let objectIndex = 0; objectIndex < this.meshes.length; objectIndex++) {
const instanceRange = this.instanceRangeForObject(objectIndex);
if (instanceRange.isEmpty)
@ -310,10 +310,10 @@ export abstract class Renderer {
const meshes = this.meshes[objectIndex];
// Set up implicit cover state.
renderContext.gl.depthFunc(this.depthFunction);
renderContext.gl.depthMask(true);
renderContext.gl.enable(renderContext.gl.DEPTH_TEST);
renderContext.gl.disable(renderContext.gl.BLEND);
gl.depthFunc(this.depthFunction);
gl.depthMask(true);
gl.enable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
// Set up the implicit cover interior VAO.
const directInteriorProgram =
@ -329,35 +329,27 @@ export abstract class Renderer {
this.setTransformUniform(directInteriorProgram.uniforms, objectIndex);
this.setFramebufferSizeUniform(directInteriorProgram.uniforms);
this.setHintsUniform(directInteriorProgram.uniforms);
this.setPathColorsUniform(objectIndex, directInteriorProgram.uniforms, 0);
this.pathTransformBufferTextures[objectIndex].bind(renderContext.gl,
directInteriorProgram.uniforms,
1);
let indexCount =
renderContext.gl.getBufferParameter(renderContext.gl.ELEMENT_ARRAY_BUFFER,
renderContext.gl.BUFFER_SIZE) / UINT32_SIZE;
if (renderingMode === 'color')
this.setPathColorsUniform(objectIndex, directInteriorProgram.uniforms, 0);
this.pathTransformBufferTextures[objectIndex]
.bind(gl, directInteriorProgram.uniforms, 1);
let indexCount = gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE) /
UINT32_SIZE;
if (!this.pathIDsAreInstanced) {
renderContext.gl.drawElements(renderContext.gl.TRIANGLES,
indexCount,
renderContext.gl.UNSIGNED_INT,
0);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_INT, 0);
} else {
renderContext.instancedArraysExt
.drawElementsInstancedANGLE(renderContext.gl.TRIANGLES,
indexCount,
renderContext.gl.UNSIGNED_INT,
0,
instanceRange.length);
renderContext.instancedArraysExt.drawElementsInstancedANGLE(gl.TRIANGLES,
indexCount,
gl.UNSIGNED_INT,
0,
instanceRange.length);
}
// Set up direct curve state.
renderContext.gl.depthMask(false);
renderContext.gl.enable(renderContext.gl.BLEND);
renderContext.gl.blendEquation(renderContext.gl.FUNC_ADD);
renderContext.gl.blendFuncSeparate(renderContext.gl.SRC_ALPHA,
renderContext.gl.ONE_MINUS_SRC_ALPHA,
renderContext.gl.ONE,
renderContext.gl.ONE);
gl.depthMask(false);
gl.enable(gl.BLEND);
gl.blendEquation(gl.FUNC_ADD);
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE);
// Set up the direct curve VAO.
//
@ -374,28 +366,19 @@ export abstract class Renderer {
this.setTransformUniform(directCurveProgram.uniforms, objectIndex);
this.setFramebufferSizeUniform(directCurveProgram.uniforms);
this.setHintsUniform(directCurveProgram.uniforms);
this.pathColorsBufferTextures[objectIndex].bind(renderContext.gl,
directCurveProgram.uniforms,
0);
this.setPathColorsUniform(objectIndex, directCurveProgram.uniforms, 0);
this.pathTransformBufferTextures[objectIndex].bind(renderContext.gl,
directCurveProgram.uniforms,
1);
indexCount =
renderContext.gl.getBufferParameter(renderContext.gl.ELEMENT_ARRAY_BUFFER,
renderContext.gl.BUFFER_SIZE) / UINT32_SIZE;
if (renderingMode === 'color')
this.setPathColorsUniform(objectIndex, directCurveProgram.uniforms, 0);
this.pathTransformBufferTextures[objectIndex].bind(gl, directCurveProgram.uniforms, 1);
indexCount = gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE) /
UINT32_SIZE;
if (!this.pathIDsAreInstanced) {
renderContext.gl.drawElements(renderContext.gl.TRIANGLES,
indexCount,
renderContext.gl.UNSIGNED_INT,
0);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_INT, 0);
} else {
renderContext.instancedArraysExt
.drawElementsInstancedANGLE(renderContext.gl.TRIANGLES,
indexCount,
renderContext.gl.UNSIGNED_INT,
0,
instanceRange.length);
renderContext.instancedArraysExt.drawElementsInstancedANGLE(gl.TRIANGLES,
indexCount,
gl.UNSIGNED_INT,
0,
instanceRange.length);
}
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);

View File

@ -11,6 +11,28 @@
import {AttributeMap, UniformMap} from './gl-utils';
import {expectNotNull, PathfinderError, unwrapNull} from './utils';
export interface ShaderMap<T> {
blit: T;
demo3DDistantGlyph: T;
demo3DMonument: T;
directCurve: T;
directInterior: T;
direct3DCurve: T;
direct3DInterior: T;
ecaaLine: T;
ecaaCurve: T;
mcaaCover: T;
mcaaLine: T;
mcaaCurve: T;
ssaaSubpixelResolve: T;
xcaaEdgeDetect: T;
xcaaMonoResolve: T;
xcaaMonoSubpixelResolve: T;
xcaaMultiDirectCurve: T;
xcaaMultiDirectInterior: T;
xcaaMultiResolve: T;
}
export interface UnlinkedShaderProgram {
vertex: WebGLShader;
fragment: WebGLShader;
@ -33,6 +55,8 @@ export const SHADER_NAMES: Array<keyof ShaderMap<void>> = [
'ecaaCurve',
'xcaaMonoResolve',
'xcaaMonoSubpixelResolve',
'xcaaMultiDirectCurve',
'xcaaMultiDirectInterior',
'xcaaMultiResolve',
'demo3DDistantGlyph',
'demo3DMonument',
@ -103,32 +127,20 @@ const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
fragment: "/glsl/gles2/xcaa-mono-subpixel-resolve.fs.glsl",
vertex: "/glsl/gles2/xcaa-mono-subpixel-resolve.vs.glsl",
},
xcaaMultiDirectCurve: {
fragment: "/glsl/gles2/xcaa-multi-direct-curve.fs.glsl",
vertex: "/glsl/gles2/xcaa-multi-direct-curve.vs.glsl",
},
xcaaMultiDirectInterior: {
fragment: "/glsl/gles2/xcaa-multi-direct-interior.fs.glsl",
vertex: "/glsl/gles2/xcaa-multi-direct-interior.vs.glsl",
},
xcaaMultiResolve: {
fragment: "/glsl/gles2/xcaa-multi-resolve.fs.glsl",
vertex: "/glsl/gles2/xcaa-multi-resolve.vs.glsl",
},
};
export interface ShaderMap<T> {
blit: T;
demo3DDistantGlyph: T;
demo3DMonument: T;
directCurve: T;
directInterior: T;
direct3DCurve: T;
direct3DInterior: T;
ecaaLine: T;
ecaaCurve: T;
mcaaCover: T;
mcaaLine: T;
mcaaCurve: T;
ssaaSubpixelResolve: T;
xcaaEdgeDetect: T;
xcaaMonoResolve: T;
xcaaMonoSubpixelResolve: T;
xcaaMultiResolve: T;
}
export interface ShaderProgramSource {
vertex: string;
fragment: string;

View File

@ -10,7 +10,7 @@
import * as glmatrix from 'gl-matrix';
import {AntialiasingStrategy, SubpixelAAType} from './aa-strategy';
import {AntialiasingStrategy, DirectRenderingMode, SubpixelAAType} from './aa-strategy';
import {createFramebuffer, createFramebufferDepthTexture, setTextureParameters} from './gl-utils';
import {Renderer} from './renderer';
import {unwrapNull} from './utils';
@ -64,8 +64,7 @@ export default class SSAAStrategy extends AntialiasingStrategy {
createFramebufferDepthTexture(renderContext.gl, this.supersampledFramebufferSize);
this.supersampledFramebuffer = createFramebuffer(renderContext.gl,
renderContext.drawBuffersExt,
[this.supersampledColorTexture],
this.supersampledColorTexture,
this.supersampledDepthTexture);
renderContext.gl.bindFramebuffer(renderContext.gl.FRAMEBUFFER, null);
@ -128,8 +127,8 @@ export default class SSAAStrategy extends AntialiasingStrategy {
0);
}
get shouldRenderDirect() {
return true;
get directRenderingMode(): DirectRenderingMode {
return 'color';
}
private get supersampleScale(): glmatrix.vec2 {

View File

@ -157,7 +157,7 @@ class SVGDemoRenderer extends Renderer {
this.camera.zoomToFit();
}
protected get depthFunction(): number {
protected get depthFunction(): GLenum {
return this.renderContext.gl.GREATER;
}
@ -180,10 +180,14 @@ class SVGDemoRenderer extends Renderer {
}
protected get directCurveProgramName(): keyof ShaderMap<void> {
if (this.antialiasingStrategy instanceof XCAAStrategy)
return 'xcaaMultiDirectCurve';
return 'directCurve';
}
protected get directInteriorProgramName(): keyof ShaderMap<void> {
if (this.antialiasingStrategy instanceof XCAAStrategy)
return 'xcaaMultiDirectInterior';
return 'directInterior';
}

View File

@ -181,8 +181,7 @@ export abstract class TextRenderer extends Renderer {
const atlasColorTexture = this.renderContext.atlas.ensureTexture(this.renderContext);
this.atlasDepthTexture = createFramebufferDepthTexture(this.renderContext.gl, ATLAS_SIZE);
this.atlasFramebuffer = createFramebuffer(this.renderContext.gl,
this.renderContext.drawBuffersExt,
[atlasColorTexture],
atlasColorTexture,
this.atlasDepthTexture);
// Allow the antialiasing strategy to set up framebuffers as necessary.

View File

@ -115,7 +115,6 @@ export abstract class DemoView extends PathfinderView implements RenderContext {
shaderPrograms: ShaderMap<PathfinderShaderProgram>;
drawBuffersExt: WebGLDrawBuffers;
instancedArraysExt: ANGLEInstancedArrays;
textureHalfFloatExt: OESTextureHalfFloat;
timerQueryExt: EXTDisjointTimerQuery;
@ -192,7 +191,6 @@ export abstract class DemoView extends PathfinderView implements RenderContext {
// Initialize the OpenGL context.
this.gl = expectNotNull(this.canvas.getContext('webgl', { antialias: false, depth: true }),
"Failed to initialize WebGL! Check that your browser supports it.");
this.drawBuffersExt = this.gl.getExtension('WEBGL_draw_buffers');
this.colorBufferHalfFloatExt = this.gl.getExtension('EXT_color_buffer_half_float');
this.instancedArraysExt = this.gl.getExtension('ANGLE_instanced_arrays');
this.sRGBExt = this.gl.getExtension('EXT_sRGB');
@ -303,8 +301,6 @@ export interface RenderContext {
/// The OpenGL context.
readonly gl: WebGLRenderingContext;
/// The `WEBGL_draw_buffers` extension.
readonly drawBuffersExt: WebGLDrawBuffers;
readonly instancedArraysExt: ANGLEInstancedArrays;
readonly textureHalfFloatExt: OESTextureHalfFloat;
readonly timerQueryExt: EXTDisjointTimerQuery;

View File

@ -11,7 +11,7 @@
import * as glmatrix from 'gl-matrix';
import * as _ from 'lodash';
import {AntialiasingStrategy, SubpixelAAType} from './aa-strategy';
import {AntialiasingStrategy, DirectRenderingMode, SubpixelAAType} from './aa-strategy';
import PathfinderBufferTexture from './buffer-texture';
import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
import {createFramebufferDepthTexture, setTextureParameters, UniformMap} from './gl-utils';
@ -33,10 +33,9 @@ type Direction = 'upper' | 'lower';
const DIRECTIONS: Direction[] = ['upper', 'lower'];
export abstract class XCAAStrategy extends AntialiasingStrategy {
abstract shouldRenderDirect: boolean;
abstract readonly directRenderingMode: DirectRenderingMode;
protected directColorTexture: WebGLTexture;
protected directPathIDTexture: WebGLTexture;
protected directTexture: WebGLTexture;
protected aaDepthTexture: WebGLTexture;
protected pathBoundsBufferTexture: PathfinderBufferTexture;
@ -87,40 +86,22 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
prepare(renderer: Renderer) {
const renderContext = renderer.renderContext;
const gl = renderContext.gl;
const usedSize = this.supersampledUsedSize(renderer);
renderContext.gl.bindFramebuffer(renderContext.gl.FRAMEBUFFER, this.directFramebuffer);
renderContext.gl.viewport(0,
0,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1]);
renderContext.gl.scissor(0, 0, usedSize[0], usedSize[1]);
renderContext.gl.enable(renderContext.gl.SCISSOR_TEST);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.directFramebuffer);
gl.viewport(0,
0,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1]);
gl.scissor(0, 0, usedSize[0], usedSize[1]);
gl.enable(gl.SCISSOR_TEST);
// Clear out the color and depth textures.
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
renderContext.gl.NONE,
]);
renderContext.gl.clearColor(1.0, 1.0, 1.0, 1.0);
renderContext.gl.clearDepth(0.0);
renderContext.gl.depthMask(true);
renderContext.gl.clear(renderContext.gl.COLOR_BUFFER_BIT |
renderContext.gl.DEPTH_BUFFER_BIT);
// Clear out the path ID texture.
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.gl.NONE,
renderContext.drawBuffersExt.COLOR_ATTACHMENT1_WEBGL,
]);
renderContext.gl.clearColor(0.0, 0.0, 0.0, 0.0);
renderContext.gl.clear(renderContext.gl.COLOR_BUFFER_BIT);
// Render to both textures.
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
renderContext.drawBuffersExt.COLOR_ATTACHMENT1_WEBGL,
]);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clearDepth(0.0);
gl.depthMask(true);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}
antialias(renderer: Renderer) {
@ -145,17 +126,20 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
protected initDirectFramebuffer(renderer: Renderer) {
const renderContext = renderer.renderContext;
this.directColorTexture = createFramebufferColorTexture(renderContext.gl,
this.destFramebufferSize,
renderContext.colorAlphaFormat);
this.directPathIDTexture = createFramebufferColorTexture(renderContext.gl,
this.destFramebufferSize,
renderContext.gl.RGBA);
this.directFramebuffer =
createFramebuffer(renderContext.gl,
renderContext.drawBuffersExt,
[this.directColorTexture, this.directPathIDTexture],
this.directDepthTexture);
const gl = renderContext.gl;
let textureFormat;
if (this.directRenderingMode === 'pathID')
textureFormat = gl.RGBA;
else
textureFormat = renderContext.colorAlphaFormat;
this.directTexture = createFramebufferColorTexture(gl,
this.destFramebufferSize,
textureFormat);
this.directFramebuffer = createFramebuffer(renderContext.gl,
this.directTexture,
this.directDepthTexture);
}
protected supersampledUsedSize(renderer: Renderer): glmatrix.vec2 {
@ -214,12 +198,6 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
gl.enable(gl.SCISSOR_TEST);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
if (renderer.destFramebuffer != null) {
renderContext.drawBuffersExt
.drawBuffersWEBGL([renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL]);
} else {
renderContext.drawBuffersExt.drawBuffersWEBGL([gl.BACK]);
}
// Clear out the resolve buffer, if necessary.
this.clearForResolve(renderer);
@ -272,8 +250,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
this.supersampledFramebufferSize);
this.aaFramebuffer = createFramebuffer(renderContext.gl,
renderContext.drawBuffersExt,
[this.aaAlphaTexture],
this.aaAlphaTexture,
this.aaDepthTexture);
}
@ -647,8 +624,8 @@ export class ECAAStrategy extends XCAAStrategy {
private lineVAO: WebGLVertexArrayObject;
private curveVAO: WebGLVertexArrayObject;
get shouldRenderDirect() {
return false;
get directRenderingMode(): DirectRenderingMode {
return 'none';
}
attachMeshes(renderer: Renderer) {
@ -952,8 +929,8 @@ export class MCAAMonochromeStrategy extends MCAAStrategy {
renderContext.gl.clear(renderContext.gl.COLOR_BUFFER_BIT);
}
get shouldRenderDirect() {
return false;
get directRenderingMode(): DirectRenderingMode {
return 'none';
}
}
@ -964,8 +941,8 @@ export class AdaptiveMonochromeXCAAStrategy implements AntialiasingStrategy {
private mcaaStrategy: MCAAMonochromeStrategy;
private ecaaStrategy: ECAAStrategy;
get shouldRenderDirect(): boolean {
return false;
get directRenderingMode(): DirectRenderingMode {
return 'none';
}
constructor(level: number, subpixelAA: SubpixelAAType) {
@ -1035,8 +1012,7 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
this.supersampledFramebufferSize,
renderContext.gl.RGBA);
this.edgeDetectFramebuffer = createFramebuffer(renderContext.gl,
renderContext.drawBuffersExt,
[this.edgePathIDTexture],
this.edgePathIDTexture,
this.aaDepthTexture);
}
@ -1063,10 +1039,6 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1]);
renderContext.drawBuffersExt.drawBuffersWEBGL([
renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL,
]);
gl.depthMask(true);
gl.depthFunc(renderContext.gl.ALWAYS);
gl.enable(renderContext.gl.DEPTH_TEST);
@ -1083,7 +1055,7 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
renderer.setTransformSTAndTexScaleUniformsForDest(edgeDetectProgram.uniforms);
renderer.setPathColorsUniform(0, edgeDetectProgram.uniforms, 0);
gl.activeTexture(renderContext.gl.TEXTURE1);
gl.bindTexture(renderContext.gl.TEXTURE_2D, this.directPathIDTexture);
gl.bindTexture(renderContext.gl.TEXTURE_2D, this.directTexture);
gl.uniform1i(edgeDetectProgram.uniforms.uPathID, 1);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderContext.quadElementsBuffer);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
@ -1103,12 +1075,6 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
renderContext.gl.enable(renderContext.gl.SCISSOR_TEST);
renderContext.gl.disable(renderContext.gl.DEPTH_TEST);
renderContext.gl.disable(renderContext.gl.BLEND);
if (renderer.destFramebuffer != null) {
renderContext.drawBuffersExt
.drawBuffersWEBGL([renderContext.drawBuffersExt.COLOR_ATTACHMENT0_WEBGL]);
} else {
renderContext.drawBuffersExt.drawBuffersWEBGL([renderContext.gl.BACK]);
}
// Resolve.
const resolveProgram = this.getResolveProgram(renderContext);
@ -1157,8 +1123,8 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
protected clearForResolve(renderer: Renderer) {}
get shouldRenderDirect() {
return true;
get directRenderingMode(): DirectRenderingMode {
return 'pathID';
}
protected get directDepthTexture(): WebGLTexture {

View File

@ -10,7 +10,6 @@
#version 100
#extension GL_EXT_draw_buffers : require
#extension GL_EXT_frag_depth : require
#define LCD_FILTER_FACTOR_0 (86.0 / 255.0)

View File

@ -13,13 +13,11 @@
precision highp float;
varying vec4 vColor;
varying vec2 vPathID;
varying vec2 vTexCoord;
varying float vSign;
void main() {
float side = vTexCoord.x * vTexCoord.x - vTexCoord.y;
float alpha = float(sign(side) == sign(vSign));
gl_FragData[0] = vec4(vColor.rgb, vColor.a * alpha);
gl_FragData[1] = vec4(vPathID, 0.0, alpha);
gl_FragColor = vec4(vColor.rgb, vColor.a * alpha);
}

View File

@ -23,7 +23,6 @@ attribute float aPathID;
attribute float aSign;
varying vec4 vColor;
varying vec2 vPathID;
varying vec2 vTexCoord;
varying float vSign;
@ -40,7 +39,6 @@ void main() {
gl_Position = vec4(position, depth, 1.0);
vColor = fetchFloat4Data(uPathColors, pathID, uPathColorsDimensions);
vPathID = packPathID(pathID);
vTexCoord = vec2(aTexCoord) / 2.0;
vSign = aSign;
}

View File

@ -11,9 +11,7 @@
precision highp float;
varying vec4 vColor;
varying vec2 vPathID;
void main() {
gl_FragData[0] = vColor;
gl_FragData[1] = vec4(vPathID, 0.0, 1.0);
gl_FragColor = vColor;
}

View File

@ -21,7 +21,6 @@ attribute vec2 aPosition;
attribute float aPathID;
varying vec4 vColor;
varying vec2 vPathID;
void main() {
int pathID = int(aPathID);
@ -36,5 +35,4 @@ void main() {
gl_Position = vec4(position, depth, 1.0);
vColor = fetchFloat4Data(uPathColors, pathID, uPathColorsDimensions);
vPathID = packPathID(pathID);
}

View File

@ -0,0 +1,23 @@
// pathfinder/shaders/gles2/xcaa-multi-direct-curve.fs.glsl
//
// Copyright (c) 2017 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// This shader implements the quadratic Loop-Blinn formulation.
precision highp float;
varying vec2 vPathID;
varying vec2 vTexCoord;
varying float vSign;
void main() {
float side = vTexCoord.x * vTexCoord.x - vTexCoord.y;
float alpha = float(sign(side) == sign(vSign));
gl_FragColor = vec4(vPathID, 0.0, alpha);
}

View File

@ -0,0 +1,42 @@
// pathfinder/shaders/gles2/xcaa-multi-direct-curve.vs.glsl
//
// Copyright (c) 2017 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
precision highp float;
uniform mat4 uTransform;
uniform vec4 uHints;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
attribute vec2 aPosition;
attribute vec2 aTexCoord;
attribute float aPathID;
attribute float aSign;
varying vec2 vPathID;
varying vec2 vTexCoord;
varying float vSign;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 position = hintPosition(aPosition, uHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPosition(position, uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);
gl_Position = vec4(position, depth, 1.0);
vPathID = packPathID(pathID);
vTexCoord = vec2(aTexCoord) / 2.0;
vSign = aSign;
}

View File

@ -0,0 +1,17 @@
// pathfinder/shaders/gles2/xcaa-multi-direct-interior.fs.glsl
//
// Copyright (c) 2017 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
precision highp float;
varying vec2 vPathID;
void main() {
gl_FragColor = vec4(vPathID, 0.0, 1.0);
}

View File

@ -0,0 +1,36 @@
// pathfinder/shaders/gles2/xcaa-multi-direct-interior.vs.glsl
//
// Copyright (c) 2017 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
precision highp float;
uniform mat4 uTransform;
uniform vec4 uHints;
uniform ivec2 uPathTransformDimensions;
uniform sampler2D uPathTransform;
attribute vec2 aPosition;
attribute float aPathID;
varying vec2 vPathID;
void main() {
int pathID = int(aPathID);
vec4 pathTransform = fetchFloat4Data(uPathTransform, pathID, uPathTransformDimensions);
vec2 position = hintPosition(aPosition, uHints);
position = transformVertexPositionST(position, pathTransform);
position = transformVertexPosition(position, uTransform);
float depth = convertPathIndexToViewportDepthValue(pathID);
gl_Position = vec4(position, depth, 1.0);
vPathID = packPathID(pathID);
}