mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
[ts][threejs] Allow to load pma textures. Non-pma textures are pma on upload. Fixed blending modes. Add physics example.
Close #2503.
This commit is contained in:
parent
06dc94ee11
commit
f3b3cb429a
@ -456,6 +456,7 @@ rm "$ROOT/spine-ts/spine-threejs/example/assets/"*
|
||||
cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-ts/spine-threejs/example/assets/"
|
||||
cp -f ../raptor/export/raptor.atlas "$ROOT/spine-ts/spine-threejs/example/assets/"
|
||||
cp -f ../raptor/export/raptor.png "$ROOT/spine-ts/spine-threejs/example/assets/"
|
||||
cp -f ../celestial-circus/export/* "$ROOT/spine-ts/spine-threejs/example/assets/"
|
||||
|
||||
rm "$ROOT/spine-ts/spine-player/example/assets/"*
|
||||
cp -f ../raptor/export/raptor-pro.json "$ROOT/spine-ts/spine-player/example/assets/"
|
||||
|
||||
@ -178,6 +178,9 @@
|
||||
<li>
|
||||
<a href="/spine-threejs/example/logarithmic-depth-buffer.html">Logarithmic depth buffer</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/spine-threejs/example/physics.html">Physics</a>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
174
spine-ts/spine-threejs/example/assets/celestial-circus-pma.atlas
Normal file
174
spine-ts/spine-threejs/example/assets/celestial-circus-pma.atlas
Normal file
@ -0,0 +1,174 @@
|
||||
celestial-circus-pma.png
|
||||
size: 1024, 1024
|
||||
filter: Linear, Linear
|
||||
pma: true
|
||||
scale: 0.4
|
||||
arm-back-down
|
||||
bounds: 324, 401, 38, 82
|
||||
rotate: 90
|
||||
arm-back-up
|
||||
bounds: 290, 44, 83, 116
|
||||
rotate: 90
|
||||
arm-front-down
|
||||
bounds: 706, 2, 36, 78
|
||||
rotate: 90
|
||||
arm-front-up
|
||||
bounds: 860, 138, 77, 116
|
||||
bench
|
||||
bounds: 725, 256, 189, 48
|
||||
body-bottom
|
||||
bounds: 879, 868, 154, 124
|
||||
rotate: 90
|
||||
body-top
|
||||
bounds: 725, 128, 126, 133
|
||||
rotate: 90
|
||||
chest
|
||||
bounds: 408, 26, 104, 93
|
||||
cloud-back
|
||||
bounds: 752, 378, 202, 165
|
||||
cloud-front
|
||||
bounds: 2, 2, 325, 196
|
||||
rotate: 90
|
||||
collar
|
||||
bounds: 786, 13, 47, 26
|
||||
ear
|
||||
bounds: 1002, 643, 20, 28
|
||||
eye-back-shadow
|
||||
bounds: 428, 395, 14, 10
|
||||
eye-front-shadow
|
||||
bounds: 704, 529, 24, 14
|
||||
eye-reflex-back
|
||||
bounds: 860, 128, 8, 7
|
||||
rotate: 90
|
||||
eye-reflex-front
|
||||
bounds: 726, 386, 10, 7
|
||||
eye-white-back
|
||||
bounds: 835, 23, 13, 16
|
||||
eye-white-front
|
||||
bounds: 1005, 1000, 22, 17
|
||||
rotate: 90
|
||||
eyelashes-down-back
|
||||
bounds: 232, 329, 11, 6
|
||||
rotate: 90
|
||||
eyelashes-down-front
|
||||
bounds: 913, 851, 15, 6
|
||||
rotate: 90
|
||||
eyelashes-top-back
|
||||
bounds: 408, 395, 18, 10
|
||||
eyelashes-top-front
|
||||
bounds: 702, 179, 30, 16
|
||||
rotate: 90
|
||||
face
|
||||
bounds: 514, 26, 93, 102
|
||||
rotate: 90
|
||||
feathers-back
|
||||
bounds: 954, 625, 46, 46
|
||||
feathers-front
|
||||
bounds: 706, 40, 72, 86
|
||||
fringe-middle-back
|
||||
bounds: 200, 6, 33, 52
|
||||
rotate: 90
|
||||
fringe-middle-front
|
||||
bounds: 878, 76, 60, 50
|
||||
rotate: 90
|
||||
fringe-side-back
|
||||
bounds: 780, 41, 27, 94
|
||||
rotate: 90
|
||||
fringe-side-front
|
||||
bounds: 939, 161, 26, 93
|
||||
glove-bottom-back
|
||||
bounds: 954, 572, 51, 41
|
||||
rotate: 90
|
||||
glove-bottom-front
|
||||
bounds: 916, 256, 47, 48
|
||||
hair-back-1
|
||||
bounds: 444, 395, 132, 306
|
||||
rotate: 90
|
||||
hair-back-2
|
||||
bounds: 438, 211, 80, 285
|
||||
rotate: 90
|
||||
hair-back-3
|
||||
bounds: 719, 306, 70, 268
|
||||
rotate: 90
|
||||
hair-back-4
|
||||
bounds: 438, 121, 88, 262
|
||||
rotate: 90
|
||||
hair-back-5
|
||||
bounds: 438, 293, 88, 279
|
||||
rotate: 90
|
||||
hair-back-6
|
||||
bounds: 200, 41, 88, 286
|
||||
hair-hat-shadow
|
||||
bounds: 232, 398, 90, 41
|
||||
hand-back
|
||||
bounds: 954, 673, 60, 47
|
||||
rotate: 90
|
||||
hand-front
|
||||
bounds: 967, 172, 53, 60
|
||||
hat-back
|
||||
bounds: 954, 802, 64, 45
|
||||
rotate: 90
|
||||
hat-front
|
||||
bounds: 780, 70, 96, 56
|
||||
head-back
|
||||
bounds: 618, 17, 102, 86
|
||||
rotate: 90
|
||||
jabot
|
||||
bounds: 967, 234, 70, 55
|
||||
rotate: 90
|
||||
leg-back
|
||||
bounds: 232, 441, 210, 333
|
||||
leg-front
|
||||
bounds: 444, 529, 258, 320
|
||||
logo-brooch
|
||||
bounds: 954, 545, 16, 25
|
||||
mouth
|
||||
bounds: 408, 121, 22, 6
|
||||
neck
|
||||
bounds: 232, 342, 39, 56
|
||||
rotate: 90
|
||||
nose
|
||||
bounds: 742, 529, 6, 7
|
||||
rotate: 90
|
||||
nose-highlight
|
||||
bounds: 719, 300, 4, 4
|
||||
nose-shadow
|
||||
bounds: 869, 128, 7, 8
|
||||
pupil-back
|
||||
bounds: 730, 529, 10, 14
|
||||
pupil-front
|
||||
bounds: 254, 21, 12, 18
|
||||
rope-back
|
||||
bounds: 232, 383, 10, 492
|
||||
rotate: 90
|
||||
rope-front
|
||||
bounds: 232, 383, 10, 492
|
||||
rotate: 90
|
||||
rope-front-bottom
|
||||
bounds: 954, 735, 42, 65
|
||||
skirt
|
||||
bounds: 2, 776, 440, 246
|
||||
sock-bow
|
||||
bounds: 408, 407, 33, 32
|
||||
spine-logo-body
|
||||
bounds: 879, 853, 13, 32
|
||||
rotate: 90
|
||||
star-big
|
||||
bounds: 939, 141, 18, 24
|
||||
rotate: 90
|
||||
star-medium
|
||||
bounds: 742, 537, 6, 8
|
||||
rotate: 90
|
||||
star-small
|
||||
bounds: 719, 378, 3, 4
|
||||
rotate: 90
|
||||
underskirt
|
||||
bounds: 2, 329, 445, 228
|
||||
rotate: 90
|
||||
underskirt-back
|
||||
bounds: 444, 851, 433, 171
|
||||
wing-back
|
||||
bounds: 290, 129, 146, 252
|
||||
wing-front
|
||||
bounds: 704, 545, 304, 248
|
||||
rotate: 90
|
||||
BIN
spine-ts/spine-threejs/example/assets/celestial-circus-pma.png
Normal file
BIN
spine-ts/spine-threejs/example/assets/celestial-circus-pma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 799 KiB |
3758
spine-ts/spine-threejs/example/assets/celestial-circus-pro.json
Normal file
3758
spine-ts/spine-threejs/example/assets/celestial-circus-pro.json
Normal file
File diff suppressed because it is too large
Load Diff
BIN
spine-ts/spine-threejs/example/assets/celestial-circus-pro.skel
Normal file
BIN
spine-ts/spine-threejs/example/assets/celestial-circus-pro.skel
Normal file
Binary file not shown.
173
spine-ts/spine-threejs/example/assets/celestial-circus.atlas
Normal file
173
spine-ts/spine-threejs/example/assets/celestial-circus.atlas
Normal file
@ -0,0 +1,173 @@
|
||||
celestial-circus.png
|
||||
size: 1024, 1024
|
||||
filter: Linear, Linear
|
||||
scale: 0.4
|
||||
arm-back-down
|
||||
bounds: 324, 401, 38, 82
|
||||
rotate: 90
|
||||
arm-back-up
|
||||
bounds: 290, 44, 83, 116
|
||||
rotate: 90
|
||||
arm-front-down
|
||||
bounds: 706, 2, 36, 78
|
||||
rotate: 90
|
||||
arm-front-up
|
||||
bounds: 860, 138, 77, 116
|
||||
bench
|
||||
bounds: 725, 256, 189, 48
|
||||
body-bottom
|
||||
bounds: 879, 868, 154, 124
|
||||
rotate: 90
|
||||
body-top
|
||||
bounds: 725, 128, 126, 133
|
||||
rotate: 90
|
||||
chest
|
||||
bounds: 408, 26, 104, 93
|
||||
cloud-back
|
||||
bounds: 752, 378, 202, 165
|
||||
cloud-front
|
||||
bounds: 2, 2, 325, 196
|
||||
rotate: 90
|
||||
collar
|
||||
bounds: 786, 13, 47, 26
|
||||
ear
|
||||
bounds: 1002, 643, 20, 28
|
||||
eye-back-shadow
|
||||
bounds: 428, 395, 14, 10
|
||||
eye-front-shadow
|
||||
bounds: 704, 529, 24, 14
|
||||
eye-reflex-back
|
||||
bounds: 860, 128, 8, 7
|
||||
rotate: 90
|
||||
eye-reflex-front
|
||||
bounds: 726, 386, 10, 7
|
||||
eye-white-back
|
||||
bounds: 835, 23, 13, 16
|
||||
eye-white-front
|
||||
bounds: 1005, 1000, 22, 17
|
||||
rotate: 90
|
||||
eyelashes-down-back
|
||||
bounds: 232, 329, 11, 6
|
||||
rotate: 90
|
||||
eyelashes-down-front
|
||||
bounds: 913, 851, 15, 6
|
||||
rotate: 90
|
||||
eyelashes-top-back
|
||||
bounds: 408, 395, 18, 10
|
||||
eyelashes-top-front
|
||||
bounds: 702, 179, 30, 16
|
||||
rotate: 90
|
||||
face
|
||||
bounds: 514, 26, 93, 102
|
||||
rotate: 90
|
||||
feathers-back
|
||||
bounds: 954, 625, 46, 46
|
||||
feathers-front
|
||||
bounds: 706, 40, 72, 86
|
||||
fringe-middle-back
|
||||
bounds: 200, 6, 33, 52
|
||||
rotate: 90
|
||||
fringe-middle-front
|
||||
bounds: 878, 76, 60, 50
|
||||
rotate: 90
|
||||
fringe-side-back
|
||||
bounds: 780, 41, 27, 94
|
||||
rotate: 90
|
||||
fringe-side-front
|
||||
bounds: 939, 161, 26, 93
|
||||
glove-bottom-back
|
||||
bounds: 954, 572, 51, 41
|
||||
rotate: 90
|
||||
glove-bottom-front
|
||||
bounds: 916, 256, 47, 48
|
||||
hair-back-1
|
||||
bounds: 444, 395, 132, 306
|
||||
rotate: 90
|
||||
hair-back-2
|
||||
bounds: 438, 211, 80, 285
|
||||
rotate: 90
|
||||
hair-back-3
|
||||
bounds: 719, 306, 70, 268
|
||||
rotate: 90
|
||||
hair-back-4
|
||||
bounds: 438, 121, 88, 262
|
||||
rotate: 90
|
||||
hair-back-5
|
||||
bounds: 438, 293, 88, 279
|
||||
rotate: 90
|
||||
hair-back-6
|
||||
bounds: 200, 41, 88, 286
|
||||
hair-hat-shadow
|
||||
bounds: 232, 398, 90, 41
|
||||
hand-back
|
||||
bounds: 954, 673, 60, 47
|
||||
rotate: 90
|
||||
hand-front
|
||||
bounds: 967, 172, 53, 60
|
||||
hat-back
|
||||
bounds: 954, 802, 64, 45
|
||||
rotate: 90
|
||||
hat-front
|
||||
bounds: 780, 70, 96, 56
|
||||
head-back
|
||||
bounds: 618, 17, 102, 86
|
||||
rotate: 90
|
||||
jabot
|
||||
bounds: 967, 234, 70, 55
|
||||
rotate: 90
|
||||
leg-back
|
||||
bounds: 232, 441, 210, 333
|
||||
leg-front
|
||||
bounds: 444, 529, 258, 320
|
||||
logo-brooch
|
||||
bounds: 954, 545, 16, 25
|
||||
mouth
|
||||
bounds: 408, 121, 22, 6
|
||||
neck
|
||||
bounds: 232, 342, 39, 56
|
||||
rotate: 90
|
||||
nose
|
||||
bounds: 742, 529, 6, 7
|
||||
rotate: 90
|
||||
nose-highlight
|
||||
bounds: 719, 300, 4, 4
|
||||
nose-shadow
|
||||
bounds: 869, 128, 7, 8
|
||||
pupil-back
|
||||
bounds: 730, 529, 10, 14
|
||||
pupil-front
|
||||
bounds: 254, 21, 12, 18
|
||||
rope-back
|
||||
bounds: 232, 383, 10, 492
|
||||
rotate: 90
|
||||
rope-front
|
||||
bounds: 232, 383, 10, 492
|
||||
rotate: 90
|
||||
rope-front-bottom
|
||||
bounds: 954, 735, 42, 65
|
||||
skirt
|
||||
bounds: 2, 776, 440, 246
|
||||
sock-bow
|
||||
bounds: 408, 407, 33, 32
|
||||
spine-logo-body
|
||||
bounds: 879, 853, 13, 32
|
||||
rotate: 90
|
||||
star-big
|
||||
bounds: 939, 141, 18, 24
|
||||
rotate: 90
|
||||
star-medium
|
||||
bounds: 742, 537, 6, 8
|
||||
rotate: 90
|
||||
star-small
|
||||
bounds: 719, 378, 3, 4
|
||||
rotate: 90
|
||||
underskirt
|
||||
bounds: 2, 329, 445, 228
|
||||
rotate: 90
|
||||
underskirt-back
|
||||
bounds: 444, 851, 433, 171
|
||||
wing-back
|
||||
bounds: 290, 129, 146, 252
|
||||
wing-front
|
||||
bounds: 704, 545, 304, 248
|
||||
rotate: 90
|
||||
BIN
spine-ts/spine-threejs/example/assets/celestial-circus.png
Normal file
BIN
spine-ts/spine-threejs/example/assets/celestial-circus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 790 KiB |
150
spine-ts/spine-threejs/example/physics.html
Normal file
150
spine-ts/spine-threejs/example/physics.html
Normal file
@ -0,0 +1,150 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>spine-threejs</title>
|
||||
<script src="https://unpkg.com/three@0.141.0/build/three.js"></script>
|
||||
<script src="../dist/iife/spine-threejs.js"></script>
|
||||
<script src="./OrbitalControls.js"></script>
|
||||
</head>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body,
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
(function () {
|
||||
let scene, camera, renderer;
|
||||
let geometry, material, mesh, skeletonMesh;
|
||||
let assetManager;
|
||||
let canvas;
|
||||
let controls;
|
||||
let lastFrameTime = Date.now() / 1000;
|
||||
|
||||
let pma = false;
|
||||
let baseUrl = "assets/";
|
||||
let skeletonFile = "celestial-circus-pro.json";
|
||||
let atlasFile = `celestial-circus${pma ? "-pma" : ""}.atlas`;
|
||||
|
||||
function init() {
|
||||
// create the THREE.JS camera, scene and renderer (WebGL)
|
||||
let width = window.innerWidth,
|
||||
height = window.innerHeight;
|
||||
camera = new THREE.PerspectiveCamera(75, width / height, 1, 3000);
|
||||
camera.position.y = 0;
|
||||
camera.position.z = 800;
|
||||
scene = new THREE.Scene();
|
||||
renderer = new THREE.WebGLRenderer();
|
||||
renderer.setSize(width, height);
|
||||
document.body.appendChild(renderer.domElement);
|
||||
canvas = renderer.domElement;
|
||||
controls = new OrbitControls(camera, renderer.domElement);
|
||||
|
||||
// load the assets required to display the Raptor model
|
||||
assetManager = new spine.AssetManager(baseUrl, undefined, pma);
|
||||
assetManager.loadText(skeletonFile);
|
||||
assetManager.loadTextureAtlas(atlasFile);
|
||||
|
||||
requestAnimationFrame(load);
|
||||
}
|
||||
|
||||
function load(name, scale) {
|
||||
if (assetManager.isLoadingComplete()) {
|
||||
// Add a box to the scene to which we attach the skeleton mesh
|
||||
geometry = new THREE.BoxGeometry(200, 200, 200);
|
||||
material = new THREE.MeshBasicMaterial({
|
||||
color: 0xff0000,
|
||||
wireframe: true,
|
||||
});
|
||||
mesh = new THREE.Mesh(geometry, material);
|
||||
scene.add(mesh);
|
||||
|
||||
// Load the texture atlas using name.atlas and name.png from the AssetManager.
|
||||
// The function passed to TextureAtlas is used to resolve relative paths.
|
||||
atlas = assetManager.require(atlasFile);
|
||||
|
||||
// Create a AtlasAttachmentLoader that resolves region, mesh, boundingbox and path attachments
|
||||
atlasLoader = new spine.AtlasAttachmentLoader(atlas);
|
||||
|
||||
// Create a SkeletonJson instance for parsing the .json file.
|
||||
let skeletonJson = new spine.SkeletonJson(atlasLoader);
|
||||
|
||||
// Set the scale to apply during parsing, parse the file, and create a new skeleton.
|
||||
skeletonJson.scale = 0.4;
|
||||
let skeletonData = skeletonJson.readSkeletonData(
|
||||
assetManager.require(skeletonFile)
|
||||
);
|
||||
|
||||
// Create a SkeletonMesh from the data and attach it to the scene
|
||||
skeletonMesh = new spine.SkeletonMesh(
|
||||
skeletonData,
|
||||
(parameters) => {
|
||||
parameters.depthTest = true;
|
||||
parameters.depthWrite = true;
|
||||
parameters.alphaTest = 0.001;
|
||||
}
|
||||
);
|
||||
skeletonMesh.state.setAnimation(0, "swing", true);
|
||||
skeletonMesh.state.setAnimation(1, "eyeblink-long", true);
|
||||
mesh.add(skeletonMesh);
|
||||
|
||||
skeletonMesh.position.y = -300;
|
||||
|
||||
requestAnimationFrame(render);
|
||||
} else requestAnimationFrame(load);
|
||||
}
|
||||
|
||||
let lastTime = Date.now();
|
||||
function render() {
|
||||
// calculate delta time for animation purposes
|
||||
let now = Date.now() / 1000;
|
||||
let delta = now - lastFrameTime;
|
||||
lastFrameTime = now;
|
||||
|
||||
// resize canvas to use full page, adjust camera/renderer
|
||||
resize();
|
||||
|
||||
// Update orbital controls
|
||||
controls.update();
|
||||
|
||||
// update the animation
|
||||
skeletonMesh.update(delta);
|
||||
|
||||
// render the scene
|
||||
renderer.render(scene, camera);
|
||||
|
||||
requestAnimationFrame(render);
|
||||
}
|
||||
|
||||
function resize() {
|
||||
let w = window.innerWidth;
|
||||
let h = window.innerHeight;
|
||||
if (canvas.width != w || canvas.height != h) {
|
||||
canvas.width = w;
|
||||
canvas.height = h;
|
||||
}
|
||||
|
||||
camera.aspect = w / h;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
renderer.setSize(w, h);
|
||||
}
|
||||
|
||||
init();
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -31,9 +31,9 @@ import { AssetManagerBase, Downloader } from "@esotericsoftware/spine-core"
|
||||
import { ThreeJsTexture } from "./ThreeJsTexture.js";
|
||||
|
||||
export class AssetManager extends AssetManagerBase {
|
||||
constructor (pathPrefix: string = "", downloader: Downloader = new Downloader()) {
|
||||
constructor (pathPrefix: string = "", downloader: Downloader = new Downloader(), pma = false) {
|
||||
super((image: HTMLImageElement | ImageBitmap) => {
|
||||
return new ThreeJsTexture(image);
|
||||
return new ThreeJsTexture(image, pma);
|
||||
}, pathPrefix, downloader);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
import { SkeletonMeshMaterial, SkeletonMeshMaterialParametersCustomizer } from "./SkeletonMesh.js";
|
||||
import * as THREE from "three"
|
||||
import { ThreeJsTexture } from "./ThreeJsTexture.js";
|
||||
import { ThreeJsTexture, ThreeBlendOptions } from "./ThreeJsTexture.js";
|
||||
import { BlendMode } from "@esotericsoftware/spine-core";
|
||||
|
||||
export class MeshBatcher extends THREE.Mesh {
|
||||
@ -163,7 +163,7 @@ export class MeshBatcher extends THREE.Mesh {
|
||||
}
|
||||
|
||||
findMaterialGroup (slotTexture: THREE.Texture, slotBlendMode: BlendMode) {
|
||||
const blending = ThreeJsTexture.toThreeJsBlending(slotBlendMode);
|
||||
const blendingObject = ThreeJsTexture.toThreeJsBlending(slotBlendMode);
|
||||
let group = -1;
|
||||
|
||||
if (Array.isArray(this.material)) {
|
||||
@ -171,17 +171,23 @@ export class MeshBatcher extends THREE.Mesh {
|
||||
const meshMaterial = this.material[i] as SkeletonMeshMaterial;
|
||||
|
||||
if (!meshMaterial.uniforms.map.value) {
|
||||
updateMeshMaterial(meshMaterial, slotTexture, blending);
|
||||
updateMeshMaterial(meshMaterial, slotTexture, blendingObject);
|
||||
return i;
|
||||
}
|
||||
|
||||
if (meshMaterial.uniforms.map.value === slotTexture && meshMaterial.blending === blending) {
|
||||
if (meshMaterial.uniforms.map.value === slotTexture
|
||||
&& blendingObject.blending === meshMaterial.blending
|
||||
&& (blendingObject.blendSrc === undefined || blendingObject.blendSrc === meshMaterial.blendSrc)
|
||||
&& (blendingObject.blendDst === undefined || blendingObject.blendDst === meshMaterial.blendDst)
|
||||
&& (blendingObject.blendSrcAlpha === undefined || blendingObject.blendSrcAlpha === meshMaterial.blendSrcAlpha)
|
||||
&& (blendingObject.blendDstAlpha === undefined || blendingObject.blendDstAlpha === meshMaterial.blendDstAlpha)
|
||||
) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
const meshMaterial = new SkeletonMeshMaterial(this.materialCustomizer);
|
||||
updateMeshMaterial(meshMaterial, slotTexture, blending);
|
||||
updateMeshMaterial(meshMaterial, slotTexture, blendingObject);
|
||||
this.material.push(meshMaterial);
|
||||
group = this.material.length - 1;
|
||||
} else {
|
||||
@ -192,10 +198,8 @@ export class MeshBatcher extends THREE.Mesh {
|
||||
}
|
||||
}
|
||||
|
||||
function updateMeshMaterial (meshMaterial: SkeletonMeshMaterial, slotTexture: THREE.Texture, blending: THREE.Blending) {
|
||||
function updateMeshMaterial (meshMaterial: SkeletonMeshMaterial, slotTexture: THREE.Texture, blending: ThreeBlendOptions) {
|
||||
meshMaterial.uniforms.map.value = slotTexture;
|
||||
meshMaterial.blending = blending;
|
||||
meshMaterial.blendDst = blending === THREE.CustomBlending ? THREE.OneMinusSrcColorFactor : THREE.OneMinusSrcAlphaFactor;
|
||||
meshMaterial.blendSrc = blending === THREE.CustomBlending ? THREE.OneFactor : THREE.SrcAlphaFactor;
|
||||
Object.assign(meshMaterial, blending);
|
||||
meshMaterial.needsUpdate = true;
|
||||
}
|
||||
|
||||
@ -97,6 +97,8 @@ export class SkeletonMeshMaterial extends THREE.ShaderMaterial {
|
||||
parameters.uniforms["alphaTest"] = { value: parameters.alphaTest };
|
||||
}
|
||||
super(parameters);
|
||||
// non-pma textures are premultiply on upload, so we set premultipliedAlpha to true
|
||||
this.premultipliedAlpha = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,9 +243,9 @@ export class SkeletonMesh extends THREE.Object3D {
|
||||
let alpha = skeletonColor.a * slotColor.a * attachmentColor.a;
|
||||
let color = this.tempColor;
|
||||
color.set(
|
||||
skeletonColor.r * slotColor.r * attachmentColor.r,
|
||||
skeletonColor.g * slotColor.g * attachmentColor.g,
|
||||
skeletonColor.b * slotColor.b * attachmentColor.b,
|
||||
skeletonColor.r * slotColor.r * attachmentColor.r * alpha,
|
||||
skeletonColor.g * slotColor.g * attachmentColor.g * alpha,
|
||||
skeletonColor.b * slotColor.b * attachmentColor.b * alpha,
|
||||
alpha
|
||||
);
|
||||
|
||||
|
||||
@ -33,12 +33,14 @@ import * as THREE from "three";
|
||||
export class ThreeJsTexture extends Texture {
|
||||
texture: THREE.Texture;
|
||||
|
||||
constructor (image: HTMLImageElement | ImageBitmap) {
|
||||
constructor (image: HTMLImageElement | ImageBitmap, pma = false) {
|
||||
super(image);
|
||||
if (image instanceof ImageBitmap)
|
||||
this.texture = new THREE.CanvasTexture(image);
|
||||
else
|
||||
this.texture = new THREE.Texture(image);
|
||||
// if the texture is not pma, we ask to threejs to premultiply on upload
|
||||
this.texture.premultiplyAlpha = !pma;
|
||||
this.texture.flipY = false;
|
||||
this.texture.needsUpdate = true;
|
||||
}
|
||||
@ -74,11 +76,31 @@ export class ThreeJsTexture extends Texture {
|
||||
else throw new Error("Unknown texture wrap: " + wrap);
|
||||
}
|
||||
|
||||
static toThreeJsBlending (blend: BlendMode) {
|
||||
if (blend === BlendMode.Normal) return THREE.NormalBlending;
|
||||
else if (blend === BlendMode.Additive) return THREE.AdditiveBlending;
|
||||
else if (blend === BlendMode.Multiply) return THREE.MultiplyBlending;
|
||||
else if (blend === BlendMode.Screen) return THREE.CustomBlending;
|
||||
static toThreeJsBlending (blend: BlendMode): ThreeBlendOptions {
|
||||
if (blend === BlendMode.Normal) return { blending: THREE.NormalBlending };
|
||||
else if (blend === BlendMode.Additive) return { blending: THREE.AdditiveBlending };
|
||||
else if (blend === BlendMode.Multiply) return {
|
||||
blending: THREE.CustomBlending,
|
||||
blendSrc: THREE.DstColorFactor,
|
||||
blendDst: THREE.OneMinusSrcAlphaFactor,
|
||||
blendSrcAlpha: THREE.OneFactor,
|
||||
blendDstAlpha: THREE.OneMinusSrcAlphaFactor,
|
||||
}
|
||||
else if (blend === BlendMode.Screen) return {
|
||||
blending: THREE.CustomBlending,
|
||||
blendSrc: THREE.OneFactor,
|
||||
blendDst: THREE.OneMinusSrcColorFactor,
|
||||
blendSrcAlpha: THREE.OneFactor,
|
||||
blendDstAlpha: THREE.OneMinusSrcColorFactor,
|
||||
}
|
||||
else throw new Error("Unknown blendMode: " + blend);
|
||||
}
|
||||
}
|
||||
|
||||
export type ThreeBlendOptions = {
|
||||
blending: THREE.Blending,
|
||||
blendSrc?: THREE.BlendingDstFactor,
|
||||
blendDst?: THREE.BlendingDstFactor,
|
||||
blendSrcAlpha?: THREE.BlendingDstFactor,
|
||||
blendDstAlpha?: THREE.BlendingDstFactor,
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user