Ver código fonte

[webgl] Fix blend modes, see #2025, #2347

Mario Zechner 2 anos atrás
pai
commit
a397b8fe3f

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

@@ -27,7 +27,7 @@
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-import { Color, Disposable, TimeKeeper } from "@esotericsoftware/spine-core";
+import { BlendMode, Color, Disposable, TimeKeeper } from "@esotericsoftware/spine-core";
 import { GLTexture } from "./GLTexture";
 import { ResizeMode, SceneRenderer } from "./SceneRenderer";
 
@@ -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(BlendMode.Normal, true);
 
 		if (complete) {
 			this.fadeOut += this.timeKeeper.delta * (this.timeKeeper.totalTime < 1 ? 2 : 1);

+ 23 - 4
spine-ts/spine-webgl/src/PolygonBatcher.ts

@@ -27,12 +27,19 @@
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
 
-import { Disposable } from "@esotericsoftware/spine-core";
+import { BlendMode, Disposable } from "@esotericsoftware/spine-core";
 import { GLTexture } from "./GLTexture";
 import { Mesh, Position2Attribute, ColorAttribute, TexCoordAttribute, Color2Attribute } from "./Mesh";
 import { Shader } from "./Shader";
 import { ManagedWebGLRenderingContext } from "./WebGL";
 
+const GL_ONE = 1;
+const GL_ONE_MINUS_SRC_COLOR = 0x0301;
+const GL_SRC_ALPHA = 0x0302;
+const GL_ONE_MINUS_SRC_ALPHA = 0x0303;
+const GL_ONE_MINUS_DST_ALPHA = 0x0305;
+const GL_DST_COLOR = 0x0306;
+
 export class PolygonBatcher implements Disposable {
 	public static disableCulling = false;
 
@@ -80,16 +87,28 @@ export class PolygonBatcher implements Disposable {
 		}
 	}
 
-	setBlendMode (srcColorBlend: number, srcAlphaBlend: number, dstBlend: number) {
+	private static blendModesGL: {srcRgb: number, srcRgbPma: number, dstRgb: number, srcAlpha: number}[] = [
+		{srcRgb: GL_SRC_ALPHA, srcRgbPma: GL_ONE, dstRgb: GL_ONE_MINUS_SRC_ALPHA, srcAlpha: GL_ONE },
+		{srcRgb: GL_SRC_ALPHA, srcRgbPma: GL_ONE, dstRgb: GL_ONE, srcAlpha: GL_ONE },
+		{srcRgb: GL_DST_COLOR, srcRgbPma: GL_DST_COLOR, dstRgb: GL_ONE_MINUS_SRC_ALPHA, srcAlpha: GL_ONE},
+		{srcRgb: GL_ONE, srcRgbPma: GL_ONE, dstRgb: GL_ONE_MINUS_SRC_COLOR, srcAlpha: GL_ONE }
+	]
+
+	setBlendMode (blendMode: BlendMode, premultipliedAlpha: boolean) {
+		const blendModeGL = PolygonBatcher.blendModesGL[blendMode];
+		const srcColorBlend = premultipliedAlpha ? blendModeGL.srcRgbPma : blendModeGL.srcRgb;
+		const srcAlphaBlend = blendModeGL.srcAlpha;
+		const dstBlend = blendModeGL.dstRgb;
+
 		if (this.srcColorBlend == srcColorBlend && this.srcAlphaBlend == srcAlphaBlend && this.dstBlend == dstBlend) return;
 		this.srcColorBlend = srcColorBlend;
 		this.srcAlphaBlend = srcAlphaBlend;
 		this.dstBlend = dstBlend;
 		if (this.isDrawing) {
 			this.flush();
-			let gl = this.context.gl;
-			gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend);
 		}
+		let gl = this.context.gl;
+		gl.blendFuncSeparate(srcColorBlend, dstBlend, srcAlphaBlend, dstBlend);
 	}
 
 	draw (texture: GLTexture, vertices: ArrayLike<number>, indices: Array<number>) {

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

@@ -30,7 +30,7 @@
 import { NumberArrayLike, Color, SkeletonClipping, Vector2, Utils, Skeleton, BlendMode, RegionAttachment, TextureAtlasRegion, MeshAttachment, ClippingAttachment } from "@esotericsoftware/spine-core";
 import { GLTexture } from "./GLTexture";
 import { PolygonBatcher } from "./PolygonBatcher";
-import { ManagedWebGLRenderingContext, WebGLBlendModeConverter } from "./WebGL";
+import { ManagedWebGLRenderingContext } from "./WebGL";
 
 
 class Renderable {
@@ -68,11 +68,6 @@ export class SkeletonRenderer {
 		let twoColorTint = this.twoColorTint;
 		let blendMode: BlendMode | null = null;
 
-		let tempPos = this.temp;
-		let tempUv = this.temp2;
-		let tempLight = this.temp3;
-		let tempDark = this.temp4;
-
 		let renderable: Renderable = this.renderable;
 		let uvs: NumberArrayLike;
 		let triangles: Array<number>;
@@ -166,10 +161,7 @@ export class SkeletonRenderer {
 				let slotBlendMode = slot.data.blendMode;
 				if (slotBlendMode != blendMode) {
 					blendMode = slotBlendMode;
-					batcher.setBlendMode(
-						WebGLBlendModeConverter.getSourceColorGLBlendMode(blendMode, premultipliedAlpha),
-						WebGLBlendModeConverter.getSourceAlphaGLBlendMode(blendMode),
-						WebGLBlendModeConverter.getDestGLBlendMode(blendMode));
+					batcher.setBlendMode(blendMode, premultipliedAlpha);
 				}
 
 				if (clipper.isClipping()) {

+ 0 - 39
spine-ts/spine-webgl/src/WebGL.ts

@@ -62,42 +62,3 @@ export class ManagedWebGLRenderingContext {
 		if (index > -1) this.restorables.splice(index, 1);
 	}
 }
-
-const ONE = 1;
-const ONE_MINUS_SRC_COLOR = 0x0301;
-const SRC_ALPHA = 0x0302;
-const ONE_MINUS_SRC_ALPHA = 0x0303;
-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;
-			case BlendMode.Additive: return 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;
-			default: throw new Error("Unknown blend mode: " + blendMode);
-		}
-	}
-
-	static getSourceAlphaGLBlendMode (blendMode: BlendMode) {
-		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;
-			default: throw new Error("Unknown blend mode: " + blendMode);
-		}
-	}
-}