Skip to content

Commit

Permalink
refactored blending and color masking
Browse files Browse the repository at this point in the history
Signed-off-by: Tim Deubler <[email protected]>
  • Loading branch information
TerminalTim committed Jul 27, 2023
1 parent d457888 commit 7d95b74
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 84 deletions.
85 changes: 42 additions & 43 deletions packages/display/src/displays/webgl/GLRender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ export class GLRender implements BasicRender {
stencilTile.pass = PASS.ALPHA;
// need to be set to enable stencil test in program init.
stencilTile.blend = true;

stencilTile.colorMask = {r: false, g: false, b: false, a: false};

this.stencilTile = stencilTile;
}

Expand Down Expand Up @@ -220,14 +223,10 @@ export class GLRender implements BasicRender {
if (clearColor) {
this.setBackgroundColor(clearColor);
}
// gl.clearDepth(1.0);
gl.colorMask(true, true, true, true);
gl.disable(gl.SCISSOR_TEST);
gl.depthMask(true);


gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
gl.colorMask(true, true, true, false);
}

init(canvas: HTMLCanvasElement, devicePixelRation: number): void {
Expand Down Expand Up @@ -548,43 +547,43 @@ export class GLRender implements BasicRender {
}


initGroundDepth(x: number, y: number, tileScale?: number
) {
const gl = this.gl;
const buffer = this.stencilTile;
let program = this.programs[buffer.type];

let bufAttributes = buffer.getAttributes();
program.initBuffers(bufAttributes);

this.useProgram(program);

gl.depthRange(0, 1.0);

gl.depthMask(true);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.SCISSOR_TEST);
gl.enable(gl.DEPTH_TEST);

program.initAttributes(bufAttributes);
program.initUniforms(buffer.uniforms);

const uLocation = program.uniforms;

gl.uniform2f(uLocation.u_topLeft, x, y);
gl.uniform1f(uLocation.u_tileScale, tileScale || 1);
gl.uniformMatrix4fv(uLocation.u_matrix, false, this.vPMat);

gl.clear(gl.DEPTH_BUFFER_BIT);
gl.depthFunc(gl.ALWAYS);
// gl.polygonOffset(1, 1);
// gl.enable(gl.POLYGON_OFFSET_FILL);
gl.colorMask(false, false, false, false);
program.draw(buffer);
gl.colorMask(true, true, true, false);
// gl.disable(gl.POLYGON_OFFSET_FILL);
gl.depthFunc(this.depthFnc);
}
// initGroundDepth(x: number, y: number, tileScale?: number
// ) {
// const gl = this.gl;
// const buffer = this.stencilTile;
// let program = this.programs[buffer.type];
//
// let bufAttributes = buffer.getAttributes();
// program.initBuffers(bufAttributes);
//
// this.useProgram(program);
//
// gl.depthRange(0, 1.0);
//
// gl.depthMask(true);
// gl.disable(gl.STENCIL_TEST);
// gl.disable(gl.SCISSOR_TEST);
// gl.enable(gl.DEPTH_TEST);
//
// program.initAttributes(bufAttributes);
// program.initUniforms(buffer.uniforms);
//
// const uLocation = program.uniforms;
//
// gl.uniform2f(uLocation.u_topLeft, x, y);
// gl.uniform1f(uLocation.u_tileScale, tileScale || 1);
// gl.uniformMatrix4fv(uLocation.u_matrix, false, this.vPMat);
//
// gl.clear(gl.DEPTH_BUFFER_BIT);
// gl.depthFunc(gl.ALWAYS);
// // gl.polygonOffset(1, 1);
// // gl.enable(gl.POLYGON_OFFSET_FILL);
// gl.colorMask(false, false, false, false);
// program.draw(buffer);
// gl.colorMask(true, true, true, false);
// // gl.disable(gl.POLYGON_OFFSET_FILL);
// gl.depthFunc(this.depthFnc);
// }


private drawBuffer(
Expand Down Expand Up @@ -693,15 +692,15 @@ export class GLRender implements BasicRender {
gl.stencilFunc(gl.ALWAYS, refVal, 0xff);
gl.stencilOp(gl.REPLACE, gl.REPLACE, gl.REPLACE);
// disable color buffer
gl.colorMask(false, false, false, false);
// gl.colorMask(false, false, false, false);

this.drawBuffer(stencilTile, x, y, null, null, this.stencilSize);

gl.stencilFunc(gl.EQUAL, refVal, 0xff);
// disable writing to stencil buffer
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
// enable color buffer again
gl.colorMask(true, true, true, false);
// gl.colorMask(true, true, true, false);
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/display/src/displays/webgl/buffer/GeometryBuffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class GeometryBuffer {
hitTest?: number;


colorMask?: { r: boolean, g: boolean, b: boolean, a: boolean };

static fromTemplateBuffer(type: string, templBuffer: TemplateBuffer): GeometryBuffer {
const {flexAttributes} = templBuffer;
let geoBuffer: GeometryBuffer;
Expand Down
4 changes: 1 addition & 3 deletions packages/display/src/displays/webgl/program/DashedLine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,9 @@ class DashedLineProgram extends Program {
this.fragmentShaderSrc = fragmentShader;
}

initGeometryBuffer(options: GeometryBuffer, pass, stencil: boolean) {
protected blendFunc(sFactor?: number, dFactor?: number) {
const {gl} = this;
super.initGeometryBuffer(options, pass, stencil);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
// gl.depthFunc(gl.LESS);
}
}

Expand Down
21 changes: 0 additions & 21 deletions packages/display/src/displays/webgl/program/Heatmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,9 @@ class HeatmapProgram extends Program {
const {width, height} = offscreen.texture;
this.bindFramebuffer(offscreen.framebuffer, width, height);

const p = this._pass;
this._pass = PASS.OPAQUE;

gl.blendFunc(gl.ONE, gl.ONE);

super.draw(geoBuffer);
this._pass = p;
} else {
// render offscreen-buffer to screen-buffer and colorize the heatmap.
const {offscreenBuffer} = this;
Expand All @@ -144,27 +140,14 @@ class HeatmapProgram extends Program {
this.initGeometryBuffer(offscreenBuffer, PASS.ALPHA, false);

this.bindFramebuffer(null);
// this.gl.colorMask(true, true, true, false);
// this.gl.colorMask(true, true, true, false);
// this.gl.colorMask(true, true, true, true);

// this.gl.disable(this.gl.STENCIL_TEST);

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
// this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
super.draw(offscreenBuffer);

// this.gl.colorMask(true, true, true, false);

// clear offscreen buffer for next frame
this.clear();
}

this.bindFramebuffer(null);

gl.disable(gl.BLEND);
gl.colorMask(true, true, true, false);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
}

private clear() {
Expand All @@ -182,11 +165,7 @@ class HeatmapProgram extends Program {
// gl.depthMask(true);
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.colorMask(true, true, true, false);

this.bindFramebuffer(null);
// gl.disable(gl.BLEND);
gl.colorMask(true, true, true, false);
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
}

setResolution(resolution: readonly number[]) {
Expand Down
5 changes: 2 additions & 3 deletions packages/display/src/displays/webgl/program/Icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ class IconProgram extends Program {
this.fragmentShaderSrc = fragmentShader;
}

initGeometryBuffer(options: GeometryBuffer, pass: PASS, stencil: boolean) {
protected blendFunc() {
const {gl} = this;
super.initGeometryBuffer(options, pass, stencil);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
super.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
}
}

Expand Down
38 changes: 26 additions & 12 deletions packages/display/src/displays/webgl/program/Program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,23 @@ import {ArrayGrp, GeometryBuffer, IndexData, IndexGrp} from '../buffer/GeometryB
import {BufferCache} from '../GLRender';
import {Attribute} from '../buffer/Attribute';
import {ConstantAttribute, FlexAttribute} from '../buffer/templates/TemplateBuffer';
import {DEFAULT_HEATMAP_GRADIENT} from '../buffer/templates/HeatmapBuffer';

let UNDEF;

type UniformMap = { [name: string]: WebGLUniformLocation };
type AttributeMap = { [name: string]: Attribute | ConstantAttribute };

type ColorMask = { r: boolean; g: boolean; b: boolean; a: boolean };

const DEFAULT_COLOR_MASK: ColorMask = {
r: true, g: true, b: true, a: false
};

const NO_COLOR_MASK: ColorMask = {
r: false, g: false, b: false, a: false
};

class Program {
protected vertexShaderSrc: string;
protected fragmentShaderSrc: string;
Expand Down Expand Up @@ -347,7 +358,6 @@ class Program {
draw(geoBuffer: GeometryBuffer) {
const {gl} = this;
const {groups, instances} = geoBuffer;
const isDepthOnlyPass = this._pass == PASS.ALPHA && geoBuffer.pass & PASS.POST_ALPHA;

// console.log(
// this.name,
Expand All @@ -357,11 +367,6 @@ class Program {
// 'BLEND', gl.getParameter(gl.BLEND)
// );

if (isDepthOnlyPass) {
// disable color mask for depth/stencil only pass
gl.colorMask(false, false, false, false);
}

for (let grp of groups) {
let mode = grp.mode != UNDEF ? grp.mode : this.mode;

Expand Down Expand Up @@ -392,11 +397,6 @@ class Program {
}
}
}

if (isDepthOnlyPass) {
// re-enable color mask
gl.colorMask(true, true, true, false);
}
};

private setStates(scissor: boolean, blend: boolean, depth: boolean, stencil: boolean) {
Expand Down Expand Up @@ -427,6 +427,13 @@ class Program {
}
}

protected blendFunc(
sFactor: number = this.gl.SRC_ALPHA,
dFactor: number = this.gl.ONE_MINUS_SRC_ALPHA
) {
this.gl.blendFunc(sFactor, dFactor);
}

initGeometryBuffer(geoBuffer: GeometryBuffer, pass: PASS, stencil: boolean, zIndex?: number) {
const prog = this;
const {gl} = prog;
Expand All @@ -447,7 +454,7 @@ class Program {
}
prog.setStates(scissor, blend, depth, stencil && !opaquePass && blend && scissor);

gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
this.blendFunc();

const cullFace = geoBuffer.cullFace();

Expand All @@ -458,6 +465,13 @@ class Program {
gl.disable(gl.CULL_FACE);
}

const isDepthPrePass = pass == PASS.ALPHA && geoBuffer.pass & PASS.POST_ALPHA;

const colorMask = isDepthPrePass
? NO_COLOR_MASK
: geoBuffer.colorMask || DEFAULT_COLOR_MASK;

gl.colorMask(colorMask.r, colorMask.g, colorMask.b, colorMask.a);

// get rid of zfighting for alpha pass.
// alpha pass is drawn ordered zindex -> no need to write to depthbuffer (performance)
Expand Down
8 changes: 6 additions & 2 deletions packages/display/src/displays/webgl/program/Text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ class TextProgram extends Program {
this.fragmentShaderSrc = fragmentShader;
}


protected blendFunc() {
const {gl} = this;
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
}

initGeometryBuffer(options: GeometryBuffer, pass: PASS, stencil: boolean, zIndex: number) {
const {gl} = this;
super.initGeometryBuffer(options, pass, stencil);
Expand All @@ -51,8 +57,6 @@ class TextProgram extends Program {
// this issues is also related to overlapping (atlas.spacing) of characters
gl.depthMask(false);
// gl.depthFunc(gl.LESS);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);


gl.polygonOffset(0, (1 << 11) * -zIndex);
gl.enable(gl.POLYGON_OFFSET_FILL);
Expand Down

0 comments on commit 7d95b74

Please sign in to comment.