فهرست منبع

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

spayton 2 سال پیش
والد
کامیت
07c05431bf

+ 1 - 1
spine-ts/spine-webgl/src/LoadingScreen.ts

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

+ 10 - 7
spine-ts/spine-webgl/src/PolygonBatcher.ts

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

+ 9 - 6
spine-ts/spine-webgl/src/ShapeRenderer.ts

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

+ 1 - 1
spine-ts/spine-webgl/src/SkeletonDebugRenderer.ts

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

+ 3 - 2
spine-ts/spine-webgl/src/SkeletonRenderer.ts

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

+ 27 - 6
spine-ts/spine-webgl/src/WebGL.ts

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