diff --git a/CHANGELOG.md b/CHANGELOG.md index 146ff44c9..0abd44897 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -238,6 +238,7 @@ * `SkeletonMesh` now takes an optional `SkeletonMeshMaterialParametersCustomizer` function that allows you to modify the `ShaderMaterialParameters` before the material is finalized. Use it to modify things like THREEJS' `Material.depthTest` etc. See #1590. * **Breaking change:** the global object `spine.canvas` no longer exists. All classes and functions are now exposed on the global `spine` object directly. Simply replace any reference to `spine.threejs.` in your source code with `spine.`. * **Breaking change:** the default fragment shader of `SkeletonMeshMaterial` now explicitely discards fragments with alpha < 0.5. See https://github.com/EsotericSoftware/spine-runtimes/issues/1985 +* **Breaking change:** reversal of the previous breaking change: the default fragment shader of `SkeletonMeshMaterial` does no longer discard fragments with alpha < 0.5. Pass a `SkeletonMeshMaterialParametersCustomizer` to the `SkeletonMesh` constructor, and modify `parameters.alphaTest` to be > 0. ### Player * Added `SpinePlayerConfig.rawDataURIs`. Allows to embed data URIs for skeletons, atlases and atlas page images directly in the HTML/JS without needing to load it from a separate file. See the example for a demonstration. diff --git a/spine-ts/.vscode/launch.json b/spine-ts/.vscode/launch.json index 109a37100..08d870cc9 100644 --- a/spine-ts/.vscode/launch.json +++ b/spine-ts/.vscode/launch.json @@ -17,6 +17,20 @@ "name": "drag-and-drop", "url": "http://localhost:8080/spine-webgl/example/drag-and-drop.html", "webRoot": "${workspaceFolder}" + }, + { + "type": "pwa-chrome", + "request": "launch", + "name": "barebones-dragon", + "url": "http://localhost:8080/spine-webgl/example/barebones-dragon.html", + "webRoot": "${workspaceFolder}" + }, + { + "type": "pwa-chrome", + "request": "launch", + "name": "threejs-example", + "url": "http://localhost:8080/spine-threejs/example/index.html", + "webRoot": "${workspaceFolder}" } ] -} \ No newline at end of file +} diff --git a/spine-ts/spine-threejs/src/SkeletonMesh.ts b/spine-ts/spine-threejs/src/SkeletonMesh.ts index e76b088d7..f004315bb 100644 --- a/spine-ts/spine-threejs/src/SkeletonMesh.ts +++ b/spine-ts/spine-threejs/src/SkeletonMesh.ts @@ -50,26 +50,35 @@ export class SkeletonMeshMaterial extends THREE.ShaderMaterial { `; let fragmentShader = ` uniform sampler2D map; + #ifdef USE_ALPHATEST + uniform float alphaTest; + #endif varying vec2 vUv; varying vec4 vColor; void main(void) { gl_FragColor = texture2D(map, vUv)*vColor; - if (gl_FragColor.a < 0.5) discard; + #ifdef USE_ALPHATEST + if (gl_FragColor.a < alphaTest) discard; + #endif } `; let parameters: THREE.ShaderMaterialParameters = { uniforms: { - map: { type: "t", value: null } as any + map: { value: null }, }, vertexShader: vertexShader, fragmentShader: fragmentShader, side: THREE.DoubleSide, transparent: true, depthWrite: false, - alphaTest: 0.5 + alphaTest: 0.0 }; customizer(parameters); + if (parameters.alphaTest > 0) { + parameters.defines = { "USE_ALPHATEST": 1 }; + parameters.uniforms["alphaTest"] = { value: parameters.alphaTest }; + } super(parameters); }; } @@ -194,7 +203,10 @@ export class SkeletonMesh extends THREE.Object3D { let clip = (attachment); clipper.clipStart(slot, clip); continue; - } else continue; + } else { + clipper.clipEndWithSlot(slot); + continue; + } if (texture != null) { let skeleton = slot.bone.skeleton; diff --git a/spine-ts/spine-webgl/example/drag-and-drop.html b/spine-ts/spine-webgl/example/drag-and-drop.html index 13cc10f40..c0fc4308e 100644 --- a/spine-ts/spine-webgl/example/drag-and-drop.html +++ b/spine-ts/spine-webgl/example/drag-and-drop.html @@ -12,6 +12,8 @@
+ +
diff --git a/spine-ts/spine-webgl/example/drag-and-drop.js b/spine-ts/spine-webgl/example/drag-and-drop.js index f635e001f..f7b5eebea 100644 --- a/spine-ts/spine-webgl/example/drag-and-drop.js +++ b/spine-ts/spine-webgl/example/drag-and-drop.js @@ -3,6 +3,7 @@ class App { this.skeleton = null; this.animationState = null; this.canvas = null; + this.pma = true; } loadAssets(canvas) { @@ -20,7 +21,13 @@ class App { // Setup listener for animation selection box let animationSelectBox = document.body.querySelector("#animations"); animationSelectBox.onchange = () => { - this.animationState.setAnimation(0, animationSelectBox.value, true); + // this.animationState.setAnimation(0, animationSelectBox.value, true); + } + + // Setup listener for the PMA checkbox + let pmaCheckbox = document.body.querySelector("#pma"); + pmaCheckbox.onchange = () => { + this.pma = pmaCheckbox.checked; } // Setup the drag and drop listener @@ -117,7 +124,7 @@ class App { animationSelectBox.appendChild(option); } - if (animationName) this.animationState.setAnimation(0, animationName, true); + // if (animationName) this.animationState.setAnimation(0, animationName, true); // Center the skeleton in the viewport this.centerSkeleton(); @@ -153,10 +160,11 @@ class App { renderer.resize(spine.ResizeMode.Expand); canvas.clear(0.2, 0.2, 0.2, 1); + renderer.begin(); renderer.line(-10000, 0, 10000, 0, spine.Color.RED); renderer.line(0, -10000, 0, 10000, spine.Color.GREEN); - renderer.drawSkeleton(this.skeleton, true); + renderer.drawSkeleton(this.skeleton, this.pma); renderer.end(); } }