Skip to content

Commit ee2b381

Browse files
authored
Merge pull request #13038 from CesiumGS/fix/textureatlas-border-internal
fix(textureatlas): Apply internal padding between images
2 parents c92d0d8 + 4e3980c commit ee2b381

File tree

3 files changed

+153
-35
lines changed

3 files changed

+153
-35
lines changed

CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
#### Fixes :wrench:
88

99
- Billboards using `imageSubRegion` now render as expected. [#12585](https://github.com/CesiumGS/cesium/issues/12585)
10-
- Improved scaling of SVGs in billboards [#TODO](https://github.com/CesiumGS/cesium/issues/TODO)
10+
- Improved scaling of SVGs in billboards [#13020](https://github.com/CesiumGS/cesium/issues/13020)
11+
- Fixed unexpected outline artifacts around billboards [#13038](https://github.com/CesiumGS/cesium/issues/13038)
1112

1213
#### Additions :tada:
1314

packages/engine/Source/Core/TexturePacker.js

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ TexturePacker.prototype._findNode = function (node, { width, height }) {
122122
return node;
123123
}
124124

125+
const borderPadding = this._borderPadding;
126+
125127
// Vertical split (childNode1 = left half, childNode2 = right half).
126128
if (widthDifference > heightDifference) {
127129
node.childNode1 = new TextureNode({
@@ -130,12 +132,18 @@ TexturePacker.prototype._findNode = function (node, { width, height }) {
130132
width,
131133
height: nodeHeight,
132134
});
133-
node.childNode2 = new TextureNode({
134-
x: rectangle.x + width,
135-
y: rectangle.y,
136-
width: widthDifference,
137-
height: nodeHeight,
138-
});
135+
136+
// Apply padding only along the vertical "cut".
137+
const widthDifferencePadded = widthDifference - borderPadding;
138+
139+
if (widthDifferencePadded > 0) {
140+
node.childNode2 = new TextureNode({
141+
x: rectangle.x + width + borderPadding,
142+
y: rectangle.y,
143+
width: widthDifferencePadded,
144+
height: nodeHeight,
145+
});
146+
}
139147

140148
return this._findNode(node.childNode1, { width, height });
141149
}
@@ -147,12 +155,19 @@ TexturePacker.prototype._findNode = function (node, { width, height }) {
147155
width: nodeWidth,
148156
height,
149157
});
150-
node.childNode2 = new TextureNode({
151-
x: rectangle.x,
152-
y: rectangle.y + height,
153-
width: nodeWidth,
154-
height: heightDifference,
155-
});
158+
159+
// Apply padding only along the horizontal "cut".
160+
const heightDifferencePadded = heightDifference - borderPadding;
161+
162+
if (heightDifferencePadded > 0) {
163+
node.childNode2 = new TextureNode({
164+
x: rectangle.x,
165+
y: rectangle.y + height + borderPadding,
166+
width: nodeWidth,
167+
height: heightDifferencePadded,
168+
});
169+
}
170+
156171
return this._findNode(node.childNode1, { width, height });
157172
}
158173

packages/engine/Specs/Renderer/TextureAtlasSpec.js

Lines changed: 124 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -852,16 +852,16 @@ describe("Scene/TextureAtlas", function () {
852852
.2222222222222222...............
853853
.2222222222222222...............
854854
.2222222222222222...............
855-
.22222222222222223333333333.....
856-
.22222222222222223333333333.....
857-
.22222222222222223333333333.....
858-
.22222222222222223333333333.....
859-
.22222222222222223333333333.....
860-
.22222222222222223333333333.....
861-
.22222222222222223333333333.....
862-
.22222222222222223333333333.....
863-
.22222222222222223333333333.....
864-
.2222222222222222333333333301...
855+
.2222222222222222.3333333333....
856+
.2222222222222222.3333333333....
857+
.2222222222222222.3333333333....
858+
.2222222222222222.3333333333....
859+
.2222222222222222.3333333333....
860+
.2222222222222222.3333333333....
861+
.2222222222222222.3333333333....
862+
.2222222222222222.3333333333.1..
863+
.2222222222222222.3333333333....
864+
.2222222222222222.3333333333.0..
865865
................................
866866
`.trim(),
867867
);
@@ -926,9 +926,9 @@ describe("Scene/TextureAtlas", function () {
926926
.2222222222...
927927
.2222222222...
928928
.2222222222...
929+
.2222222222.1.
929930
.2222222222...
930-
.2222222222...
931-
.222222222201.
931+
.2222222222.0.
932932
..............
933933
`.trim(),
934934
);
@@ -976,16 +976,16 @@ describe("Scene/TextureAtlas", function () {
976976
.3333333333333333...............
977977
.3333333333333333...............
978978
.3333333333333333...............
979-
.33333333333333332222222222.....
980-
.33333333333333332222222222.....
981-
.33333333333333332222222222.....
982-
.33333333333333332222222222.....
983-
.33333333333333332222222222.....
984-
.33333333333333332222222222.....
985-
.33333333333333332222222222.....
986-
.33333333333333332222222222.....
987-
.33333333333333332222222222.....
988-
.3333333333333333222222222201...
979+
.3333333333333333.2222222222....
980+
.3333333333333333.2222222222....
981+
.3333333333333333.2222222222....
982+
.3333333333333333.2222222222....
983+
.3333333333333333.2222222222....
984+
.3333333333333333.2222222222....
985+
.3333333333333333.2222222222....
986+
.3333333333333333.2222222222.1..
987+
.3333333333333333.2222222222....
988+
.3333333333333333.2222222222.0..
989989
................................
990990
`.trim(),
991991
);
@@ -1337,6 +1337,108 @@ describe("Scene/TextureAtlas", function () {
13371337
).contextToRender([0, 255, 0, 255]);
13381338
});
13391339

1340+
it("adds custom padding with borderWidthInPixels", async function () {
1341+
atlas = new TextureAtlas({ borderWidthInPixels: 0 });
1342+
let indices = await addImages();
1343+
1344+
expect(drawAtlas(atlas, indices)).toBe(
1345+
`
1346+
................
1347+
................
1348+
................
1349+
................
1350+
................
1351+
................
1352+
2222222222......
1353+
2222222222......
1354+
2222222222......
1355+
2222222222......
1356+
2222222222......
1357+
2222222222......
1358+
22222222220.....
1359+
22222222220.....
1360+
22222222220.....
1361+
222222222201....
1362+
`.trim(),
1363+
);
1364+
1365+
atlas = new TextureAtlas({ borderWidthInPixels: 2 });
1366+
indices = await addImages();
1367+
1368+
expect(drawAtlas(atlas, indices)).toBe(
1369+
`
1370+
................................
1371+
................................
1372+
................................
1373+
................................
1374+
..2222222222....................
1375+
..2222222222....................
1376+
..2222222222....................
1377+
..2222222222..1.................
1378+
..2222222222....................
1379+
..2222222222....................
1380+
..2222222222..0.................
1381+
..2222222222..0.................
1382+
..2222222222..0.................
1383+
..2222222222..0.................
1384+
................................
1385+
................................
1386+
`.trim(),
1387+
);
1388+
1389+
atlas = new TextureAtlas({ borderWidthInPixels: 5 });
1390+
indices = await addImages();
1391+
1392+
expect(drawAtlas(atlas, indices)).toBe(
1393+
`
1394+
................................
1395+
................................
1396+
................................
1397+
................................
1398+
................................
1399+
................................
1400+
................................
1401+
................................
1402+
................................
1403+
................................
1404+
................................
1405+
................................
1406+
................................
1407+
................................
1408+
................................
1409+
................................
1410+
................................
1411+
.....2222222222.................
1412+
.....2222222222.................
1413+
.....2222222222.................
1414+
.....2222222222.................
1415+
.....2222222222.................
1416+
.....2222222222.................
1417+
.....2222222222.....0...........
1418+
.....2222222222.....0...........
1419+
.....2222222222.....0...........
1420+
.....2222222222.....0.....1.....
1421+
................................
1422+
................................
1423+
................................
1424+
................................
1425+
................................
1426+
`.trim(),
1427+
);
1428+
1429+
async function addImages() {
1430+
const promise = Promise.all([
1431+
atlas.addImage(tallGreenGuid, tallGreenImage),
1432+
atlas.addImage(blueGuid, blueImage),
1433+
atlas.addImage(bigBlueGuid, bigBlueImage),
1434+
]);
1435+
1436+
return pollWhilePromise(promise, () => {
1437+
atlas.update(scene.frameState.context);
1438+
});
1439+
}
1440+
});
1441+
13401442
it("GUID changes when atlas texure is modified", async function () {
13411443
atlas = new TextureAtlas();
13421444

0 commit comments

Comments
 (0)