split webgl blendmodes into separate destination color/alpha values (#2347)

This commit is contained in:
spayton 2023-09-04 09:40:16 +01:00 committed by GitHub
parent d041e9e39c
commit 07c05431bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 23 deletions

View File

@ -88,7 +88,7 @@ export class LoadingScreen implements Disposable {
renderer.resize(ResizeMode.Expand);
renderer.camera.position.set(canvas.width / 2, canvas.height / 2, 0);
renderer.batcher.setBlendMode(gl.ONE, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
renderer.batcher.setBlendMode(gl.ONE, gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
if (complete) {
this.fadeOut += this.timeKeeper.delta * (this.timeKeeper.totalTime < 1 ? 2 : 1);

View File

@ -47,7 +47,8 @@ export class PolygonBatcher implements Disposable {
private indicesLength = 0;
private srcColorBlend: number;
private srcAlphaBlend: number;
private dstBlend: number;
private dstColorBlend: number;
private dstAlphaBlend: number;
private cullWasEnabled = false;
constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, twoColorTint: boolean = true, maxVertices: number = 10920) {
@ -60,7 +61,8 @@ export class PolygonBatcher implements Disposable {
let gl = this.context.gl;
this.srcColorBlend = gl.SRC_ALPHA;
this.srcAlphaBlend = gl.ONE;
this.dstBlend = gl.ONE_MINUS_SRC_ALPHA;
this.dstColorBlend = gl.ONE_MINUS_SRC_ALPHA;
this.dstAlphaBlend = gl.ONE_MINUS_SRC_ALPHA;
}
begin (shader: Shader) {
@ -72,7 +74,7 @@ export class PolygonBatcher implements Disposable {
let gl = this.context.gl;
gl.enable(gl.BLEND);
gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend);
gl.blendFuncSeparate(this.srcColorBlend, this.dstColorBlend, this.srcAlphaBlend, this.dstAlphaBlend);
if (PolygonBatcher.disableCulling) {
this.cullWasEnabled = gl.isEnabled(gl.CULL_FACE);
@ -80,15 +82,16 @@ export class PolygonBatcher implements Disposable {
}
}
setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) {
if (this.srcColorBlend == srcColorBlend && this.srcAlphaBlend == srcAlphaBlend && this.dstBlend == dstBlend) return;
setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstColorBlend: number, dstAlphaBlend: number) {
if (this.srcColorBlend == srcColorBlend && this.srcAlphaBlend == srcAlphaBlend && this.dstColorBlend == dstColorBlend && this.dstAlphaBlend == dstAlphaBlend) return;
this.srcColorBlend = srcColorBlend;
this.srcAlphaBlend = srcAlphaBlend;
this.dstBlend = dstBlend;
this.dstColorBlend = dstColorBlend;
this.dstAlphaBlend = dstAlphaBlend;
if (this.isDrawing) {
this.flush();
let gl = this.context.gl;
gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend);
gl.blendFuncSeparate(srcColorBlend, dstColorBlend, srcAlphaBlend, dstAlphaBlend);
}
}

View File

@ -43,7 +43,8 @@ export class ShapeRenderer implements Disposable {
private tmp = new Vector2();
private srcColorBlend: number;
private srcAlphaBlend: number;
private dstBlend: number;
private dstColorBlend: number;
private dstAlphaBlend: number;
constructor (context: ManagedWebGLRenderingContext | WebGLRenderingContext, maxVertices: number = 10920) {
if (maxVertices > 10920) throw new Error("Can't have more than 10920 triangles per batch: " + maxVertices);
@ -52,7 +53,8 @@ export class ShapeRenderer implements Disposable {
let gl = this.context.gl;
this.srcColorBlend = gl.SRC_ALPHA;
this.srcAlphaBlend = gl.ONE;
this.dstBlend = gl.ONE_MINUS_SRC_ALPHA;
this.dstColorBlend = gl.ONE_MINUS_SRC_ALPHA;
this.dstAlphaBlend = gl.ONE_MINUS_SRC_ALPHA;
}
begin (shader: Shader) {
@ -63,17 +65,18 @@ export class ShapeRenderer implements Disposable {
let gl = this.context.gl;
gl.enable(gl.BLEND);
gl.blendFuncSeparate(this.srcColorBlend, this.dstBlend, this.srcAlphaBlend, this.dstBlend);
gl.blendFuncSeparate(this.srcColorBlend, this.dstColorBlend, this.srcAlphaBlend, this.dstAlphaBlend);
}
setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) {
setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstColorBlend: number, dstAlphaBlend: number) {
this.srcColorBlend = srcColorBlend;
this.srcAlphaBlend = srcAlphaBlend;
this.dstBlend = dstBlend;
this.dstColorBlend = dstColorBlend;
this.dstAlphaBlend = dstAlphaBlend;
if (this.isDrawing) {
this.flush();
let gl = this.context.gl;
gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend);
gl.blendFuncSeparate(srcColorBlend, dstColorBlend, srcAlphaBlend, dstAlphaBlend);
}
}

View File

@ -67,7 +67,7 @@ export class SkeletonDebugRenderer implements Disposable {
let skeletonY = skeleton.y;
let gl = this.context.gl;
let srcFunc = this.premultipliedAlpha ? gl.ONE : gl.SRC_ALPHA;
shapes.setBlendMode(srcFunc, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
shapes.setBlendMode(srcFunc, gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
let bones = skeleton.bones;
if (this.drawBones) {

View File

@ -168,8 +168,9 @@ export class SkeletonRenderer {
blendMode = slotBlendMode;
batcher.setBlendMode(
WebGLBlendModeConverter.getSourceColorGLBlendMode(blendMode, premultipliedAlpha),
WebGLBlendModeConverter.getSourceAlphaGLBlendMode(blendMode),
WebGLBlendModeConverter.getDestGLBlendMode(blendMode));
WebGLBlendModeConverter.getSourceAlphaGLBlendMode(blendMode, premultipliedAlpha),
WebGLBlendModeConverter.getDestColorGLBlendMode(blendMode),
WebGLBlendModeConverter.getDestAlphaGLBlendMode(blendMode, premultipliedAlpha) );
}
if (clipper.isClipping()) {

View File

@ -71,6 +71,7 @@ const ONE_MINUS_DST_ALPHA = 0x0305;
const DST_COLOR = 0x0306;
export class WebGLBlendModeConverter {
static getDestGLBlendMode (blendMode: BlendMode) {
switch (blendMode) {
case BlendMode.Normal: return ONE_MINUS_SRC_ALPHA;
@ -81,22 +82,42 @@ export class WebGLBlendModeConverter {
}
}
static getDestColorGLBlendMode (blendMode: BlendMode) {
switch (blendMode) {
case BlendMode.Normal: return ONE_MINUS_SRC_ALPHA;
case BlendMode.Additive: return ONE;
case BlendMode.Multiply: return ONE_MINUS_SRC_ALPHA;
case BlendMode.Screen: return ONE_MINUS_SRC_COLOR;
default: throw new Error("Unknown blend mode: " + blendMode);
}
}
static getDestAlphaGLBlendMode (blendMode: BlendMode, premultipliedAlpha: boolean = false) {
switch (blendMode) {
case BlendMode.Normal: return ONE_MINUS_SRC_ALPHA;
case BlendMode.Additive: return premultipliedAlpha ? ONE_MINUS_SRC_ALPHA : ONE;
case BlendMode.Multiply: return ONE_MINUS_SRC_ALPHA;
case BlendMode.Screen: return ONE_MINUS_SRC_ALPHA;
default: throw new Error("Unknown blend mode: " + blendMode);
}
}
static getSourceColorGLBlendMode (blendMode: BlendMode, premultipliedAlpha: boolean = false) {
switch (blendMode) {
case BlendMode.Normal: return premultipliedAlpha ? ONE : SRC_ALPHA;
case BlendMode.Additive: return premultipliedAlpha ? ONE : SRC_ALPHA;
case BlendMode.Multiply: return DST_COLOR;
case BlendMode.Screen: return ONE;
case BlendMode.Screen: return premultipliedAlpha ? ONE : SRC_ALPHA;
default: throw new Error("Unknown blend mode: " + blendMode);
}
}
static getSourceAlphaGLBlendMode (blendMode: BlendMode) {
static getSourceAlphaGLBlendMode (blendMode: BlendMode, premultipliedAlpha: boolean = false) {
switch (blendMode) {
case BlendMode.Normal: return ONE;
case BlendMode.Additive: return ONE;
case BlendMode.Multiply: return ONE_MINUS_SRC_ALPHA;
case BlendMode.Screen: return ONE_MINUS_SRC_COLOR;
case BlendMode.Normal: return premultipliedAlpha ? SRC_ALPHA : ONE;
case BlendMode.Additive: return premultipliedAlpha ? SRC_ALPHA : ONE;
case BlendMode.Multiply: return ONE;
case BlendMode.Screen: return ONE;
default: throw new Error("Unknown blend mode: " + blendMode);
}
}